ci: add gated provenance-emitting release workflow - #17
Conversation
…red to a tag push) Adds .github/workflows/release.yml on a v* tag trigger, modelled on wave-av/adk's proven release.yml (secret-scan -> verify -> publish, OIDC trusted publishing + --provenance, tag/package.json version equality gate, no NODE_AUTH_TOKEN, all third-party actions pinned to full commit SHAs). Does NOT publish anything and pushes no tag. See PR description for the known gap: main has no package.json/src today, so the verify job cannot succeed until source is committed.
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_42662894-ad53-446b-a573-85615cd135c2) |
|
Warning Review limit reachedYou’ve reached a temporary PR review limit under our Fair Usage Limits Policy. Next review available in: 6 minutes Your organization has reached its usage spending cap. Adjust your spending cap in the billing tab. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
Comment |
ApprovabilityVerdict: Needs human review Unable to check for correctness in d95fbd3. This PR establishes significant release infrastructure (npm publishing pipeline with OIDC provenance), which warrants human review despite the author owning the file. While most review comment concerns appear addressed in the current code, the security model and the architectural choice of building twice rather than publishing the exact verified artifact should be reviewed by a human. You can customize Macroscope's approvability policy. Learn more. |
PR Summary by QodoCI: add gated, provenance-emitting npm release workflow
AI Description
Diagram
High-Level Assessment
Files changed (1)
|
Code Review by Qodo
1.
|
Qodo Fixer✅ Merged (0) · ☑ Fixed (0) Process
|
…sert wave bin, fix version-floor NaN gap - publish job: run npm ci --ignore-scripts (id-token: write job should not execute untrusted dependency lifecycle scripts) then npm run build before npm publish, so the tarball actually contains dist/ and matches what verify proved working (jobs do not share a workspace/filesystem) - verify job: re-run the pinned+checksum-verified gitleaks over dist/ after build, since gate 1 only scans the pre-build source tree and never sees generated build output before it reaches npm - e2e-smoke: require the packed bins to include a key literally named "wave", not just any bin - ESM smoke test: assert the imported module actually has exports instead of a truthy-object check that can never fail - npm version floor check: parse with a strict x.y.z regex so a non-numeric/prerelease npm --version cannot silently produce NaN comparisons that pass the >=11.5.1 gate
|
Reply to unresolved review thread re: |
…ish jobs own build too - both dist/ scans now pass --config .gitleaks.toml, matching gate 1 and the merge-path gitleaks invocation, instead of falling back to defaults with no allowlist/stopwords - publish job (fresh checkout + its own npm run build) now also gets a gitleaks scan of its dist/ output before publish - that build was previously the one artifact in the whole workflow no secret-scan gate ever touched
| - name: content policy (WAVE trade-secret / internal-leak gate) | ||
| env: | ||
| GUARD_PRIVATE_REPOS: ${{ vars.GUARD_PRIVATE_REPOS }} | ||
| run: bash scripts/public-repo-guard/content-policy.sh . |
There was a problem hiding this comment.
🔍 content-policy gate is not re-run on build output
The release path re-runs gitleaks over dist/ in both verify and publish, but the WAVE content-policy script (private-repo references, developer absolute paths, account IDs) is only run once over the source tree in secret-scan. Note the script's own IGNORE list excludes **/dist/**, so pointing it at the build output would require passing dist as the root. If bundlers can inline absolute developer paths or internal repo names into dist/, this asymmetry leaves that class of leak unscanned.
Was this helpful? React with 👍 or 👎 to provide feedback.
What this does
Adds
.github/workflows/release.yml, av*-tag-triggered, gated public-npmrelease path for
@wave-av/cli, modelled directly onwave-av/adk'srelease.yml(the file that published@wave-av/adk@1.0.15today withOIDC trusted-publisher +
--provenance).Three gates, in order:
secret-scan(pinned+checksummed gitleaks + theexisting WAVE content-policy script) ->
verify(install, lint/type-check/test if declared, build, then an e2e-smoke that packs the real tarball,
installs it into a throwaway project, and imports it) ->
publish(OIDCtrusted publishing only — no
NODE_AUTH_TOKEN/NPM_TOKENanywhere in thisfile — gated on a tag-version ==
package.json-version equality check, andon both prior gates being green). All third-party actions are pinned to
full commit SHAs, copied from the
adkfile.This PR does NOT publish anything and does NOT push a tag. It only adds
the workflow file. The first
v*tag push is a separate, explicit,operator-authorized act — not part of this change.
Known gap — please read before merging
mainin this repo currently has nopackage.jsonand nosrc/—only governance scaffolding (
AGENTS.md,capabilities.json, the guardCI).
@wave-av/cliwas hand-published to npm from a checkout that wasnever committed to this repo. Until a
package.json+ build (the repowould need
tsup/eslint/vitestper the shape already published as@wave-av/cli@1.0.8, confirmed by fetching that version's manifest fromthe npm registry) lands on
main, theverifyjob in this workflow willfail at
npm ci(no manifest to install against). This PR builds therelease path; it does not by itself make the repo publishable — that
needs a separate PR that actually commits the source.
Before the first tag push
The Trusted Publisher for
@wave-av/cli(org:wave-av, repo:cli,workflow:
release.yml) must be registered/verified in the npmjs.com UIbefore any
v*tag is pushed. If it isn't registered (or therepo/workflow name doesn't match exactly), the
publishjob'snpm publish --provenancestep fails withnpm error code EOTP— that's a2FA prompt, and it's how an unregistered/mismatched Trusted Publisher
binding actually presents, not an obviously-labelled "not configured"
error.
Verification performed
python3 -c "import yaml; yaml.safe_load(open('.github/workflows/release.yml'))"— parses clean, all 3 jobs (secret-scan,verify,publish) present.actionlint .github/workflows/release.yml— exit 0, zero findings.name:for the unquoted-colon-space bug that brokewave-av/sdks'publish-npm.ymlfor 28 runs — none present.Tag findings (read-only, reported, not acted on)
A
v*-shaped tag already exists in this repo:v1.0.0(only one found viagh api repos/wave-av/cli/tags). It predates the currently-published1.0.8on npm, so it does not correspond to the latest hand-publishedversion — worth the operator's attention separately from this PR.
Note
Medium Risk
Introduces the production npm publish path with OIDC and provenance, but publish only runs after secret-scan and verify pass; misconfiguration (Trusted Publisher, tag/version mismatch) fails closed rather than shipping a bad release.
Overview
Adds
.github/workflows/release.yml, av*tag-triggered path to publish@wave-av/clito public npm. Nothing is published by merging this PR alone; the first release still requires a separate tag push and npm Trusted Publisher setup.The workflow runs three sequential gates:
secret-scan(pinned gitleaks + the same WAVEcontent-policy.shas merge CI),verify(npm ci, optional lint/type-check/test when declared inpackage.json, build, then tarball e2e-smoke with ESM import andwavebin checks), andpublish(only if both prior jobs pass). Publishing uses npm OIDC trusted publishing with--provenance—no long-lived npm token—and enforces tag version ==package.jsonversion, with prereleases taggednextand stable releaseslatest.Known gap:
mainstill has nopackage.json/src/; theverifyjob will fail atnpm ciuntil the package source is committed in a follow-up PR.Reviewed by Cursor Bugbot for commit 07b5ef5. Configure here.
Note
Add gated provenance-emitting release workflow for npm publishing
v*tags, with three sequential gated jobs:secret-scan,verify, andpublish.secret-scanruns gitleaks and a content policy script against the source tree, blocking the release if secrets or internal content are detected.verifyinstalls dependencies, conditionally runs lint/type-check/tests, builds the package, rescansdist/with gitleaks, and e2e smoke-tests the packed tarball (ESM import +wavebin presence and executability).publishvalidates that the git tag version matchespackage.json, selects a dist-tag (latestornext), and publishes to npm using OIDC-based trusted publishing with provenance (no secret token required).Macroscope summarized d95fbd3.