Skip to content

ci: allow retrying npm publish for an existing release tag - #86

Merged
satsukies merged 3 commits into
mainfrom
ci/publish-retry
Oct 7, 2026
Merged

satsukies merged 3 commits into
mainfrom
ci/publish-retry

Conversation

@satsukies

@satsukies satsukies commented Oct 7, 2026 •

Copy link
Copy Markdown
Member

Summary

Allow retrying npm publish for a release whose tag already exists, and publish exactly what was tagged.

Today release-please creates the tag and GitHub Release before npm publish runs. If publishing fails, re-running the workflow skips it, because release_created is false on a re-run. In the 1.5.0 incident (#32), the workaround of deleting the tag broke release-please's baseline.

.github/workflows/release.yml:

  • New workflow_dispatch trigger with a required tag input (for example deploygate--v1.5.2). It stays in release.yml, because npm trusted publishing is bound to this workflow file.
  • release-please job
    • It now runs only on push.
    • Its release-PR bundle regeneration is unchanged.
    • It exposes release_created and tag_name as job outputs. These are the root-package output names in release-please-action v5 (src/index.ts).
    • It no longer needs id-token: write.
  • New publish job
    • It runs after a new release, or on workflow_dispatch, and has contents: read and id-token: write.
    • It validates the tag format (deploygate--vX.Y.Z), checks out the tag, and verifies that the package.json version matches the tag.
    • It refuses tags that are not reachable from main (git merge-base --is-ancestor), so a manual run can't publish unreviewed code.
    • It skips publishing with a notice if that version is already on npm. Only an explicit E404 counts as "not published"; any other registry error stops the run instead of attempting a publish.
    • The tag is passed only through env; no run: script interpolates ${{ }}.
  • No npm run bundle before npm publish. The plugin/scripts/bundle.js committed at the tag is published as-is, so npm and git always ship the same file. Check that the committed bundle is up to date on release PRs #81 / ci: check that the committed bundle is up to date on release PRs #85 make sure that committed bundle is up to date.

README.md: a new "Retrying a failed npm publish" subsection at the end of "Releasing". It covers transient or external failures (Actions → Release → Run workflow → tag), and says that failures caused by the tagged files need a new fix: release instead. It doesn't touch the lines that #84 edits.

Related Issue

Closes #82

Type of change

  • Bug fix
  • New feature
  • Documentation
  • Refactor / internal change
  • Build / CI / tooling

Test plan

  • npm run build passes

  • npm test passes (235 tests)

  • Manually verified the change (describe how below)

  • I parsed the workflow with the yaml package. It shows the jobs release-please and publish, the triggers push (main) and workflow_dispatch (tag), and the expected permissions per job.

  • bash -n passes on every run: script in the publish job.

  • I ran the guard scripts locally with a stubbed TAG and GITHUB_OUTPUT, against package.json from tag deploygate--v1.5.2. npm publish was never run.

TAG Result
deploygate--v1.5.2 Version matches, already on npm → skip=true, exit 0
deploygate--v9.9.9 package.json version 1.5.2 does not match tag → exit 1
foo; rm -rf / Invalid release tag → exit 1, before checkout
deploygate--v9.9.9, package.json stubbed to 9.9.9 npm view returns E404 → skip=false, publish path
deploygate--v1.5.2, npm stubbed to fail with ENOTFOUND Could not check npm → exit 1, no publish attempt

The reachability guard allows deploygate--v1.5.2 (on main) and refuses this PR's own head commit (not on main).

Which jobs run for each event:

Event release-please publish
Push, no release runs skipped
Push, release created runs runs with tag_name
Push, release-please fails fails skipped
workflow_dispatch skipped runs with inputs.tag (!cancelled() overrides the skipped needs)

The OIDC publish and the refs/tags/ checkout can't be exercised outside GitHub Actions. They'll first run on the next release, or on a manual run against an already-published tag, which only takes the skip path.

Checklist

  • I have updated the plugin version in plugin/.codex-plugin/plugin.json and plugin/.claude-plugin/plugin.json if applicable (not applicable: CI only)
  • I have read and agree to the Code of Conduct

🤖 Generated with Claude Code


Devin Review

Copilot AI balanced review requested due to automatic review settings October 7, 2026 05:45

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Devin Review found 2 potential issues.

Devin Review

Comment thread .github/workflows/release.yml Outdated
Comment thread .github/workflows/release.yml

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Copilot review overview

🟡 Changes recommended

The manual path needs stronger tag provenance validation, and its documented recovery scope needs clarification.

Review effort: Balanced
Findings: 1 High severity · 1 Low severity

Open (2)
What changed in this PR

Enables safe npm publish retries for existing release tags while publishing the exact tagged artifact.

Changes:

  • Adds manual tag-based publishing and release/version validation.
  • Separates release creation from npm publishing.
  • Documents the retry procedure.
File Description
.github/​workflows/​release.yml Adds the guarded publish job and manual trigger.
README.md Documents failed-publish retries.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread .github/workflows/release.yml
Comment thread README.md Outdated
Copilot AI balanced review requested due to automatic review settings October 7, 2026 05:50

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Copilot review overview

🟢 Approval recommended

The workflow safely supports retries and matches the documented release requirements.

Review effort: Balanced
Findings: None

Resolved since last review (2)

@enomoto-kazuya enomoto-kazuya left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

LGTM!

Copilot AI balanced review requested due to automatic review settings October 7, 2026 09:28

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Copilot review overview

🟢 Approval recommended

The workflow safely validates tagged releases, prevents duplicate publishing, and matches the documented recovery process.

Review effort: Balanced
Findings: None

@satsukies

Copy link
Copy Markdown
Member Author

Thanks

@satsukies
satsukies merged commit 919bcdb into main Oct 7, 2026
5 checks passed
@satsukies
satsukies deleted the ci/publish-retry branch October 7, 2026 09:30
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.

Allow retrying npm publish for an existing release tag

3 participants