Skip to content

fix(release): unblock re-runs and recover from a rejected release push - #39

Open
prisis wants to merge 3 commits into
mainfrom
fix/semantic-release-already-published
Open

prisis wants to merge 3 commits into
mainfrom
fix/semantic-release-already-published

Conversation

@prisis

@prisis prisis commented Oct 21, 2026 •

Copy link
Copy Markdown
Member

Problem

Every Semantic Release run on main since Oct 17 fails while publishing @visulima/task-runner:

[E403] 403 Forbidden - PUT https://registry.npmjs.org/@visulima%2ftask-runner-binding-darwin-arm64
- You cannot publish over the previously published versions: 3.0.1.

@visulima/task-runner is at 3.0.0 on npm, but all eight @visulima/task-runner-binding-* packages are already at 3.0.1. Run 39075638678 published the bindings and then failed at git push --tags, so the parent package, the tag and the release commit never landed. Every later run recomputes 3.0.1 and retries the same impossible publish.

That push was rejected because a lock-file maintenance commit landed on main 39 seconds earlier:

22:55:31  chore(release): @visulima/secret-scanner@2.0.3 [skip ci]
22:57:05  chore: updated lock file [ci skip]          <- moved main
22:57:44  ! [rejected] HEAD -> main (fetch first)     <- release push

Changes

1. Recognise an already-published native addon

scripts/semantic-release-native-addons.mjs already treats a republished version as success, but only inspected error.message:

if (message.includes("You cannot publish over the previously published versions")) { ... }

execFileSync builds that message from stderr, and pnpm 11.28.2 writes its publish report to stdout (the failed job shows stderr: '' with the E403 in stdout). The guard never matched.

  • Add isAlreadyPublishedError(error), which matches the conflict on the message, stdout and stderr, and use it in prepare.
  • Unit tests covering the pnpm stdout shape, the npm message shape, EPUBLISHCONFLICT, an unrelated 401, and a non-Error rejection.
  • Register the script as an implicit dependency of task-runner so changing it runs the package tests.

2. Recover from a rejected release push

@semantic-release/git pushes HEAD:<branch> from inside the release. Any push landing between checkout and that push aborts the release with the failed package untagged. The workflow now keeps the multi-semantic-release log and, when that failure is a rejected push and the branch has moved since the run started, dispatches a fresh run from the new tip. Re-running is safe because npm and the native-addon plugin skip versions that already exist.

Effect

On the next release run the eight burnt bindings are skipped, @visulima/task-runner@3.0.1 publishes, and the tag/release commit complete — main stops failing. Future mid-release pushes self-heal with one fresh run instead of staying red.

Verification

  • vitest run __tests__/unit/semantic-release-native-addons.test.ts — 5 passed
  • eslint on the new test — clean
  • prettier --check on all changed files — clean
  • actionlint .github/workflows/semantic-release.yml — clean
  • zizmor — only the pre-existing self-repository finding, unrelated to this change

…stdout

pnpm 11 writes its publish report to stdout and leaves stderr empty, so
`error.message` - which execFileSync builds from stderr only - never
contained the registry's "You cannot publish over the previously published
versions" text. The guard meant to make re-runs idempotent therefore never
matched, and a partially released version aborted every later release.

Match against stdout and stderr as well as the message. This unblocks the
stuck @visulima/task-runner release: all eight platform bindings were
published at 3.0.1 on Oct 17 before the run failed at `git push --tags`,
so they must be skipped for the parent package, tag and release commit to
land.
@github-actions

Copy link
Copy Markdown
Contributor

Thank you for following the naming conventions! 🙏

@coderabbitai

coderabbitai Bot commented Oct 21, 2026 •

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 1 minute.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: f62b65e9-84cd-4a1f-96cb-8c5377229975
📥 Commits

Reviewing files that changed from the base of the PR and between b59ffc0 and a7d4351.

📒 Files selected for processing: 4
  • .github/workflows/semantic-release.yml
  • packages/tooling/task-runner/__tests__/unit/semantic-release-native-addons.test.ts
  • packages/tooling/task-runner/project.json
  • scripts/semantic-release-native-addons.mjs
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added size:M Size of the change, tests and generated files excluded. vouch:trusted PR author is a collaborator, a bot or on the VOUCHED list. labels Oct 21, 2026
@semantic-release/git pushes HEAD:<branch> during prepare. When anything
else lands on the branch between checkout and that push, git rejects it
with "fetch first" and the release aborts: the failed package has no tag
and no release commit, while its native bindings are already on npm. The
push that broke the Oct 17 run was a lock-file maintenance commit that
landed on main 39 seconds before the release tried to push.

Keep the multi-semantic-release log and, on that specific failure,
dispatch a fresh run from the new tip instead of leaving the branch red.
Re-running is safe because npm and the native-addon plugin skip versions
that already exist.
@prisis prisis changed the title fix(release): skip already-published native addons when pnpm logs to stdout fix(release): unblock re-runs and recover from a rejected release push Oct 21, 2026
nx implicitDependencies only accepts project names, so listing the script
there failed the project graph with "point to non-existent project(s)".
Attach the file to the test target's inputs instead, which is what marks
task-runner affected and reruns its tests when the plugin changes.
@pkg-pr-new

pkg-pr-new Bot commented Oct 21, 2026

Copy link
Copy Markdown

Open in StackBlitz

@visulima/task-runner

npm i https://pkg.pr.new/visulima/vis/@visulima/task-runner@39

@visulima/vis

npm i https://pkg.pr.new/visulima/vis/@visulima/vis@39

@visulima/vis-mcp

npm i https://pkg.pr.new/visulima/vis/@visulima/vis-mcp@39

@visulima/task-runner-binding-darwin-arm64

npm i https://pkg.pr.new/visulima/vis/@visulima/task-runner-binding-darwin-arm64@39

@visulima/task-runner-binding-darwin-x64

npm i https://pkg.pr.new/visulima/vis/@visulima/task-runner-binding-darwin-x64@39

@visulima/task-runner-binding-linux-arm64-gnu

npm i https://pkg.pr.new/visulima/vis/@visulima/task-runner-binding-linux-arm64-gnu@39

@visulima/task-runner-binding-linux-arm64-musl

npm i https://pkg.pr.new/visulima/vis/@visulima/task-runner-binding-linux-arm64-musl@39

@visulima/task-runner-binding-linux-x64-gnu

npm i https://pkg.pr.new/visulima/vis/@visulima/task-runner-binding-linux-x64-gnu@39

@visulima/task-runner-binding-linux-x64-musl

npm i https://pkg.pr.new/visulima/vis/@visulima/task-runner-binding-linux-x64-musl@39

@visulima/task-runner-binding-win32-arm64-msvc

npm i https://pkg.pr.new/visulima/vis/@visulima/task-runner-binding-win32-arm64-msvc@39

@visulima/task-runner-binding-win32-x64-msvc

npm i https://pkg.pr.new/visulima/vis/@visulima/task-runner-binding-win32-x64-msvc@39

commit: a7d4351

@codspeed

codspeed Bot commented Oct 21, 2026

Copy link
Copy Markdown

Merging this PR will degrade performance by 12.06%

⚠️ 35 benchmarks spent significant time in system calls

System calls cannot be consistently instrumented, so they are not included in the measure, which understates the real cost. Please switch to the Walltime instrument to accurately measure system calls.

Measurement and system calls

⚠️ Different runtime environments detected

Some benchmarks with significant performance changes were compared across different runtime environments,
which may affect the accuracy of the results.

Open the report in CodSpeed to investigate

❌ 2 regressed benchmarks
✅ 63 untouched benchmarks
⏩ 48 skipped benchmarks1

Warning

Please fix the performance issues or acknowledge them on CodSpeed.

Performance Changes

Benchmark BASE HEAD Efficiency
❌ ⚠️ storeAction (1KB payload) 7.8 ms 8.9 ms -12.63%
❌ ⚠️ detectPm · bun workspace 97.8 µs 110.5 µs -11.49%

Tip

Investigate this regression by commenting @codspeedbot fix this regression on this PR, or directly use the CodSpeed MCP with your agent.


Comparing fix/semantic-release-already-published (a7d4351) with main (b59ffc0)

Open in CodSpeed

Footnotes

  1. 48 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports. ↩

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

package: task-runner size:M Size of the change, tests and generated files excluded. vouch:trusted PR author is a collaborator, a bot or on the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant