Skip to content

ci(publish): publish to npm on tag push (with provenance)#4

Merged
mabry1985 merged 1 commit into
mainfrom
ci/publish-on-tag-2026-05-25
May 25, 2026
Merged

ci(publish): publish to npm on tag push (with provenance)#4
mabry1985 merged 1 commit into
mainfrom
ci/publish-on-tag-2026-05-25

Conversation

@mabry1985

Copy link
Copy Markdown

Summary

Stops the manual npm publish + OTP dance. From now on:

git tag v0.6.0 && git push --tags

triggers a CI workflow that:

  1. Runs the full quality gate (typecheck, lint, format, test, build) — same as ci.yml
  2. Verifies package.json version matches the tag (catches forgot-to-bump errors before they hit npm)
  3. Publishes to npm with --provenance for supply-chain attestation

Why this works without OTP

NPM_TOKEN at the org level is an automation token — npm's automation tokens bypass 2FA on publish by design (that's their entire purpose). No human-in-the-loop needed.

Why --provenance

id-token: write job permission + --provenance flag makes npm verify the package was built by THIS workflow on THIS ref. Shows up as a "Provenance" badge on npmjs.com. Public, tamper-evident chain of custody — important since downstream agents (Quinn, workstacean, etc.) pull from this org.

Manual escape hatch

workflow_dispatch is wired so you can re-publish from a specific ref without re-tagging if a release goes sideways.

Releasing 0.6.0 right now

After this lands:

git tag v0.6.0
git push --tags

CI publishes. We confirm via npm view @protolabsai/protopatch@0.6.0 and then swap the workstacean Dockerfile to @protolabsai/protopatch@^0.6.0 (replacing the github: install).

Future repos

Copy this file to any other publishable repo in the org. As long as NPM_TOKEN is granted to that repo (org secret → selected repositories), it just works.

🤖 Generated with Claude Code

Stops the manual `npm publish` + OTP dance. From now on:

  git tag v$X.$Y.$Z && git push --tags

triggers a CI build that runs the full quality gate (typecheck / lint /
format / test / build), verifies package.json version matches the tag,
and publishes to npm with --provenance for supply-chain attestation.

Uses the org-level NPM_TOKEN (automation token, bypasses 2FA on
publish by design — that's the entire point of automation tokens).
Job permissions include `id-token: write` so npm provenance OIDC
works against this workflow's identity.

workflow_dispatch is kept as an escape hatch: re-publish from a
specific ref without re-tagging if a release goes sideways.

Quality gate mirrors .github/workflows/ci.yml so the publish path
can't accidentally diverge from the merge gate — a release can only
ship something that already passes CI.
@mabry1985 mabry1985 merged commit f3be262 into main May 25, 2026
2 of 3 checks passed

@mabry1985 mabry1985 left a comment

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

QA Audit — PR #4 | ci(publish): publish to npm on tag push (with provenance)

VERDICT: FAIL


CI Status

  • Analyze (typescript): in_progress
  • Analyze (actions): in_progress
  • test: FAILURE ⚠️

Diff Review
Adds .github/workflows/publish.yml — a well-structured npm publish workflow:

  • Triggers on semver tags (v*.*.*) with workflow_dispatch escape hatch
  • Sets id-token: write + npm publish --provenance for supply-chain attestation
  • Mirrors ci.yml quality gate (typecheck, lint, format, test, build) as publish gate
  • Version-to-tag verification step prevents publishing with mismatched versions
  • Automation token (NPM_TOKEN) correctly used — no OTP needed

Design is sound; no correctness or security issues in the diff itself.

Observations

  • CRITICAL: test job is failing. This blocks merge — the workflow cannot be approved until CI is green.
  • LOW: This is a pure workflow-only change. The test failure is almost certainly pre-existing and unrelated to the publish workflow, but must be resolved before this lands.
  • LOW: No CodeRabbit threads unresolved; no CLAWPATCH review available for this repo.

Recommendation
Re-run CI once test clears. The diff itself is approved — this is a mechanical re-run requirement only.

— Quinn, QA Engineer

@mabry1985

Copy link
Copy Markdown
Author

Submitted COMMENT review on #4.

Summary: The diff is sound — the publish workflow is well-designed with correct id-token: write permissions, proper quality gate mirroring, and --provenance attestation. However, the test CI job is currently failing (CRITICAL), which blocks merge. The review was submitted as a COMMENT since GitHub's API blocked a CHANGES_REQUESTED action from this account (the bot appears to be recognized as the PR author or a collaborator with restricted review permissions). A human will need to re-run CI and clear the failure before this can land.

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