Repository navigation
Direct release: no working recovery when the branch push lands but a tag push fails #774
Description
Problem
A direct release pushes the branch, then each tag, and sets git.pushed only after the last one (packages/publish/src/stages/git-push.ts:182-191). Per-package mode does the same for each package (#765). If a tag push fails after the branch push, the release commit is on main and the packages are published, but the tags and GitHub Releases are missing.
The failure report can't tell this case from a rejected branch push, because both leave git.pushed false. For a direct release it recommends GitHub's "Re-run failed jobs" (packages/release/src/failure-report/failure-report.ts:160), and docs/troubleshooting.md:254 says the same. #762 rewords the report's state line to say the branch "may" be on the remote, but keeps that recovery.
What a re-run does
The re-run checks out the original trigger commit, not the release commit, so the resume path from #709 doesn't apply. It:
- computes the same version, since the tag never reached the remote;
- creates a second release commit on the old base;
- skips the packages already on the registry;
- pushes the branch, which is rejected as non-fast-forward because
mainalready has the first release commit.
So the re-run fails at the same stage every time. Nothing is corrupted, but the report offers no way out. (Traced, not run.)
What works today
- Roll forward. The next release reads the bumped
package.jsonversion and bumps past the failed one, under the defaultmismatchStrategy: 'warn'and under'prefer-package'. Under'error'it throws a version mismatch instead. The failed version never gets a tag or a GitHub Release. - Recreate the tags by hand on the release commit and push them. That restores the tags, not the GitHub Releases.
Fix
This needs a decision on the recovery path:
- Record that the branch push landed, e.g. an optional
git.branchPushedonPublishOutput, so the report can tell this case from a rejected branch push. - Choose what the report recommends for this case:
- recreate and push the missing tags on the release commit, then create the GitHub Releases, possibly with a command or action mode that works from the failure report's data;
- or roll forward, noting the
mismatchStrategy: 'error'caveat.
- Cover per-package runs too (below).
- Update
docs/troubleshooting.mdto match.
Standing-PR mode isn't affected: its publish pushes tags only, and release:retry recreates them on the merge commit.
Per-package runs (moved from #735, item 3)
In per-package mode each package pushes the branch, then its tag, as it publishes, and GitHub Releases wait until every package succeeds. If a later package fails, a re-run recreates the release commit at a new SHA, finds the earlier packages' tags on the remote at a different commit, and throws GIT_TAG_ERROR (packages/publish/src/stages/git-commit.ts:105-127; traced, not run).
#762 settles that case the documented way: once a per-package run has pushed, the report recommends rolling forward and leaves out the "Retrying is safe" note. Two gaps remain for this issue:
- The first package's tag push fails after its branch push.
git.pushedis still false, so the report recommends a re-run, which fails for the reasons above. - Packages that published never get a GitHub Release. Their tags are on the remote, but releases are only created after every package succeeds. If the decision here is to restore missing tags and releases rather than roll forward, it should create these too.
Related: #765 set the per-package push order, and #762 the report wording this builds on.
Found while reviewing #762.
Activity