Skip to content

Commit ec5cc27

Browse files
committed
Add release npm publish automation
1 parent 1e5e788 commit ec5cc27

2 files changed

Lines changed: 111 additions & 0 deletions

File tree

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
name: Release Publish
2+
3+
on:
4+
release:
5+
types: [published]
6+
workflow_dispatch:
7+
inputs:
8+
tag:
9+
description: "Release tag to publish, for example v0.1.1"
10+
required: true
11+
type: string
12+
dry_run:
13+
description: "Run npm publish as a dry run"
14+
required: true
15+
type: boolean
16+
default: true
17+
18+
permissions:
19+
contents: read
20+
id-token: write
21+
22+
concurrency:
23+
group: release-publish-${{ github.event.release.tag_name || inputs.tag }}
24+
cancel-in-progress: false
25+
26+
jobs:
27+
publish-npm:
28+
name: Publish to npm
29+
if: github.event_name != 'release' || !github.event.release.prerelease
30+
runs-on: ubuntu-latest
31+
timeout-minutes: 15
32+
33+
steps:
34+
- name: Checkout
35+
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
36+
with:
37+
ref: ${{ github.event.release.tag_name || inputs.tag }}
38+
39+
- name: Setup Node
40+
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
41+
with:
42+
node-version: 22
43+
registry-url: https://registry.npmjs.org
44+
cache: npm
45+
46+
- name: Install dependencies
47+
run: npm ci
48+
49+
- name: Verify release tag
50+
env:
51+
RELEASE_TAG: ${{ github.event.release.tag_name || inputs.tag }}
52+
run: |
53+
node --input-type=module <<'NODE'
54+
import { readFileSync } from "node:fs";
55+
56+
const tag = process.env.RELEASE_TAG?.replace(/^v/, "");
57+
const { version } = JSON.parse(readFileSync("package.json", "utf8"));
58+
59+
if (tag !== version) {
60+
console.error(`Release tag ${process.env.RELEASE_TAG} does not match package.json version ${version}.`);
61+
process.exit(1);
62+
}
63+
NODE
64+
65+
- name: Audit dependencies
66+
run: npm audit
67+
68+
- name: Typecheck
69+
run: npm run typecheck
70+
71+
- name: Test
72+
run: npm test
73+
env:
74+
OPENAI_API_KEY: ""
75+
76+
- name: Build
77+
run: npm run build
78+
env:
79+
OPENAI_API_KEY: ""
80+
81+
- name: Package smoke
82+
run: npm pack --dry-run
83+
84+
- name: Publish dry run
85+
if: github.event_name == 'workflow_dispatch' && inputs.dry_run
86+
run: npm publish --access public --dry-run
87+
88+
- name: Publish to npm
89+
if: github.event_name == 'release' || !inputs.dry_run
90+
run: npm publish --access public

README.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,27 @@ The package starts on `http://127.0.0.1:4141` and stores data in
138138
`./data/board.db` from the directory where the command is run. Set
139139
`BOARD_DB_PATH` when you want a fixed database location.
140140

141+
## Release Automation
142+
143+
Publishing a GitHub Release whose tag matches `package.json` publishes the same
144+
version to npm automatically. For example, release tag `v0.1.1` publishes
145+
`draftmora@0.1.1`.
146+
147+
One-time npm setup:
148+
149+
1. Open the npm package settings for
150+
[`draftmora`](https://www.npmjs.com/package/draftmora).
151+
2. Add a trusted publisher with GitHub Actions.
152+
3. Use owner `afurm`, repository `draftmora`, and workflow filename
153+
`release-publish.yml`.
154+
155+
The workflow validates dependencies, typecheck, tests, build, and package smoke
156+
before running `npm publish`.
157+
158+
GitHub's repository sidebar "Packages" section is separate from npm. It only
159+
shows packages published to GitHub Packages, not packages published to
160+
npmjs.com.
161+
141162
## Security Model
142163

143164
Draftmora is designed as a personal, local-first app. The Fastify API binds to

0 commit comments

Comments
 (0)