Skip to content

feat: publish zero to npm via release-please#367

Merged
kevincodex1 merged 4 commits into
mainfrom
feat/release-please
Jul 2, 2026
Merged

feat: publish zero to npm via release-please#367
kevincodex1 merged 4 commits into
mainfrom
feat/release-please

Conversation

@kevincodex1

@kevincodex1 kevincodex1 commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Summary

Automates versioning and publishing with release-please so npm install -g @gitlawb/zero can go live and stay live without manual release steps.

  • release-please-config.json / .release-please-manifest.jsonnode release type (package.json is Zero's version source of truth, read by internal/release/release.go), plain v* tags, bootstrap-sha at current HEAD so the first changelog starts clean, and release-as: 0.1.0 to pin the first release (remove after v0.1.0 ships).
  • .github/workflows/release-please.yml (new) — maintains the release PR from conventional commits on main; when merged, creates the tag + GitHub Release, then dispatches release-artifacts.yml at the tag. The explicit dispatch is required because tags created with the default GITHUB_TOKEN never trigger on: push: tags workflows; API-invoked workflow_dispatch is exempt from that suppression.
  • .github/workflows/release-artifacts.yml — tag-gated steps now match the ref (refs/tags/v*) instead of requiring a push event, so the dispatched-at-tag run packages and publishes identically to a manual tag push. Adds a publish-npm job that runs after all five platform artifacts upload: it probes every asset URL scripts/postinstall.mjs builds (verified against dry-runs for all platform/arch combos) as an anonymous client, then npm publish --access public --provenance. The probe doubly acts as a gate: while the repo is private, assets 404 anonymously, so a broken npm package cannot ship.

Resulting flow: conventional commit lands on main → release-please updates its release PR → merge → tag + Release → 5-platform artifacts build/upload → npm wrapper publishes.

Follow-ups tracked outside this PR: enable "Allow GitHub Actions to create and approve pull requests" in repo settings, add the NPM_TOKEN secret, make the repo public, and drop release-as after v0.1.0.

Checklist

  • The linked issue already has the issue-approved label.
  • go build ./..., go vet ./..., and go test ./... pass locally.
  • gofmt clean.
  • Tests added/updated for the change (and run under -race where relevant). — N/A: no Go code changed; workflows/config validated via YAML/JSON parsing, pinned-action SHA verification against the GitHub API, and postinstall.mjs dry-runs for every platform/arch.
  • UI changes include screenshots or a short recording where possible. — N/A: no UI changes.

Summary by CodeRabbit

  • New Features
    • Added automated release creation via a dedicated “Release Please” workflow on updates to the main branch.
    • Improved release-artifact publishing to run for v* tag refs (not limited to specific event types).
    • Added an npm publishing job for v* tags that validates expected GitHub Release asset URLs before publishing @gitlawb/zero publicly.
  • Chores
    • Added and configured release automation files (Release Please config and manifest).

Adds release-please to automate versioning and releases from
conventional commits on main:

- release-please-config.json / .release-please-manifest.json: node
  release type (package.json is the version source of truth), plain
  v-prefixed tags, bootstrap-sha at current HEAD, and release-as 0.1.0
  to pin the first release (remove after v0.1.0 ships).
- .github/workflows/release-please.yml: maintains the release PR; on
  merge it tags + creates the GitHub Release, then dispatches
  release-artifacts.yml at the tag (GITHUB_TOKEN-created tags cannot
  fire on-push-tags workflows).
- .github/workflows/release-artifacts.yml: tag-gated steps now match
  the ref instead of the push event so the dispatched-at-tag run
  publishes assets, and a new publish-npm job publishes @gitlawb/zero
  after verifying every postinstall asset URL is publicly downloadable
  (also blocks publishing while the repo is private).
@github-actions

github-actions Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Zero automated PR review

Verdict: No blockers found

Blockers

  • None found.

Validation

  • [pass] Diff hygiene: git diff --check
  • [pass] Tests: go test ./...
  • [pass] Build: go run ./cmd/zero-release build
  • [pass] Smoke build: go run ./cmd/zero-release smoke

Scope

Head: 94d8148a060a
Changed files (4): .github/workflows/release-artifacts.yml, .github/workflows/release-please.yml, .release-please-manifest.json, release-please-config.json

This deterministic review checks validation status and basic diff hygiene. A human reviewer still owns product judgment and design quality.

@coderabbitai

coderabbitai Bot commented Jul 2, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 8c8c551e-6fc2-4c1b-a95c-387267f1727a

📥 Commits

Reviewing files that changed from the base of the PR and between 0d0e5e9 and 94d8148.

📒 Files selected for processing (1)
  • .github/workflows/release-artifacts.yml
🚧 Files skipped from review as they are similar to previous changes (1)
  • .github/workflows/release-artifacts.yml

Walkthrough

Adds Release Please automation for main-branch release creation, updates release artifact gating to use tag refs, and adds an npm publish job that checks GitHub Release asset availability before publishing.

Changes

Release automation pipeline

Layer / File(s) Summary
Release Please workflow and config
.github/workflows/release-please.yml, release-please-config.json, .release-please-manifest.json
New workflow triggers Release Please on main pushes, dispatches release-artifacts.yml for the generated tag, and adds Release Please config plus an empty manifest.
Tag-ref gating for release steps
.github/workflows/release-artifacts.yml
Version-check and GitHub Release publish steps now condition on github.ref starting with refs/tags/v instead of github.event_name == 'push'.
publish-npm job with asset verification
.github/workflows/release-artifacts.yml
New job runs after package on tag refs, verifies expected binary and .sha256 URLs are publicly reachable, then runs npm publish --access public.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Main as main branch push
  participant ReleasePlease as release-please.yml
  participant GH as GitHub API
  participant ReleaseArtifacts as release-artifacts.yml
  participant Npm as npm registry

  Main->>ReleasePlease: push event
  ReleasePlease->>GH: create release PR/tag
  GH-->>ReleasePlease: tag_name output
  ReleasePlease->>ReleaseArtifacts: gh workflow run (tag)
  ReleaseArtifacts->>GH: create/upload GitHub Release assets
  ReleaseArtifacts->>ReleaseArtifacts: curl-check binary + .sha256 URLs
  ReleaseArtifacts->>Npm: npm publish --access public
Loading

Possibly related PRs

  • Gitlawb/node#130: Both PRs modify release-please-config.json, so they are directly connected at the release configuration level.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately reflects the main change: adding release-please-driven npm publishing for zero.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (2)
.github/workflows/release-artifacts.yml (1)

113-114: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick win

Disable credential persistence on the publish-npm checkout.

This checkout only needs to read package.json; it never pushes. Default persist-credentials: true leaves the GITHUB_TOKEN in the local git config for the rest of the job, which is unnecessary exposure in a job that also handles NPM_TOKEN and OIDC provenance credentials.

🔧 Suggested fix
       - name: Checkout
         uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
+        with:
+          persist-credentials: false
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/release-artifacts.yml around lines 113 - 114, The
publish-npm checkout in the release-artifacts workflow is leaving GitHub
credentials persisted unnecessarily; update the Checkout step that uses
actions/checkout to disable credential persistence. Set persist-credentials to
false on that checkout so the job only reads package.json without storing
GITHUB_TOKEN in git config alongside NPM_TOKEN and OIDC credentials.

Source: Linters/SAST tools

.github/workflows/release-please.yml (1)

27-34: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick win

Harden the tag_name interpolation against template injection.

--ref "${{ steps.release.outputs.tag_name }}" is expanded directly into the shell script rather than passed through an env var, which zizmor flags as template-injection-prone. tag_name is release-please-generated (low real exploitability here), but routing it through an env var is the standard mitigation and costs nothing.

🔧 Suggested fix
       - name: Build and publish release artifacts
         if: ${{ steps.release.outputs.release_created }}
         env:
           GH_TOKEN: ${{ github.token }}
+          TAG_NAME: ${{ steps.release.outputs.tag_name }}
         run: |
           gh workflow run release-artifacts.yml \
             --repo "$GITHUB_REPOSITORY" \
-            --ref "${{ steps.release.outputs.tag_name }}"
+            --ref "$TAG_NAME"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/release-please.yml around lines 27 - 34, The
release-artifacts trigger in the `Build and publish release artifacts` step
interpolates `steps.release.outputs.tag_name` directly inside the shell script,
which is template-injection-prone. Move the tag value into an environment
variable in this job, then reference that variable in the `gh workflow run
release-artifacts.yml` command instead of expanding
`steps.release.outputs.tag_name` inline. Keep the change localized to the
workflow step using `release.outputs.tag_name`.

Source: Linters/SAST tools

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/release-please.yml:
- Around line 8-11: The release workflow permissions are missing the Issues
scope needed by release-please-action to apply release-tracking labels on the
release PR. Update the permissions block in the release-please workflow to
include issues: write alongside the existing contents, pull-requests, and
actions permissions so the action can manage labels successfully.

---

Nitpick comments:
In @.github/workflows/release-artifacts.yml:
- Around line 113-114: The publish-npm checkout in the release-artifacts
workflow is leaving GitHub credentials persisted unnecessarily; update the
Checkout step that uses actions/checkout to disable credential persistence. Set
persist-credentials to false on that checkout so the job only reads package.json
without storing GITHUB_TOKEN in git config alongside NPM_TOKEN and OIDC
credentials.

In @.github/workflows/release-please.yml:
- Around line 27-34: The release-artifacts trigger in the `Build and publish
release artifacts` step interpolates `steps.release.outputs.tag_name` directly
inside the shell script, which is template-injection-prone. Move the tag value
into an environment variable in this job, then reference that variable in the
`gh workflow run release-artifacts.yml` command instead of expanding
`steps.release.outputs.tag_name` inline. Keep the change localized to the
workflow step using `release.outputs.tag_name`.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 75fa4bf8-b04d-4879-98d5-fbdbfd32c4b7

📥 Commits

Reviewing files that changed from the base of the PR and between 02f0c09 and 4f84e1e.

📒 Files selected for processing (4)
  • .github/workflows/release-artifacts.yml
  • .github/workflows/release-please.yml
  • .release-please-manifest.json
  • release-please-config.json

Comment thread .github/workflows/release-please.yml
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
npm's trusted publishing exchanges the workflow's OIDC token for
publish auth, so no long-lived NPM_TOKEN secret exists to leak, and
provenance is generated automatically. Drops registry-url from
setup-node (its .npmrc line hard-fails on the unset NODE_AUTH_TOKEN)
and updates npm first (OIDC needs npm >= 11.5.1). One-time caveat:
npm only lets you configure a trusted publisher on an existing
package, so the first @gitlawb/zero publish is a manual bootstrap.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
.github/workflows/release-artifacts.yml (1)

149-153: 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Retry release asset probes before failing publish.

The publish job runs immediately after matrix uploads; a single transient 404/5xx can block npm publishing even though the asset becomes public moments later.

Proposed fix
             "zero-v${version}-windows-x64.zip"; do
             for url in "${base}/${asset}" "${base}/${asset}.sha256"; do
-              if ! curl -fsSLI -o /dev/null "$url"; then
+              ok=false
+              for attempt in {1..6}; do
+                if curl -fsSLI -o /dev/null "$url"; then
+                  ok=true
+                  break
+                fi
+                sleep 10
+              done
+              if [ "$ok" != true ]; then
                 echo "::error::${url} is not publicly downloadable — npm postinstall would fail. Is the repo public and are all assets uploaded?" >&2
                 exit 1
               fi
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/release-artifacts.yml around lines 149 - 153, The release
artifact probe in the publish workflow fails immediately on a single transient
404/5xx, which can block npm publishing even when the asset appears moments
later. Update the URL check loop in the release-artifacts workflow to retry the
HEAD request for each asset and its .sha256 before exiting, using the existing
curl-based probe around the `${base}/${asset}` and `${base}/${asset}.sha256`
checks. Keep the final failure path and error message, but only emit it after
the retry attempts are exhausted.
🧹 Nitpick comments (1)
.github/workflows/release-artifacts.yml (1)

119-120: 🔒 Security & Privacy | 🔵 Trivial | 💤 Low value

Set persist-credentials: false on checkout. This job doesn’t use git after checkout, so there’s no need to leave GITHUB_TOKEN in .git/config.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/release-artifacts.yml around lines 119 - 120, The Checkout
step in the release-artifacts workflow should disable persisted git credentials.
Update the actions/checkout usage for the Checkout job to set
persist-credentials to false so GITHUB_TOKEN is not left in .git/config, and
keep the change localized to that checkout step.

Source: Linters/SAST tools

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/release-artifacts.yml:
- Around line 125-132: The trusted-publishing job currently upgrades npm with
npm@latest, which introduces unnecessary supply-chain risk. Update the npm
bootstrap step in the release workflow to use a pinned npm version that
satisfies the OIDC requirement, or replace it with a fast version check in the
setup step so the job fails if the bundled npm is too old. Refer to the Setup
Node and Update npm for trusted publishing steps in the workflow when making the
change.

---

Outside diff comments:
In @.github/workflows/release-artifacts.yml:
- Around line 149-153: The release artifact probe in the publish workflow fails
immediately on a single transient 404/5xx, which can block npm publishing even
when the asset appears moments later. Update the URL check loop in the
release-artifacts workflow to retry the HEAD request for each asset and its
.sha256 before exiting, using the existing curl-based probe around the
`${base}/${asset}` and `${base}/${asset}.sha256` checks. Keep the final failure
path and error message, but only emit it after the retry attempts are exhausted.

---

Nitpick comments:
In @.github/workflows/release-artifacts.yml:
- Around line 119-120: The Checkout step in the release-artifacts workflow
should disable persisted git credentials. Update the actions/checkout usage for
the Checkout job to set persist-credentials to false so GITHUB_TOKEN is not left
in .git/config, and keep the change localized to that checkout step.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 27f3fbe8-7391-49fe-8447-ab94ea2ead42

📥 Commits

Reviewing files that changed from the base of the PR and between 7436769 and 0d0e5e9.

📒 Files selected for processing (1)
  • .github/workflows/release-artifacts.yml

Comment thread .github/workflows/release-artifacts.yml Outdated
Rely on the npm bundled with the pinned Node 24 toolchain (>= 11.5.1,
the trusted-publishing minimum) instead of pulling an unpinned
npm@latest from the registry inside the publish job, and fail fast
with a clear error if a future toolchain change regresses it.
@kevincodex1 kevincodex1 merged commit 8eccc26 into main Jul 2, 2026
7 checks passed
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