Summary
scripts/release.mjs runs the full test gate (30+ min when HEAD has no green push-CI run), then commits the release, tags it, re-inserts [Unreleased], and only then does git fetch origin main + git merge --no-edit origin/main (scripts/release-git.mjs:8-16) before pushing. Any PR merged to main during the gate that touched a package CHANGELOG.md under [Unreleased] conflicts with the release commit (which moved that block into the released section), the merge fails, and the whole run fails after 33 minutes with the tag created locally and nothing pushed or published.
Reproduction
Run 35074114707 (2026-09-16, dispatched on 9e1f97f whose push-CI was red from the #1290 flake, so the gate ran): gate green at 09:04, release: v2026.9.16-3 committed and tagged, then
[release] git fetch origin main
9e1f97f63..76dfe1760 main -> origin/main
[release] git merge --no-edit origin/main
CONFLICT (content): Merge conflict in packages/coding-agent/CHANGELOG.md
[release] error: git merge --no-edit origin/main failed
Three PRs (#1761, #1762, #1763) landed on main during the gate; #1761's changelog entry is what conflicted.
Expected
The release either (a) resolves the [Unreleased] conflict itself — the released section is the release commit's, the new [Unreleased] entries are main's, a union is always correct — or (b) rebases the release commit onto the fetched main before tagging, or (c) fails BEFORE the 30-minute gate when it cannot guarantee a clean merge (e.g. refuse to run the gate on a HEAD whose push-CI is not green, and tell the operator to wait for green so the gate is skipped and the window is ~4 min).
Actual
33 minutes of CI spent, local tag v2026.9.16-3 created in the runner, no push, no publish, exit 1. A retry recomputes the same version and can hit the same race.
Root cause
release-git.mjs merges with git merge --no-edit and no conflict strategy on a file the release commit structurally rewrites; combined with a long gate on a fast-moving branch this is a race the script cannot win.
Scope
- In: conflict-aware merge for
packages/*/CHANGELOG.md (union of the released section from HEAD and [Unreleased] from origin/main), or pre-gate refusal when the gate would run on a fast-moving branch; a unit test in scripts/release-git.test.mjs that reproduces the conflict.
- Out: the test gate itself.
Related
Summary
scripts/release.mjsruns the full test gate (30+ min when HEAD has no green push-CI run), then commits the release, tags it, re-inserts[Unreleased], and only then doesgit fetch origin main+git merge --no-edit origin/main(scripts/release-git.mjs:8-16) before pushing. Any PR merged tomainduring the gate that touched a packageCHANGELOG.mdunder[Unreleased]conflicts with the release commit (which moved that block into the released section), the merge fails, and the whole run fails after 33 minutes with the tag created locally and nothing pushed or published.Reproduction
Run 35074114707 (2026-09-16, dispatched on 9e1f97f whose push-CI was red from the #1290 flake, so the gate ran): gate green at 09:04,
release: v2026.9.16-3committed and tagged, thenThree PRs (#1761, #1762, #1763) landed on main during the gate; #1761's changelog entry is what conflicted.
Expected
The release either (a) resolves the
[Unreleased]conflict itself — the released section is the release commit's, the new[Unreleased]entries are main's, a union is always correct — or (b) rebases the release commit onto the fetched main before tagging, or (c) fails BEFORE the 30-minute gate when it cannot guarantee a clean merge (e.g. refuse to run the gate on a HEAD whose push-CI is not green, and tell the operator to wait for green so the gate is skipped and the window is ~4 min).Actual
33 minutes of CI spent, local tag
v2026.9.16-3created in the runner, no push, no publish, exit 1. A retry recomputes the same version and can hit the same race.Root cause
release-git.mjsmerges withgit merge --no-editand no conflict strategy on a file the release commit structurally rewrites; combined with a long gate on a fast-moving branch this is a race the script cannot win.Scope
packages/*/CHANGELOG.md(union of the released section from HEAD and[Unreleased]from origin/main), or pre-gate refusal when the gate would run on a fast-moving branch; a unit test inscripts/release-git.test.mjsthat reproduces the conflict.Related
dist/cli.jsdrift, fixed in build(coding-agent): commit the rebuilt dist/cli.js for the help fast path #1760)