Skip to content

Commit 82a8174

Browse files
committed
ci: fan out build -> [npm, jsr] in parallel
Reshapes the publish workflow into build -> {npm, jsr}: - 'build' job runs deno task build-npm + ./stage-jsr.sh, uploads npm/ and build/ as artifacts. - 'npm' and 'jsr' jobs both have needs: build and no mutual dependency, so Actions runs them concurrently after build completes. Factor the JSR staging out of publish-jsr.sh into a dedicated stage-jsr.sh so CI can reuse the exact same tree locally developers get via ./publish-jsr.sh. The local script now just composes stage-jsr.sh + 'deno publish'. JSR OIDC inherits id-token: write from the workflow-level permissions, so no PAT secret is required after linking the package in JSR settings. Also gitignore build/ and switch npm publish to the standard setup-node@v4 + NODE_AUTH_TOKEN flow instead of hand-rolled .npmrc.
1 parent 6973338 commit 82a8174

4 files changed

Lines changed: 71 additions & 42 deletions

File tree

.github/workflows/publish.yaml

Lines changed: 52 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,66 +1,94 @@
1-
21
name: Publish to NPM + JSR
32

43
on:
54
workflow_dispatch:
65
push:
76
tags:
8-
- 'v*' # This will run the workflow when you push a tag with a version format, like v1.0.0
7+
- 'v*' # Runs when a version tag is pushed, e.g. v0.10.3
98

109
permissions:
1110
id-token: write
1211
contents: read
1312

1413
jobs:
1514
build:
16-
name: Publish to NPM
15+
name: Build
1716
runs-on: ubuntu-latest
1817

1918
steps:
2019
- name: Clone repository
21-
uses: actions/checkout@v3
20+
uses: actions/checkout@v4
2221

2322
- name: Install Deno
2423
uses: denoland/setup-deno@v1
2524
with:
2625
deno-version: v1.x
2726

28-
- name: Run Deno build script
27+
# Produces ./npm (dnt-generated Node package).
28+
- name: Build npm package
2929
run: deno task build-npm
3030

31-
- name: Navigate to npm directory
32-
run: cd ./npm
31+
# Produces ./build (staged JSR payload: src + deno.json, no tests).
32+
- name: Stage JSR package
33+
run: ./stage-jsr.sh
34+
35+
- name: Upload npm artifact
36+
uses: actions/upload-artifact@v4
37+
with:
38+
name: npm-package
39+
path: npm/
40+
retention-days: 1
41+
42+
- name: Upload jsr artifact
43+
uses: actions/upload-artifact@v4
44+
with:
45+
name: jsr-package
46+
path: build/
47+
retention-days: 1
3348

49+
npm:
50+
name: Publish to NPM
51+
runs-on: ubuntu-latest
52+
needs: build
53+
54+
steps:
55+
- name: Setup Node
56+
uses: actions/setup-node@v4
57+
with:
58+
node-version: '20'
59+
registry-url: 'https://registry.npmjs.org'
60+
61+
- name: Download npm artifact
62+
uses: actions/download-artifact@v4
63+
with:
64+
name: npm-package
65+
path: npm
3466

3567
- name: Publish
36-
run: |
37-
echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" > .npmrc
38-
if grep -qE "_authToken=.{1,}" .npmrc; then
39-
npm publish
40-
else
41-
echo "Failed to create .npmrc file" && exit 1
42-
fi
68+
run: npm publish
4369
working-directory: ./npm
4470
env:
45-
NPM_TOKEN: ${{ secrets.NPM_AUTOMATION_TOKEN }}
71+
NODE_AUTH_TOKEN: ${{ secrets.NPM_AUTOMATION_TOKEN }}
4672

4773
jsr:
4874
name: Publish to JSR
4975
runs-on: ubuntu-latest
5076
needs: build
5177

5278
steps:
53-
- name: Clone repository
54-
uses: actions/checkout@v3
55-
5679
- name: Install Deno
5780
uses: denoland/setup-deno@v1
5881
with:
5982
deno-version: v1.x
6083

61-
- name: Publish to JSR
62-
# publish-jsr.sh stages src + deno.json under ./build, strips
63-
# __tests__, then runs `deno publish --allow-dirty`. With
64-
# id-token: write set at the workflow level, deno publish
65-
# exchanges the OIDC token with JSR — no PAT needed.
66-
run: ./publish-jsr.sh
84+
- name: Download jsr artifact
85+
uses: actions/download-artifact@v4
86+
with:
87+
name: jsr-package
88+
path: build
89+
90+
# OIDC authenticates via the workflow-level id-token: write. Once the
91+
# JSR package is linked to this repo, no token secret is required.
92+
- name: Publish
93+
run: deno publish --allow-dirty
94+
working-directory: ./build

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ node_modules
22
coverage
33
scripts
44
npm
5+
build
56
dev
67
cov_profile
78
.vscode

publish-jsr.sh

Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,9 @@
11
#!/bin/bash
2+
# Local-dev wrapper: stage the JSR tree and publish it. CI splits these
3+
# two steps so the staged tree becomes a build artifact shared with the
4+
# npm publish job (see .github/workflows/publish.yaml).
25
set -euo pipefail
36

4-
# Clean up any existing build directory
5-
rm -rf build
6-
7-
# Create a fresh build directory
8-
mkdir build
9-
10-
# Copy necessary files to the build directory
11-
cp -R src build/
12-
cp -R __tests__ build/
13-
cp deno.json build/
14-
cp README.md build/
15-
cp LICENSE build/
16-
17-
# Change to the build directory
7+
./stage-jsr.sh
188
cd build
19-
20-
# Publish the package.
21-
# __tests__ was copied in above; strip it so JSR doesn't index tests.
22-
rm -rf __tests__
239
deno publish --allow-dirty

stage-jsr.sh

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#!/bin/bash
2+
# Stage a JSR-publishable tree under ./build. Used by both the local
3+
# publish-jsr.sh wrapper and the CI build job.
4+
set -euo pipefail
5+
6+
rm -rf build
7+
mkdir build
8+
9+
cp -R src build/
10+
cp deno.json build/
11+
cp README.md build/
12+
cp LICENSE build/
13+
14+
# __tests__ is intentionally NOT copied — JSR ships src + manifest only.

0 commit comments

Comments
 (0)