Skip to content

fix(ci): publish rspack to verdaccio with fresh sentinel version#28

Merged
fi3ework merged 1 commit intomainfrom
test/verdaccio-fresh-binding
Apr 8, 2026
Merged

fix(ci): publish rspack to verdaccio with fresh sentinel version#28
fi3ework merged 1 commit intomainfrom
test/verdaccio-fresh-binding

Conversation

@fi3ework
Copy link
Copy Markdown
Member

@fi3ework fi3ework commented Apr 8, 2026

Problem

Commit 7956c22 (feat: migrate rspack ecosystem CI to Verdaccio-based --release mode) introduced a verdaccio + --release pattern that assumed rspack HEAD's package.json version was globally unique on verdaccio. In practice — especially in the from-commit case — the HEAD version usually matches a previously published version on public npm.

Because verdaccio.yaml sets proxy: npmjs on both @*/* and **, any pnpm publish to verdaccio for a version that already exists on public npm becomes a silent no-op ("version already exists upstream"). Downstream pnpm install then falls through the uplink and pulls the OLD public tarball instead of the freshly built one — so fresh binding is never actually used, defeating the entire point of eco-ci.

Fix

Extract the verdaccio bootstrap into a reusable composite action (./.github/actions/publish-rspack-to-verdaccio) that, before publishing, bumps all @rspack/* workspace packages to a sentinel version <current>-fresh.<runId>.<runAttempt>.

  • The sentinel is guaranteed unique per workflow run and never exists on public npm, so pnpm publish always lands in the local registry.
  • Inter-package deps use workspace:*, which pnpm publish rewrites to the sentinel automatically — no manual dependency rewriting needed.
  • The action outputs the sentinel via steps.publish-rspack.outputs.version, which each workflow feeds to --release.

All 4 rspack workflows are wired to the composite action (ci.yml, rspack-ecosystem-ci-from-commit, rspack-ecosystem-ci-from-pr, rspack-ecosystem-ci-selected), 7 callsites in total. The _selftest if: guards and workspace:rspack pnpm bug #9270 rationale comments are preserved.

Validation

End-to-end dispatched against the test branch, covering both paths and both trigger sources:

Scenario Path Target Publish Downstream install Suite result
from-commit + plugin A (sourceRunId) d96ac80 (rc.1) ✅ 13 pkgs resolved to 2.0.0-rc.1-fresh.<runId>.1 ✅ green
from-pr #13612 + plugin B (build from scratch) PR #13612 ✅ 13 pkgs resolved to 2.0.0-rc.0-fresh.<runId>.1 ✅ green
from-commit full matrix A 013df8db (#13627) ✅ 12 × 13 pkgs resolved to 2.0.0-rc.0-fresh.<runId>.1 4 green / 8 red
from-pr #13625 full matrix B d96ac80 (#13625) ✅ 11 × 13 pkgs resolved to 2.0.0-rc.1-fresh.<runId>.1 3 green / 8 red

The 8 failures in both full-matrix runs are the same set of suites (rslib, rstest, modernjs, rsbuild, rsdoctor, devserver, rspress, lynx-stack) and all fail on rspack HEAD's new node:* externals behavior introduced by web-infra-dev/rspack#13627 (fix(externals): correct external type for aliased node builtin externals). This is the strongest possible proof that fresh binding is actually being used — if publish/install had silently fallen through to public npm, these suites would have inherited the old behavior and not failed on the new externals rule.

Test plan

Commit 7956c22 introduced a verdaccio + --release pattern that assumed
rspack HEAD's package.json version was globally unique on verdaccio.
In practice (especially from-commit) the HEAD version usually matches
a previously published version on public npm, and because verdaccio.yaml
sets `proxy: npmjs` on both `@*/*` and `**`, the publish becomes a silent
no-op ("version already exists upstream"). Downstream `pnpm install` then
falls through the uplink and pulls the OLD public tarball instead of the
freshly built one, so fresh binding is never actually used.

Extract the verdaccio bootstrap into a composite action that bumps all
@rspack/* workspace packages to `<current>-fresh.<runId>.<runAttempt>`
before publishing. The sentinel version is guaranteed unique per workflow
run and never exists on public npm, so publish always lands locally.
Since inter-package deps use `workspace:*`, pnpm publish rewrites them
automatically — no manual dependency rewriting needed.

Wire the composite action into all 4 rspack workflows (ci.yml, from-pr,
from-commit, selected) and feed the sentinel version to --release.
@fi3ework fi3ework merged commit 078b034 into main Apr 8, 2026
35 of 58 checks passed
@fi3ework fi3ework deleted the test/verdaccio-fresh-binding branch April 8, 2026 08:42
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.

1 participant