fix(release): run tests before mutating, restore files on abort - #151
Merged
Conversation
Ports the fix that landed in the core library's release.sh (livetemplate/livetemplate#499) to the client, where it hadn't been. Two related problems, both hit while releasing v0.19.1: update_versions and generate_changelog ran before build_and_test, so a failing test left VERSION, package.json, package-lock.json and CHANGELOG.md already rewritten. main() refuses to start on a dirty tree, so the next attempt would fail for a reason unrelated to why the first one did. Tests and the build now run first, on the pre-bump tree. The dist bundle embeds no version string, so building ahead of the bump is equivalent; verify_build still runs after, since it asserts package.json carries the new version. Reordering can't help with failures that only happen after the write — verify_build, npm pack, gh release create — so an EXIT trap restores the four release-managed files when the run aborts before committing, and stands down once commit_and_tag has run. Restores from HEAD rather than the index (commit_and_tag stages the files first, so a plain checkout would copy the modified versions back over themselves), and one path per invocation (a combined pathspec bails before touching anything if any entry is missing from HEAD, restoring none of them). Verified both directions: a simulated pre-commit abort restores VERSION and CHANGELOG.md, and a simulated post-commit abort leaves them alone. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ui2cwpeGkrUfRt8rh2FgGG
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Ports the fix that landed in the core library's
release.sh(livetemplate#499) to the client, where it had never been applied.Two problems, both hit while releasing v0.19.1
1. Files were mutated before tests ran.
update_versionsandgenerate_changelogran ahead ofbuild_and_test, so a failing test left VERSION, package.json, package-lock.json and CHANGELOG.md already rewritten.main()refuses to start on a dirty tree — so the next attempt fails for a reason unrelated to why the first one did.Tests and the build now run first, on the pre-bump tree.
2. No recovery for post-write failures. Reordering can't help with anything that fails after the write —
verify_build,npm pack,gh release create. An EXIT trap now restores the four release-managed files when the run aborts before committing, and stands down oncecommit_and_taghas run.Ordering constraint the client has and core doesn't
verify_buildassertspackage.json's version equals the new one, so it genuinely must run post-bump. Moving the build ahead of the bump was only safe after confirming the dist bundle embeds no version string — otherwise dist would ship stamped with the old version. Verified: no__VERSION__substitution, no package.json import in the TS sources. Final order:Two subtleties carried over from the core fix
commit_and_tagstages the files before committing, so if the commit itself fails a plaingit checkout --would restore them from the index — copying the modified versions back over themselves.git checkout HEAD -- a b cresolves the whole pathspec first and bails before touching the worktree if any entry is missing from HEAD, so a single call would restore none of them when one is untracked.Verification
Both directions exercised against a real worktree:
The second case matters as much as the first: a trap that fired after the commit would discard the release commit's content.
bash -nclean;--dry-runreaches the same decision points as before.🤖 Generated with Claude Code
https://claude.ai/code/session_01Ui2cwpeGkrUfRt8rh2FgGG