From e5ad9e9d872719fa6d303aed375f8c80c754d5e0 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 26 Aug 2026 00:22:11 +0000 Subject: [PATCH] docs(ci): measure the last lockfile merge-driver row instead of removing it MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `changeset-release.yml` performs no local merge, so the driver it configures cannot fire in that job. Swept the whole file with a control term on every zero-hit; the deciding fact is in `changesets/action@v1`, whose entire git surface is checkout / reset --hard / add / commit / push --force — a force-push resolves no merge. The `.gitattributes` line is a different matter and is NOT dead: CONTRIBUTING.md has contributors configure the same driver and then merge upstream locally. Measured both ways in a scratch repo — with the attribute the driver fires, and without it the identical merge conflicts. The CI half is dead while the repository-wide half is live, and the doc pin binds them together, so the removal is escalated as a decision rather than guessed at. Records the measurement in the workflow and the guide so it is not re-derived a fourth time, and corrects the row's stated reason: a rewrite is not a merge. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_012CZgmFFzqA9cX8tBMhvpFe --- .../6391-lockfile-merge-driver-measurement.md | 29 ++++++++++++ .github/workflows/changeset-release.yml | 46 +++++++++++++++++++ content/docs/guide/ci-cd-pipeline.md | 36 ++++++++++++++- 3 files changed, 110 insertions(+), 1 deletion(-) create mode 100644 .changeset/6391-lockfile-merge-driver-measurement.md diff --git a/.changeset/6391-lockfile-merge-driver-measurement.md b/.changeset/6391-lockfile-merge-driver-measurement.md new file mode 100644 index 0000000000..d92c283548 --- /dev/null +++ b/.changeset/6391-lockfile-merge-driver-measurement.md @@ -0,0 +1,29 @@ +--- +--- + +CI/doc-only: records the measurement of the last remaining "Lockfile Merge Driver" row +(objectui#6391). No mechanism is added or removed. + +`changeset-release.yml` performs no local merge, so the driver it configures cannot fire in +that job. Swept the whole file with a control term on every zero-hit — no `git merge`, +`rebase`, `pull`, `cherry-pick`, `am`, `apply` or `revert`; every `git` in it is the two +`git config` lines, `git status` twice, and the `git checkout -- .` / `git clean` pair that +undoes the version step, `checkout -- .` being an index-restore rather than a merge. The +deciding fact is in the marketplace action: read at `changesets/action` v1.9.0 (`a45c4d5`), +`src/git.ts` and the shipped `dist/` agreeing, its entire git surface is `checkout`, +`reset --hard`, `add .`, `commit -m`, `push --force` and `config user.*` — the version branch +is updated by `reset --hard` plus a force-push, and a force-push resolves no merge. + +⭐ The `.gitattributes` line is NOT dead, which is why the row was not removed with the other +two. `CONTRIBUTING.md` has contributors configure the same driver and then `git merge +upstream/main` — a real local merge on the attributed path. Measured in a scratch repository +with one variable changed: with the attribute the driver fires and the lockfile is +regenerated; without it the identical merge ends in `CONFLICT (content)`. The CI half is dead +and the repository-wide half is live, while `ci-cd-pipeline-doc.test.ts` binds them together, +so the removal is a decision rather than a cleanup and is escalated instead of guessed. + +The row's stated reason ("version bumps rewrite the lockfile") was wrong and is corrected — a +rewrite is not a merge — and the guide gains the third ⛔ note in the series that already +records "pushing is not merging" and "a server-side merge is not a local one". + +No source and no behaviour change; nothing a consumer installs is affected. diff --git a/.github/workflows/changeset-release.yml b/.github/workflows/changeset-release.yml index 8513a64901..395c55238d 100644 --- a/.github/workflows/changeset-release.yml +++ b/.github/workflows/changeset-release.yml @@ -518,6 +518,52 @@ jobs: cache: 'pnpm' registry-url: 'https://registry.npmjs.org' + # ⚠️ MEASURED 2026-08-26 (objectui#6391): this job performs NO local merge, + # so the driver configured below has no occasion to fire HERE. The step is + # kept anyway — see the ⛔ at the bottom of this comment, which is the part + # that matters. + # + # The sweep, so nobody re-derives it a fourth time (objectui#6358 and + # objectui#6369 each re-derived it for a different workflow): + # + # Every `git` in this file, enumerated rather than grepped-for-absence: + # the two `git config` lines below, `git status --porcelain` (x2), + # `git checkout -- .` and `git clean -fdq` in "Restore the pre-version + # tree". No `merge`, `rebase`, `pull`, `cherry-pick`, `am`, `apply` or + # `revert` anywhere in the file — each of those zero-hits was taken with + # a control term that DID hit the same file, because a zero-hit with no + # control is not a reading. + # + # `git checkout -- .` (below, in the restore step) takes tracked paths + # from the INDEX to undo what `pnpm changeset:version` wrote. That is a + # discard, not a merge; no merge driver participates. + # + # ⭐ The load-bearing part is not in this file at all — it is what + # `changesets/action@v1` does, and it has to be read to be known. Read at + # v1.9.0 (`a45c4d594aa4e2c509dc14a9f2b3b67ba3780d0d`), `src/git.ts` and the + # executed `dist/` bundle agreeing: the action's COMPLETE git surface is + # `checkout ` / `checkout -b`, `reset --hard `, `add .`, + # `commit -m`, `push origin HEAD: --force`, `push origin ` + # and `config user.*`. The version-branch update is `prepareBranch` + # (checkout, then `reset --hard github.context.sha`) followed by a commit + # and a FORCE-PUSH. It never merges, rebases or three-ways anything, so on + # this side too the driver has no occasion to fire. (Its `commitMode: + # github-api` path — not selected here; the default is `git-cli` — builds + # the commit through the GitHub API instead, and the bundle reads no + # `.gitattributes` and implements no merge driver at all.) + # + # ⛔ DO NOT delete this step "because it is dead" without a ruling. It is + # dead only in the CI half. The `.gitattributes` line it depends on + # (`pnpm-lock.yaml merge=pnpm-merge`) is NOT dead: `CONTRIBUTING.md` tells + # contributors to configure this same driver locally and then to + # `git merge upstream/main`, which is a real local merge on the attributed + # path. Measured both ways in a scratch repo: with the attribute the driver + # fires and the lockfile is regenerated; with the attribute removed and + # nothing else changed, the same merge ends in `CONFLICT (content)` with + # conflict markers in `pnpm-lock.yaml`. Removing the CI half forces + # `ci-cd-pipeline-doc.test.ts` to demand the attribute's removal too, which + # would break that live contributor path — so the two must be decided + # together, not dropped as one more dead row. objectui#6391 carries it. - name: Configure Git merge driver for pnpm-lock.yaml run: | # Configure custom merge driver for pnpm-lock.yaml diff --git a/content/docs/guide/ci-cd-pipeline.md b/content/docs/guide/ci-cd-pipeline.md index 17ff627553..38356f486a 100644 --- a/content/docs/guide/ci-cd-pipeline.md +++ b/content/docs/guide/ci-cd-pipeline.md @@ -1699,7 +1699,35 @@ One workflow carries that step: | Workflow | Why it needs the driver | |---|---| -| `changeset-release.yml` | version bumps rewrite the lockfile on the release branch | +| `changeset-release.yml` | ⚠️ configures it — but performs no local merge, see the measurement below | + +⚠️ **That row's stated reason was wrong, and the row is now the whole question** +([#6391](https://github.com/objectstack-ai/objectui/issues/6391)). It used to read "version bumps +rewrite the lockfile on the release branch". A **rewrite is not a merge**: `changeset:version` +overwrites `pnpm-lock.yaml` outright, and git runs a merge driver only when it has to *reconcile +two versions* of an attributed path. Measured on `changeset-release.yml`, and recorded in the file +itself so it is not re-derived a fourth time: + +- Every `git` in that workflow, enumerated rather than grepped for absence: the two `git config` + lines, `git status --porcelain` twice, and `git checkout -- .` plus `git clean -fdq` in "Restore + the pre-version tree". No `merge`, `rebase`, `pull`, `cherry-pick`, `am`, `apply` or `revert` — + every zero-hit taken with a control term that hit the same file. +- `git checkout -- .` there takes tracked paths from the **index** to undo what the version step + wrote. That is a discard, not a merge. +- The deciding fact is in the marketplace action, not the workflow. Read at `changesets/action` + v1.9.0 (`a45c4d5`), `src/git.ts` and the shipped `dist/` bundle agreeing: its entire git surface + is `checkout`, `reset --hard`, `add .`, `commit -m`, `push --force` and `config user.*`. The + version-branch update is a checkout, a `reset --hard` to the triggering commit, a commit, and a + **force-push**. A force-push resolves no merge, so the driver has no occasion to fire. + +⭐ **But the `.gitattributes` line is not dead, and that is why this is not simply a third +removal.** The attribute is repository-wide, and its live consumer is the contributor path this +page already points at: `CONTRIBUTING.md` tells contributors to configure this same driver and +then to `git merge upstream/main`. Measured in a scratch repository, one variable changed between +the two runs — **with** the attribute the driver fires and the lockfile is regenerated; **without** +it, and nothing else altered, the identical merge ends in `CONFLICT (content)` with conflict +markers left in `pnpm-lock.yaml`. So the CI half is dead and the repository half is live, while the +pin below binds them together. Resolving that is a decision, not a cleanup. `scripts/__tests__/ci-cd-pipeline-doc.test.ts` pins that table against the workflows that actually configure `merge.pnpm-merge`, in both directions. It is pinned because the claim had @@ -1729,6 +1757,12 @@ needs no driver, and giving it one buys nothing while implying a lockfile hazard — `gh pr merge`. But GitHub executes that one itself, not on the runner, so no local git config takes part in it. +⛔ **A rewrite is not a merge, and a force-push resolves none.** `changeset-release.yml` carries +the step on the strength of "version bumps rewrite the lockfile" +([#6391](https://github.com/objectstack-ai/objectui/issues/6391)). Regenerating a file is not +reconciling two versions of it, and the version branch is updated by `reset --hard` plus a +force-push inside `changesets/action`, which merges nothing on the runner. + ## Adding a New Workflow > **Give it a section on this page in the same PR.** Not a convention — a test.