Skip to content

Commit f9d30b0

Browse files
lidge-junclaude
andcommitted
ci(npm): publish to npm on version tag (provenance) + release runbook
`bun/npm install -g opencodex` pulls from the npm registry, not GitHub — so the package must be published. Add .github/workflows/publish-npm.yml: on a pushed tag vX.Y.Z (or manual dispatch) it sets up bun (for the prepublishOnly GUI build) + node, verifies the tag matches package.json, and runs `npm publish --provenance --access public`. Needs an NPM_TOKEN repo secret. Release runbook in devlog/65_npm-publish-ci. Package already publish-ready (npm pack: 54 files, ships gui/dist + bin, excludes dev dirs). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 70e6c9f commit f9d30b0

2 files changed

Lines changed: 99 additions & 0 deletions

File tree

.github/workflows/publish-npm.yml

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
name: Publish to npm
2+
3+
# Publishes opencodex to the npm registry so `bun install -g opencodex` /
4+
# `npm install -g opencodex` work. Triggered by pushing a version tag (v1.2.3),
5+
# which `npm version` creates — or manually from the Actions tab.
6+
on:
7+
push:
8+
tags: ["v*.*.*"]
9+
workflow_dispatch:
10+
11+
# id-token: write enables npm provenance (supply-chain attestation from this CI run).
12+
permissions:
13+
contents: read
14+
id-token: write
15+
16+
concurrency:
17+
group: publish-npm
18+
cancel-in-progress: false
19+
20+
jobs:
21+
publish:
22+
runs-on: ubuntu-latest
23+
steps:
24+
- name: Checkout
25+
uses: actions/checkout@v4
26+
27+
# opencodex is bun-native (the `prepublishOnly` build runs under bun).
28+
- name: Setup Bun
29+
uses: oven-sh/setup-bun@v2
30+
with:
31+
bun-version: latest
32+
33+
# node + npm do the actual publish (with provenance); registry-url wires NODE_AUTH_TOKEN.
34+
- name: Setup Node
35+
uses: actions/setup-node@v4
36+
with:
37+
node-version: 22
38+
registry-url: "https://registry.npmjs.org"
39+
40+
- name: Install dependencies
41+
run: bun install
42+
43+
# Guard: a pushed tag (v1.2.3) must match package.json "version" so we never
44+
# publish a mismatched build.
45+
- name: Verify tag matches package version
46+
if: startsWith(github.ref, 'refs/tags/')
47+
run: |
48+
PKG=$(node -p "require('./package.json').version")
49+
TAG="${GITHUB_REF_NAME#v}"
50+
echo "package.json=$PKG tag=$TAG"
51+
test "$PKG" = "$TAG" || { echo "::error::tag v$TAG != package.json $PKG"; exit 1; }
52+
53+
# `npm publish` runs prepublishOnly (typecheck + build the GUI into gui/dist) first,
54+
# so the published tarball always ships a fresh GUI. --access public for the unscoped name.
55+
- name: Publish
56+
run: npm publish --provenance --access public
57+
env:
58+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# npm publish CI + release runbook
2+
3+
## Why
4+
`bun install -g opencodex` / `npm install -g opencodex` install from the **npm registry**, NOT from
5+
GitHub. Pushing to GitHub does not make those commands work — opencodex must be **published to npm**
6+
first. This adds a GitHub Actions workflow that publishes on a version tag.
7+
8+
## What shipped
9+
- `.github/workflows/publish-npm.yml` — on a pushed tag `vX.Y.Z` (or manual dispatch):
10+
setup bun (for the `prepublishOnly` GUI build) + node (for `npm publish`), `bun install`, verify the
11+
tag matches `package.json` version, then `npm publish --provenance --access public`.
12+
- Package was already made publish-ready (earlier `63_release-prep`):
13+
`files` allowlist (src + gui/dist + scripts/postinstall.mjs + README + LICENSE), `bin` (opencodex/ocx,
14+
`#!/usr/bin/env bun`), `engines.bun`, `prepublishOnly` (typecheck + build the GUI into gui/dist so the
15+
published tarball always carries a fresh dashboard). `npm pack --dry-run`: 54 files / 634 KB, ships
16+
gui/dist + the bin, excludes devlog/docs-site/gui-src.
17+
18+
## One-time setup (owner)
19+
1. Create an npm **Automation** access token: npmjs.com → Access Tokens → Generate → *Automation*.
20+
2. Add it to the repo as a secret named **`NPM_TOKEN`**: GitHub → Settings → Secrets and variables →
21+
Actions → New repository secret.
22+
3. (First publish only) the npm name `opencodex` is currently unclaimed, so the first tagged release
23+
claims it under your npm account.
24+
25+
## Releasing (each version)
26+
```bash
27+
# from a clean main
28+
npm version patch # or minor/major — bumps package.json + creates the vX.Y.Z git tag
29+
git push --follow-tags # pushes the commit AND the tag → CI publishes to npm (with provenance)
30+
```
31+
After the workflow goes green:
32+
```bash
33+
bun install -g opencodex # or: npm install -g opencodex
34+
ocx init && ocx start
35+
```
36+
37+
## Notes
38+
- opencodex is **bun-native** (the `ocx` bin is `#!/usr/bin/env bun` and the server uses `Bun.serve`),
39+
so installers still need **bun** on PATH even via `npm install -g`. `engines.bun` documents this.
40+
- The consumer-side `postinstall` (interactive [Y/n] GitHub-star prompt) is TTY-gated → it no-ops in
41+
CI / piped installs, so it never blocks an automated install.

0 commit comments

Comments
 (0)