Replace npm release workflow with a local interactive PHP script#3604
Closed
Kocal wants to merge 1 commit into
Closed
Replace npm release workflow with a local interactive PHP script#3604Kocal wants to merge 1 commit into
Kocal wants to merge 1 commit into
Conversation
kbond
approved these changes
May 29, 2026
Member
Author
|
Let's go for another, automated, but more secure, solution. |
Kocal
added a commit
that referenced
this pull request
Jun 4, 2026
This PR was squashed before being merged into the 2.x branch. Discussion ---------- [CI] Harden the release-on-npm workflow | Q | A | -------------- | --- | Bug fix? | no | New feature? | no <!-- please update src/**/CHANGELOG.md files --> | Deprecations? | no <!-- if yes, also update UPGRADE-*.md and src/**/CHANGELOG.md --> | Documentation? | no <!-- required for new features, or documentation updates --> | Issues | Fix #... <!-- prefix each issue number with "Fix #", no need to create an issue if none exist, explain below instead --> | License | MIT Following #3604 ## Summary Following an audit of `.github/workflows/release-on-npm.yaml` with my super friend Claude, this PR tightens several aspects of the npm release pipeline. OIDC trusted publisher protects authentication on the npm side, but says nothing about the integrity of the code being published. The changes below close that gap. Each commit addresses one finding from the audit, tagged `(F<n>)` in its title. ## Commits - **[CI] Publish from the tagged commit, not the branch HEAD (F1)** — checkout `${{ github.ref }}` (the tag) instead of the hardcoded `2.x` branch, and verify the tagged commit is an ancestor of the matching release branch (`2.x` for `v2.*.*`, `3.x` for `v3.*.*`). Closes a TOCTOU where `2.x` HEAD could drift between tag creation and job execution. - **[CI] Stop touching package.json versions during release (F8)** — drop the `pnpm version` + commit + push back to `2.x` block. The Git tag is the single source of truth; version bumps are now done manually before tagging. The workflow token is downgraded from `contents: write` to `contents: read`, and **the new `MAINTAINERS.md` documents the bump procedure.** Code can not be commited/pushed to the repo anymore ✨ - **[CI] Pin npm version used by the release workflow (F6)** — replace `npm@latest` with `npm@11.16.0` so a compromised npm release cannot ship through the release path without an explicit, reviewable bump PR. - **[CI] Generate npm provenance attestations on publish (F7)** — add `--provenance` to `pnpm publish`. Each tarball now carries a signed SLSA attestation pointing to the repo, commit and workflow run, verifiable via `npm audit signatures`. - **[CI] Serialize release runs per tag (F9)** — add a concurrency group keyed on `github.ref_name`, so two runs on the same tag queue instead of overlapping. Distinct tags (`v2.x.y` vs `v3.0.0`) still run in parallel. - **[CI] Build assets and refuse to publish if dist files drift (F2)** — run `pnpm build` on the tagged commit and fail if `git diff --quiet` reports anything. Mirrors the existing `dist-files-unbuilt.yaml` PR check, brought into the release path so tampered dist/source pairs cannot publish even if the branch CI was bypassed. Commits ------- 6607915 [CI] Build assets and refuse to publish if dist files drift (F2) aa5fcb8 [CI] Serialize release runs per tag (F9) 49d7697 [CI] Generate npm provenance attestations on publish (F7) b61c0d5 [CI] Pin npm version used by the release workflow (F6) 86131fe [CI] Stop touching package.json versions during release (F8) 4ab4f5b [CI] Publish from the tagged commit, not the branch HEAD (F1)
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.
I'm open to discussion, but I strongly believe automated releases on npm must not be a thing anymore.
The
release-on-npm.yamlworkflow has been failing repeatedly when publishing@symfony/ux-native(see run 26623506573 and #3522) EDIT: I forgot to enable OIDC on@symfony/ux-nativenpm package 🙄.The combination of OIDC (#3142), workflow permissions tweaks, and an automated bump+commit+push from CI is hard to debug and adds a real security surface for a step that runs once per release.
This PR drops the workflow and adds
bin/release-on-npm.php, an interactive script run manually after pushing a release tag.All UX packages have been configured on npm to only allow manual releases with 2FA enabled

After merging and upmerge, the OIDC (trusted publisher) will be removed from npm packages, since it won't be useful anymore.
Usage
php bin/release-on-npm.php 2.37.0 # default remote: upstream php bin/release-on-npm.php 2.37.0 --remote=origin