Skip to content

fix(tools): add preflight checks and rollback to release script#5235

Open
marcoscaceres wants to merge 3 commits intomainfrom
fix/release-script-preflight
Open

fix(tools): add preflight checks and rollback to release script#5235
marcoscaceres wants to merge 3 commits intomainfrom
fix/release-script-preflight

Conversation

@marcoscaceres
Copy link
Copy Markdown
Contributor

Closes #5234

The release script could fail mid-release (after committing the version bump and tag) due to missing external dependencies, leaving the repo in a state requiring manual cleanup.

Adds three improvements:

Preflight checks run before any mutations — verifying Java (for vnu), Puppeteer Chrome (for respec2html), and that gh-pages resolves unambiguously. Fails fast with actionable fix instructions.

Rollback on failure — saves the pre-release HEAD sha and restores it if anything fails before the push. Deletes the local tag, resets main and gh-pages to their pre-release state. After push (point of no return), if only npm publish fails, it tells you to run npm publish manually instead of rolling back git.

Interactive npm publish — switches from exec() to spawn() with inherited stdio so the npm OTP browser auth flow works.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR hardens the tools/release.cjs release workflow by adding upfront dependency checks, adding a local rollback path on failures before pushing, and making npm publish interactive to support OTP/browser auth.

Changes:

  • Add preflight checks for Java (vnu), Puppeteer-managed Chrome (respec2html), and gh-pages branch resolution.
  • Add rollback logic to restore pre-release main/gh-pages state and delete the local tag when failures occur before pushing.
  • Switch npm publish execution from exec() to spawn() with inherited stdio for interactive auth.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread tools/release.cjs
Comment thread tools/release.cjs
Comment thread tools/release.cjs Outdated
Comment on lines 483 to 488
await preflight();

// 1. Confirm maintainer is on up-to-date and on the main branch
indicators.get("remote-update").show();
await git("remote update");
indicators.get("remote-update").hide();
Copy link

Copilot AI Apr 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

preflight() runs before git remote update, but the gh-pages check relies on remote-tracking refs (git branch -r ...). If the local remote refs are stale, preflight can give incorrect results. Consider moving the remote update (or a fetch/prune) before the preflight phase, or have preflight itself refresh remotes before checking branches.

Suggested change
await preflight();
// 1. Confirm maintainer is on up-to-date and on the main branch
indicators.get("remote-update").show();
await git("remote update");
indicators.get("remote-update").hide();
indicators.get("remote-update").show();
await git("remote update");
indicators.get("remote-update").hide();
await preflight();
// 1. Confirm maintainer is on up-to-date and on the main branch

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Applied the suggestion — git remote update now runs before preflight() so the gh-pages branch check has current remote refs.

Comment thread tools/release.cjs Outdated
Comment on lines +552 to +557
indicators.get("push-to-server").show();
await git("push origin main");
await git("push origin gh-pages");
await git("push --tags");
indicators.get("push-to-server").hide();
pushed = true;
Copy link

Copilot AI Apr 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pushed is only set to true after all three git push commands succeed. If git push origin main succeeds but a later push fails (e.g., gh-pages or tags), the catch block will treat it as "not pushed" and perform a local rollback, leaving the remote partially updated and the local repo reset behind it. Consider marking the point-of-no-return after the first successful push (or tracking which refs were pushed) and adjusting the failure message/rollback behavior accordingly.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed — pushed = true is now set immediately after git push origin main succeeds (the first push), so if gh-pages or tags push fails, the catch block won't attempt a local rollback against an already-updated remote.

- Check origin/gh-pages exists specifically, not just count remotes
- Move remote update before preflight so refs are current
- Set pushed=true after first push (point of no return)
@marcoscaceres
Copy link
Copy Markdown
Contributor Author

@copilot Can you confirm all your feedback has been addressed? Can you fix anything that was not addressed?

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 30, 2026

@copilot Can you confirm all your feedback has been addressed? Can you fix anything that was not addressed?

All four items from the automated review were addressed in commit 6c29f2f:

  1. origin/gh-pages existence — preflight now explicitly checks remotes.some(r => r.trim() === "origin/gh-pages") and fails with a git fetch origin gh-pages hint if missing.
  2. origin-specific check — covered by the same fix above.
  3. remote update before preflight()git remote update (with its loading indicator) now runs before preflight() so the gh-pages ref check sees fresh data.
  4. pushed = true after first push — moved to immediately after git push origin main so partial push failures don't trigger an incorrect local rollback.

Nothing left to address.

The W3C CDN syncs from GitHub Releases, not tags. Without this
step, new versions don't reach specs until someone manually creates
a release. Adds gh CLI to preflight checks.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Release script needs preflight checks and rollback on failure

3 participants