fix(ci): gate publishing on the registry, and bump actions off Node 20 - #25
Merged
Merged
Conversation
The old check compared package.json at HEAD against HEAD~1. That made a version bump a one-shot trigger: if the publish that followed it failed, the bump was already consumed and no later push would ever retry it. Three versions were stranded that way, each by a different publish failure: 1.1.1 bumped in #16, publish failed on an expired npm token 1.2.0 bumped in #15, publish failed on an expired npm token 1.2.1 bumped in #18, publish failed on npm 12 requiring Node >= 22 Ask the registry instead: GET registry.npmjs.org/<name>/<version> and read the status. 200 means published, so skip; 404 means it is not there, so publish; anything else fails the job rather than guessing. This is idempotent, so a failed publish just retries on the next push. Consequences: - workflow_dispatch no longer needs to bypass the gate. Bypassing would now mean attempting to republish an existing version, which npm rejects anyway. Dispatch is still useful for retrying without pushing. - fetch-depth: 2 is gone; no history is needed. - Outputs renamed to say what they mean: version_changed -> should_publish, new_version -> version. Verified by running the step's script locally against the live registry: 1.2.1 returns 200 and yields should_publish=false, a synthetic 9.9.9 returns 404 and yields should_publish=true, and the scope is URL-encoded correctly as @galangel%2freact-tip-magic. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Every recent run warned that actions/checkout, actions/setup-node and softprops/action-gh-release target Node 20, which GitHub has deprecated and is already force-running on Node 24. Bumped across all three workflows, to the current major of each: actions/checkout v4 -> v7 actions/setup-node v4 -> v7 actions/upload-artifact v4 -> v7 actions/configure-pages v4 -> v6 actions/upload-pages-artifact v3 -> v5 actions/deploy-pages v4 -> v5 codecov/codecov-action v4 -> v7 softprops/action-gh-release v1 -> v3 Every input in use is stable across these majors: token/files/ fail_ci_if_error for codecov, name/path/retention-days for upload-artifact, and tag_name/name/generate_release_notes/draft/prerelease for the release step. No input changes were needed. Confirmed each referenced major tag resolves in its upstream repository and that all three workflows still parse. Note on coverage: ci.yml runs on pull_request, so checkout, setup-node and upload-artifact are exercised by this PR. deploy-storybook.yml and publish.yml only run on pushes to main, and the codecov step is gated on github.event_name == 'push', so those three are not verified until this lands on main. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
galangel
added a commit
that referenced
this pull request
Aug 18, 2026
#25) * fix(ci): gate publishing on the registry instead of a git diff The old check compared package.json at HEAD against HEAD~1. That made a version bump a one-shot trigger: if the publish that followed it failed, the bump was already consumed and no later push would ever retry it. Three versions were stranded that way, each by a different publish failure: 1.1.1 bumped in #16, publish failed on an expired npm token 1.2.0 bumped in #15, publish failed on an expired npm token 1.2.1 bumped in #18, publish failed on npm 12 requiring Node >= 22 Ask the registry instead: GET registry.npmjs.org/<name>/<version> and read the status. 200 means published, so skip; 404 means it is not there, so publish; anything else fails the job rather than guessing. This is idempotent, so a failed publish just retries on the next push. Consequences: - workflow_dispatch no longer needs to bypass the gate. Bypassing would now mean attempting to republish an existing version, which npm rejects anyway. Dispatch is still useful for retrying without pushing. - fetch-depth: 2 is gone; no history is needed. - Outputs renamed to say what they mean: version_changed -> should_publish, new_version -> version. Verified by running the step's script locally against the live registry: 1.2.1 returns 200 and yields should_publish=false, a synthetic 9.9.9 returns 404 and yields should_publish=true, and the scope is URL-encoded correctly as @galangel%2freact-tip-magic. * chore(ci): bump actions off the deprecated Node 20 runtime Every recent run warned that actions/checkout, actions/setup-node and softprops/action-gh-release target Node 20, which GitHub has deprecated and is already force-running on Node 24. Bumped across all three workflows, to the current major of each: actions/checkout v4 -> v7 actions/setup-node v4 -> v7 actions/upload-artifact v4 -> v7 actions/configure-pages v4 -> v6 actions/upload-pages-artifact v3 -> v5 actions/deploy-pages v4 -> v5 codecov/codecov-action v4 -> v7 softprops/action-gh-release v1 -> v3 Every input in use is stable across these majors: token/files/ fail_ci_if_error for codecov, name/path/retention-days for upload-artifact, and tag_name/name/generate_release_notes/draft/prerelease for the release step. No input changes were needed. Confirmed each referenced major tag resolves in its upstream repository and that all three workflows still parse. Note on coverage: ci.yml runs on pull_request, so checkout, setup-node and upload-artifact are exercised by this PR. deploy-storybook.yml and publish.yml only run on pushes to main, and the codecov step is gated on github.event_name == 'push', so those three are not verified until this lands on main.
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.
Two independent CI fixes, one commit each so they can be reverted separately.
1. Gate publishing on the registry, not a git diff
check-versioncomparedpackage.jsonatHEADagainstHEAD~1. That made a version bump a one-shot trigger: when the publish that followed it failed, the bump was already consumed and no later push would ever retry it.That single flaw stranded three versions, each behind a different publish failure:
Each needed a fresh version number or a manual dispatch to escape. Now the gate asks the registry instead:
This is idempotent, so a failed publish simply retries on the next push — no stranding, no burnt version numbers.
Knock-on changes:
workflow_dispatchno longer bypasses the gate. Bypassing would now mean attempting to republish an existing version, which npm rejects anyway. Dispatch still works for retrying without pushing.fetch-depth: 2removed — no history needed.version_changed→should_publish,new_version→version.Verified against the live registry
I extracted the step's script from the parsed YAML and ran it for real, rather than trusting it by inspection:
Both branches behave correctly and the scope is URL-encoded properly as
@galangel%2freact-tip-magic.2. Bump actions off the deprecated Node 20 runtime
Every recent run warned that
checkout,setup-nodeandaction-gh-releasetarget Node 20, which GitHub has deprecated and is already force-running on Node 24.actions/checkoutactions/setup-nodeactions/upload-artifactactions/configure-pagesactions/upload-pages-artifactactions/deploy-pagescodecov/codecov-actionsoftprops/action-gh-release18 references across all three workflows. Several cross multiple majors, so I checked the inputs actually in use —
token/files/fail_ci_if_error,name/path/retention-days, andtag_name/name/generate_release_notes/draft/prerelease— all stable across these ranges. No input changes were needed.Also confirmed every referenced major tag resolves upstream (so nothing points at a tag that doesn't exist) and all three workflows still parse.
Worth being explicit, because the coverage is uneven:
ci.ymlpull_requestdeploy-storybook.ymlpublish.ymlSo
configure-pages,upload-pages-artifact,deploy-pages,action-gh-releaseand the new gate are not exercised until this lands onmain. The codecov step is additionally gated ongithub.event_name == 'push', socodecov-action@v7is untested here too.The gate's logic is covered by the local run above. The storybook deploy and the release step are the two things to watch on the first push after merge.
Expected behaviour right after merge
The push will run
Publish to npm, the gate will find1.2.1already published, and the publish job will skip — same visible outcome as before, but now for the correct reason. The next version bump publishes automatically without a dispatch.