ci(release): add protected npm staged publishing - #3192
Conversation
Split CLI publication into an OIDC stage operation and a separately verified finalization. Bind release artifacts to the exact workflow attempt, then require registry byte, tag, signature, and provenance checks before creating the GitHub release. Generated-by: OpenAI Codex
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (5)
🚧 Files skipped from review as they are similar to previous changes (3)
Included review availability: Your plan includes up to 3 reviews per rolling hour; 0 remain after this review. 📝 WalkthroughProblem solvedThis PR adds a protected, two-phase npm release process for the CLI package.
Source of truthThe PR extends the existing CLI validation and packaging path. It does not create a parallel package or release source. The validation workflow remains the source of the candidate tarball. The new workflows add controlled staging and finalization around that candidate. Solution size and complexityThe two-phase design is the smallest coherent solution shown by the diff for the required controls. Separate workflows are necessary because candidate validation, npm staging with human approval, registry verification, and GitHub Release creation require different permissions and release states. The added checks are necessary to prevent artifact substitution, ambiguous reruns, premature releases, and unverifiable npm publications. Simplification opportunitiesNo safe deletion is evident. The publication module validates release identity, source provenance, candidate checksums, file inventory, registry bytes, integrity, signatures, provenance, bounded responses, and GitHub Actions outputs. Removing these checks would weaken release protection or regression coverage. Validation performedThe PR adds tests for:
The No real Successful test execution and final required-check status are unverified from the supplied evidence. Complexity delta
Total maintenance complexity increases. The increase is justified by the required release protection and supply-chain verification. Review-relevant risks
The person performing the merge reviews the final diff. A maintainer makes the final determination. WalkthroughAdded a validated two-step CLI npm release process. The stage workflow prepares and publishes a staged package. The finalize workflow verifies the exact staged run, registry tarball, signatures, and provenance before creating the Git tag and GitHub Release. ChangesCLI npm release lifecycle
Estimated code review effort: 4 (Complex) | ~60 minutes Merge Risk: 🔵 Low · up to The PR adds a protected two-phase npm publishing flow. It is mergeable with owner awareness of a bounded risk that brittle workflow-policy assertions may provide false confidence or require updates after harmless workflow changes. Sequence Diagram(s)sequenceDiagram
participant ReleaseOperator
participant StageWorkflow
participant PublicationModule
participant NpmRegistry
participant FinalizeWorkflow
participant GitHubRelease
ReleaseOperator->>StageWorkflow: Dispatch release version
StageWorkflow->>PublicationModule: Prepare and bind candidate
PublicationModule->>NpmRegistry: Check version and dist-tag availability
StageWorkflow->>NpmRegistry: Publish staged package with provenance
ReleaseOperator->>FinalizeWorkflow: Dispatch stage run, attempt, and version
FinalizeWorkflow->>PublicationModule: Validate exact successful stage run
FinalizeWorkflow->>NpmRegistry: Verify tarball, checksums, signatures, and provenance
FinalizeWorkflow->>GitHubRelease: Create verified Git tag and release assets
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
PR Summary by QodoProtect CLI releases with staged npm publishing
AI Description
Diagram
High-Level Assessment
Files changed (8)
|
Code Review by Qodo
1.
|
There was a problem hiding this comment.
Actionable comments posted: 4
🧹 Nitpick comments (1)
.github/workflows/release-cli-finalize.yml (1)
72-78: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueRemove
registry-urlfrom theinspectjob.This job reads public npm data and does not publish packages. The setting adds unnecessary authentication configuration.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 329f8731-3da5-4239-a0bb-04000b33d5dd
📒 Files selected for processing (8)
.github/workflows/cli-package-validation.yml.github/workflows/release-cli-finalize.yml.github/workflows/release-cli-stage.ymlCONTRIBUTING.mdCONTRIBUTING.zh-CN.mdpackage.jsonscripts/release-cli-publication.mjsscripts/release-cli-publication.test.mjs
Included review availability: Your plan includes up to 3 reviews per rolling hour; 1 remains after this review.
Make artifact producers authoritative across partial reruns, bind finalization to an explicit workflow attempt, and validate the stage source before executing it. Finalization now audits only the public package edge, owns exact tag creation, and preserves Desktop as the repository Latest release. Generated-by: OpenAI Codex
There was a problem hiding this comment.
🧹 Nitpick comments (1)
scripts/release-cli-workflow-policy.test.mjs (1)
18-21: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winThree assertions do not protect observable behavior.
Line 30 forbids the strings
assert-vacantandgit ls-remote. It records a removed implementation, not a release invariant. Line 80 passes on any occurrence ofpackageManagerin the file, including a comment, so it does not prove that the npm toolchain comes from the root authority. Line 19 pins the consumer count to 2 for an exact string with exact spacing, so a third legitimate consumer ofrelease_candidate_artifact_idfails a green test with no behavior change.Tighten each to the contract you want to hold: assert that every
Select the release npm toolchainstep readspackageManagerfrompackage.json, assert that eachdownload-artifactstep usesartifact-idsinstead of a fixed total, and delete Line 30.Disposition: optional.
Also applies to: 30-31, 72-82
Source: Path instructions
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: bd4b639d-bf17-4de6-bc36-b7ebd4d25a51
📒 Files selected for processing (7)
.github/workflows/cli-package-validation.yml.github/workflows/release-cli-finalize.yml.github/workflows/release-cli-stage.ymlpackage.jsonscripts/release-cli-publication.mjsscripts/release-cli-publication.test.mjsscripts/release-cli-workflow-policy.test.mjs
🚧 Files skipped from review as they are similar to previous changes (2)
- package.json
- scripts/release-cli-publication.test.mjs
Included review availability: Your plan includes up to 3 reviews per rolling hour; 1 remains after this review.
Require provenance before npm accepts the staged version, keep staging as the final business step, and run finalization with the current verifier while treating the staged SHA only as release data. Pass canonical artifact identity across jobs and test the observable workflow contracts instead of deleted implementation details. Generated-by: OpenAI Codex
|
I have manually reviewed this and take responsibility for the result. |
English
Summary
Adds a two-phase CLI release path: GitHub Actions may only stage the exact validated tarball through npm OIDC, while a maintainer must approve it on npm with 2FA before a separate workflow verifies the public bytes, dist-tag, signatures, and provenance and creates the GitHub Release.
Release records bind the source commit, workflow run, and explicit rerun attempt. Artifact consumers use the immutable ID emitted by their producer, so partial reruns cannot select or reconstruct a different candidate.
Refs #3166
Verification
actionlintv1.7.7 passed.d78236b2bef4b9adcf71cc32954b93099e410d5db75b809b1ea992d51a864655.npm run check:releaseremains blocked before its affected suites by pre-existing UI/Desktop staledisttimestamps; its notice checks and all release tests were run separately and passed.npm stage publishwas intentionally not run before merge and Trusted Publisher setup.Release setup
After merge, create the protected
npm-releaseGitHub Environment, then configure the npm Trusted Publisher asmaka-agent/maka-agent, workflowrelease-cli-stage.yml, environmentnpm-release, with only Allow npm stage publish enabled.AI use
Select exactly one:
Tool(s) and scope: OpenAI Codex implemented and tested the release workflows and publication validation under human direction. The commits include the required
Generated-bytrailer.Checklist
Does this PR entail a change in behavior?
中文
概要
新增两阶段 CLI 发布流程:GitHub Actions 只能通过 npm OIDC 提交经过完整验证的精确 tarball;维护者必须在 npm 使用 2FA 人工批准。包公开后,独立 workflow 会核对 registry 字节、dist-tag、签名和 provenance,再创建 GitHub Release。
Release record 绑定 source commit、workflow run 与明确的 rerun attempt;artifact consumer 直接使用 producer 输出的 immutable ID,partial rerun 不再重算或选择其它候选。
关联 #3166。
验证
d78236b2bef4b9adcf71cc32954b93099e410d5db75b809b1ea992d51a864655。npm run check:release仍在执行相关测试前被本地既有 UI/Desktop staledist时间戳阻断;其中的 notice checks 和全部 release tests 已分别运行并通过。npm stage publish。发布配置
合并后先创建受保护的
npm-releaseGitHub Environment,再将 npm Trusted Publisher 配置为maka-agent/maka-agent、workflowrelease-cli-stage.yml、environmentnpm-release,并且只启用 Allow npm stage publish。AI 使用
OpenAI Codex 在人工指导下实现并测试发布 workflow 与 publication validation;commit 已包含要求的
Generated-bytrailer。