Skip to content

chore(release): add secure staged publishing process - #7613

Merged
benlesh merged 4 commits into
ReactiveX:masterfrom
benlesh:codex/readme-status-badges
Aug 4, 2026
Merged

chore(release): add secure staged publishing process#7613
benlesh merged 4 commits into
ReactiveX:masterfrom
benlesh:codex/readme-status-badges

Conversation

@benlesh

@benlesh benlesh commented Aug 2, 2026

Copy link
Copy Markdown
Member

Summary

  • replace token-based direct publication and unsupported Nx release integration with a generated release PR
  • build, attest, qualify, stage, and re-download the exact synchronized tarballs before npm approval
  • require npm TFA approval for all four packages, with rxjs approved last
  • add the public release runbook, succession template, release doctor, CODEOWNERS, CodeQL, and SHA-pinned Actions

Why

RxJS npm publication is irreversible. The release boundary therefore needs to prove every byte before a maintainer approves publication, avoid long-lived npm credentials, and leave enough public operational documentation for project succession.

Maintainer experience

After an ordinary release-relevant PR reaches master, an organization-owned GitHub App refreshes one release PR with the selected version, channel, categorized changelog, and npm Staged Packages link. Merging that PR authorizes exact-tarball qualification and stage-only OIDC submission. The maintainer then reviews the recorded and npm-staged digests and approves each stage with TFA.

Repository administrators must complete the documented GitHub App, ruleset, environment, npm trusted-publisher, and disposable-package rehearsal before the first release.

Validation

  • pnpm run release:check — 36 tests passed
  • pnpm run test:workflows
  • all GitHub workflow YAML parsed successfully
  • pnpm run prepare-packages
  • exact candidate pack, hash verification, hydration, runtime contract, and Webpack checks
  • git diff --check

No npm package, tag, GitHub Release, documentation site, or external account setting was changed while implementing this process.

@benlesh
benlesh force-pushed the codex/readme-status-badges branch from 7ded8ab to 9cf951d Compare August 2, 2026 17:29
@github-advanced-security

Copy link
Copy Markdown

You are seeing this message because GitHub Code Scanning has recently been set up for this repository, or this pull request contains the workflow file for the Code Scanning tool.

What Enabling Code Scanning Means:

  • The 'Security' tab will display more code scanning analysis results (e.g., for the default branch).
  • Depending on your configuration and choice of analysis tool, future pull requests will be annotated with code scanning analysis results.
  • You will be able to see the analysis results for the pull request's branch on this overview once the scans have completed and the checks have passed.

For more information about GitHub Code Scanning, check out the documentation.

Comment thread scripts/release/release-policy.mjs Fixed
Comment thread scripts/release/release-policy.mjs Fixed
@benlesh
benlesh marked this pull request as ready for review August 2, 2026 18:40
@benlesh
benlesh requested a review from Copilot August 2, 2026 18:41

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR replaces the prior token-based/Nx-driven publishing flow with a repository-owned secure release process built around a generated release PR, exact-tarball qualification, npm staged publishing, and post-publication finalization.

Changes:

  • Introduces a release-PR-based version selection policy (Conventional Commit titles), candidate packing/verification/hydration, staged publishing with re-download digest verification, and a scheduled finalizer.
  • Adds a “release doctor” audit to enforce workflow hardening (SHA-pinned Actions, no direct npm publish, no long-lived npm tokens, required config present).
  • Documents the public release runbook + private succession template, and adds CODEOWNERS/Dependabot/CodeQL + SHA-pinning updates across workflows.

Reviewed changes

Copilot reviewed 45 out of 45 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
scripts/release/wait-for-required-checks.mjs Polls GitHub check-runs until configured required checks succeed before generating a release PR.
scripts/release/validate-pr-title.mjs CLI wrapper to validate PR titles against the release policy.
scripts/release/stage-release.test.mjs Tests for stage-id parsing, staged download digest verification, and comment rendering.
scripts/release/stage-release.mjs Stages candidate tarballs to npm, re-downloads to verify bytes, and renders maintainer approval instructions.
scripts/release/release-policy.test.mjs Tests for Conventional Commit classification and release selection logic.
scripts/release/release-policy.mjs Implements Conventional Commit parsing + RxJS 9 release version/channel selection rules.
scripts/release/release-doctor.mjs Audits repo/workflows for hardened release requirements (pins/tokens/publish/caches/rules).
scripts/release/release-config.mjs Central release constants (packages list, branches, allowed files, channel mapping, URL validation).
scripts/release/release-candidate.test.mjs Tests deterministic candidate manifest hashing/ordering and source-commit binding behavior.
scripts/release/release-candidate.mjs Builds/verifies/hydrates an exact release candidate bundle (pack, inventory, hash, hydrate dist).
scripts/release/prepare-release-pr.mjs Generates/updates the release PR content: version bumps, changelog, lockfile updates, PR body plan.
scripts/release/finalize-release.mjs Verifies public npm registry integrity vs qualified manifest before final GitHub Release publishing.
scripts/release/check-release-bot-diff.mjs Enforces the release bot’s allowlisted file boundary before pushing the release PR branch.
scripts/release/bootstrap-release.mjs One-time manual bootstrap path to publish by filename with interactive TFA (no rebuild/repack).
scripts/release/authorize-release-commit.test.mjs Tests that only the exact merged repo-owned release PR can authorize the privileged workflow.
scripts/release/authorize-release-commit.mjs Validates that the current commit is the squash-merge of the repo-owned release PR.
scripts/release.js Removes legacy Nx-based release script.
scripts/publish.js Removes legacy token-based publish script.
scripts/check-release-coherence.test.mjs Updates coherence tests to reflect removal of Nx release + new publish/channel mapping source.
scripts/check-release-coherence.mjs Updates coherence auditing to enforce “Nx release removed” + new staging workflow requirements.
README.md Links the repository-level secure release runbook alongside package release docs.
packages/rxjs/docs/RELEASE_GATES.md Cross-links secure release runbook and clarifies that gates qualify candidates, not direct publication.
packages/rxjs/docs/PRERELEASE_APPROVAL.md Updates publication boundary description to staged OIDC + TFA approval order and finalization model.
package.json Replaces release scripts with release doctor/checks; expands workflow formatting coverage.
nx.json Removes Nx release configuration block.
docs/rxjs-next/PROJECT_PLAN.md Advances plan to P6.10 and records secure release process implementation evidence and session log.
docs/rxjs-next/DECISIONS.md Adds accepted decision D-057 defining the release PR + exact tarball + staged approval model.
docs/release/PRIVATE_SUCCESSION_PACKET.template.md Adds private successor packet template (non-secret inventory and procedure).
docs/RELEASE_PROCESS.md Adds the public secure release runbook (steps, scenarios, admin setup, rehearsal/failure handling).
.github/workflows/release-stage.yml New privileged workflow: build once, attest/qualify exact tarballs, tag+draft release, stage via OIDC, comment receipt.
.github/workflows/release-readiness.yml Pins actions to full SHAs in the readiness workflow.
.github/workflows/release-pr.yml New workflow to generate/refresh the single release PR using an org-owned GitHub App token.
.github/workflows/release-doctor.yml Scheduled/manual workflow to run strict release doctor audits.
.github/workflows/rebase.yml Pins checkout and rebase action to SHAs and normalizes YAML formatting/indentation.
.github/workflows/publish.yml Removes legacy publish workflow.
.github/workflows/observable-wpt.yml Pins actions (checkout/python/cache/upload-artifact/setup-chrome) to full SHAs.
.github/workflows/finalize-release.yml Adds scheduled/manual finalizer that publishes GitHub Releases only after registry integrity matches.
.github/workflows/conventional-commit.yml Adds PR-title Conventional Commit validation workflow.
.github/workflows/codeql.yml Adds CodeQL scanning workflow for JS/TS.
.github/workflows/ci_ts_latest.yml Pins checkout action to a full SHA.
.github/workflows/ci_main.yml Pins checkout action to a full SHA.
.github/PULL_REQUEST_TEMPLATE.md Updates template to require Conventional Commit PR titles for release selection.
.github/dependabot.yml Adds Dependabot updates for GitHub Actions.
.github/CODEOWNERS Adds CODEOWNERS coverage for workflows/release boundary assets and docs.
.github/actions/install-dependencies/action.yml Pins pnpm/action-setup and actions/setup-node to full SHAs.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread scripts/release/release-policy.test.mjs
Comment thread scripts/release/release-policy.mjs Outdated
Comment thread scripts/release/release-doctor.mjs
@benlesh
benlesh force-pushed the codex/readme-status-badges branch from 43e9124 to b4d133b Compare August 4, 2026 14:20
@benlesh
benlesh merged commit 651c2e7 into ReactiveX:master Aug 4, 2026
17 checks passed
@benlesh
benlesh deleted the codex/readme-status-badges branch August 4, 2026 14:29
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.

3 participants