GeezerVisonThe World Wide Web, restored to 800 pixels of glory. | ||||||||||||||||
| Home|About|Gaming cabinet|Archives|How it works|Starter sites | ||||||||||||||||
GeezerVison is showing github.com — feat(release): version-bump automation + shared release-readiness gate by mikolalysenko · Pull Request #139 · SocketDev/socket-patch Conversation
|
| Check | Ordinary PRs / pushes (CI release-readiness) |
Bump PRs (version changed vs base) | Release workflow version job |
|---|---|---|---|
Version coherence — version-sync.sh is a no-op across all packaging sites |
✅ | ✅ | ✅ |
| CHANGELOG section exists and is non-empty | — | ✅ | ✅ |
Tag v<X.Y.Z> absent (or at HEAD = release retry) |
— | ✅ | ✅ |
release.yml's version job now calls the script in place of its inline tag/CHANGELOG checks — the PR gate and the publish gate are the same code and cannot drift.docs/releasing.mdThe full operator playbook: bump → merge → dispatch Release (optional dry-run) → approve staged npm (platform packages first) → "Re-run failed jobs" semantics → pointer to the one-time registry setup checklist in #138.
3.3.0 → 3.4.0 rolls the CHANGELOG correctly (empty [Unreleased] kept on top, 382 lines of notes under the new dated heading), full lint then passes end-to-end; a second bump correctly refuses on the now-empty [Unreleased].vX.Y.Z shape, dirty tree, empty notes.--sync-only passes (ordinary-PR CI stays green); the full gate correctly fails for 3.3.0, whose CHANGELOG section genuinely doesn't exist — the next bump supersedes that, but it means a hypothetical 3.3.0 re-release dispatch fails the gate exactly as the old inline check would have.-v escape-processes its values, so -v re="\[3\.4\.0\]"-style patterns silently mangle and misread a populated section as empty — the section matchers use plain-string prefix matching instead.shellcheck clean on all three scripts (now also linted in CI); YAML parses; all uses: SHA-pinned.🤖 Generated with Claude Code
Note
Low Risk
Changes are release automation, CI gates, and docs only—no runtime product code paths.
Overview
Adds one-command / one-click version bumps and centralizes release checks so PR CI and the Release workflow cannot drift.
scripts/bump-version.sh validates the target version, rolls [Unreleased] into a dated ## [X.Y.Z] section (refuses empty notes), runs version-sync.sh across all packaging sites, and with --pr opens release/vX.Y.Z with notes and post-merge steps in the body.
scripts/release-lint.sh is the shared gate: version coherence (version-sync must be a no-op), non-empty CHANGELOG section, and optional remote tag collision check (tag at HEAD allowed for retries). CI’s new release-readiness job runs sync-only on ordinary PRs and the full gate on version-bump PRs; release.yml replaces inline tag/CHANGELOG steps with the same script. version-bump.yml dispatches the bump from Actions (with the documented GITHUB_TOKEN / pull_request CI caveat).
docs/releasing.md documents bump → merge → Release → npm 2FA approval and idempotent re-runs. CI also shellchecks the release scripts.
Reviewed by Cursor Bugbot for commit 365924c. Configure here.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
scripts/bump-version.sh <X.Y.Z> [--pr] turns the whole version-bump chore
into one command: validates the version (shape, no downgrade, clean tree),
rolls CHANGELOG.md's [Unreleased] notes into a dated `## [X.Y.Z]` section
(refusing when no notes were written), stamps every packaging site via
version-sync.sh, and with --pr opens the release/vX.Y.Z PR whose body
carries the rolled-over notes and the post-merge playbook.
.github/workflows/version-bump.yml exposes the same flow as a
workflow_dispatch so a bump can be started from the GitHub UI. Documented
caveat: PRs opened with GITHUB_TOKEN don't trigger pull_request CI (the
same event suppression that shaped release.yml's topology) — close/reopen
the PR or push to its branch to kick checks; running the script locally is
the preferred path.
scripts/release-lint.sh is the single source of truth for the release
gate, shared by CI and the Release workflow so the two can't drift:
- version coherence: version-sync.sh must be a no-op (catches a
hand-edited version in any single packaging site);
- CHANGELOG has a non-empty section for the version;
- --tag-check: the tag doesn't exist at a commit other than HEAD
(same-commit = release retry, allowed).
ci.yml gains a release-readiness job: coherence-only on ordinary
PRs/pushes, the full gate (incl. tag check) on PRs that change the
workspace version. release.yml's version job now calls the same script in
place of its inline tag/CHANGELOG checks. The full playbook lives in
docs/releasing.md.
Note: awk -v escape-processes its values, so the section matchers use
plain-string prefix matching instead of -v regexes — a -v pattern like
"\[3\.4\.0\]" silently mangles and misreads a populated section as empty
(caught by the scratch-clone round-trip test).
Co-Authored-By: Claude Fable 5 <[email protected]>
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Cursor Bugbot has reviewed your changes using high effort and found 3 potential issues.
Bugbot Autofix prepared a fix for the issue found in the latest run.
Or push these changes by commenting:
@cursor push 3eaf9d1a98
diff --git a/scripts/release-lint.sh b/scripts/release-lint.sh --- a/scripts/release-lint.sh +++ b/scripts/release-lint.sh @@ -79,13 +79,24 @@ else bash scripts/version-sync.sh "$VERSION" >/dev/null DRIFTED="$(git status --porcelain | awk '{print $2}')" - if [ -n "$DRIFTED" ]; then - fail "version-sync.sh $VERSION is not a no-op — these files carried a stale version: $(echo "$DRIFTED" | tr '\n' ' ')" + # Exclude npm/socket-patch/package-lock.json: version-sync refreshes it via + # npm install --package-lock-only, which re-resolves optional platform packages + # from the registry. After a release publishes those packages, the lockfile + # changes from hollow stubs to fully resolved entries (or vice versa when + # running on the bump commit before publish), but that's not version drift. + DRIFTED_VERSIONS="$(echo "$DRIFTED" | grep -v '^npm/socket-patch/package-lock\.json$' || true)" + if [ -n "$DRIFTED_VERSIONS" ]; then + fail "version-sync.sh $VERSION is not a no-op — these files carried a stale version: $(echo "$DRIFTED_VERSIONS" | tr '\n' ' ')" # The tree was clean before the sync, so restoring exactly the files the # sync touched leaves it as found. echo "$DRIFTED" | xargs git checkout -- else - note "version coherence OK: every stamped site already carries $VERSION" + if [ -n "$DRIFTED" ]; then + note "version coherence OK: every stamped site already carries $VERSION (npm lockfile refreshed from registry, as expected)" + echo "$DRIFTED" | xargs git checkout -- + else + note "version coherence OK: every stamped site already carries $VERSION" + fi fi fi
You can send follow-ups to the cloud agent here.
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 365924c. Configure here.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
…ace) Between a sibling thread's fork() and its exec(), the child briefly inherits every open fd — including a write fd on the binary staged moments ago — and exec'ing the file during that window fails with "Text file busy". Retry the spawn on ErrorKind::ExecutableFileBusy (10 attempts, 25 ms linear backoff, <=1.4 s worst case) instead of failing a fully SHA-verified download; all other spawn errors still fail immediately and the 10 s hang timeout applies per attempt. Same dance Go's os/exec and cargo do. Turns the previous commit's RED regression test green and deflakes the coverage job (first bitten on PR #139: llvm-cov widens the race window, which is why `test`/`test-release` never caught it). Co-Authored-By: Claude Fable 5 <[email protected]>
570339d
into
main
There was an error while loading. Please reload this page.
…en self-update against the fork/exec fd race (#140) * test(update): regression test for the ETXTBSY sanity-exec race (RED) Reproduces the coverage-job flake deterministically: a write fd held open on the staged binary while sanity_exec runs — the shape a sibling thread's fork() leaves behind via fd inheritance — makes the exec fail with "Text file busy" (Linux enforces ETXTBSY; the test is linux-gated). Also tightens the existing strictness test to assert each rejection's REASON instead of bare is_err(), which previously let an ETXTBSY spawn failure masquerade as the expected rejection one line before the flake surfaced. This commit is intentionally pushed without the fix so CI demonstrates the failure; the follow-up commit makes it pass. Co-Authored-By: Claude Fable 5 <[email protected]> * fix(update): retry sanity-exec on ETXTBSY (fork/exec fd-inheritance race) Between a sibling thread's fork() and its exec(), the child briefly inherits every open fd — including a write fd on the binary staged moments ago — and exec'ing the file during that window fails with "Text file busy". Retry the spawn on ErrorKind::ExecutableFileBusy (10 attempts, 25 ms linear backoff, <=1.4 s worst case) instead of failing a fully SHA-verified download; all other spawn errors still fail immediately and the 10 s hang timeout applies per attempt. Same dance Go's os/exec and cargo do. Turns the previous commit's RED regression test green and deflakes the coverage job (first bitten on PR #139: llvm-cov widens the race window, which is why `test`/`test-release` never caught it). Co-Authored-By: Claude Fable 5 <[email protected]> --------- Co-authored-by: Claude Fable 5 <[email protected]>
`test (ubuntu-latest)` failed in `make_served_binary_output_execs` with "Text file busy" (os error 26). Linux refuses to exec a file while any process still holds it open for writing: `fs::write` had closed our handle, but the suite runs tests in parallel threads, so a sibling that forks between our open and its exec inherits the write fd and our exec lands in that window. The race is in the harness, not in the binary under test, so retry the spawn for up to 10s instead of failing the run. Same flake class as PR #139's `coverage` job, which was resolved by re-running. This PR does not otherwise touch update_fixture.rs. Verified: update_notifier_e2e 37/37; rustfmt and clippy clean. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
There was an error while loading. Please reload this page.
Successfully merging this pull request may close these issues.
There was an error while loading. Please reload this page.