@@ -19,10 +19,13 @@ concurrency:
1919 cancel-in-progress : false
2020
2121jobs :
22- publish :
23- name : publish
22+ build :
23+ name : build
2424 runs-on : ${{ (vars.CI_PROVIDER == '' || vars.CI_PROVIDER == 'blacksmith') && 'blacksmith-4vcpu-ubuntu-2404' || 'ubuntu-latest' }}
2525 timeout-minutes : 15
26+ outputs :
27+ version : ${{ steps.release.outputs.version }}
28+ tag : ${{ steps.release.outputs.tag }}
2629 steps :
2730 - name : Checkout repository
2831 uses : actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v6
3740 provider : ${{ vars.CI_PROVIDER }}
3841 node-version : ' 22'
3942
40- - name : Verify npm authentication
41- env :
42- NPM_CONFIG_TOKEN : ${{ secrets.NPM_TOKEN }}
43- run : bun pm whoami
44-
4543 - name : Auto-bump package version
4644 run : bun run bump:npm-packages sim-cli
4745
5452 run : bun run type-check
5553
5654 # The usage-reporting destination is baked into the bundle at build time
57- # (docs/cli/usage-data), so only the two steps that build it get the
58- # token. Every other step, the tests above in particular, runs without
59- # it: a test that runs a real command must never report to production.
55+ # (docs/cli/usage-data), so only this step gets the token, and the
56+ # tarball packed from its output is what ships. Every other step, the
57+ # tests above in particular, runs without it: a test that runs a real
58+ # command must never report to production.
6059 - name : Build package
6160 working-directory : packages/sim-cli
6261 env :
@@ -107,23 +106,28 @@ jobs:
107106 echo "tag=$TAG"
108107 } >> "$GITHUB_OUTPUT"
109108
109+ # Bun packs because it rewrites `workspace:` ranges to real versions,
110+ # which `npm pack` would publish verbatim. The smoke test below and the
111+ # publish job both use this one tarball, so what was tested is what ships.
112+ - name : Pack package
113+ working-directory : packages/sim-cli
114+ run : bun pm pack --ignore-scripts --filename "$RUNNER_TEMP/package.tgz" --quiet
115+
110116 - name : Setup Node 20 for the bundle smoke test
111117 uses : actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v6
112118 with :
113119 node-version : ' 20'
114120
115121 - name : Smoke-test packed Node bundle
116- working-directory : packages/sim-cli
122+ env :
123+ VERSION : ${{ steps.release.outputs.version }}
117124 run : |
118125 set -euo pipefail
119126 SMOKE_DIR="$(mktemp -d "$RUNNER_TEMP/sim-cli-smoke.XXXXXX")"
120- PACKAGE_PATH="$SMOKE_DIR/sim-cli.tgz"
121- bun pm pack --ignore-scripts --filename "$PACKAGE_PATH" --quiet
122- tar -xzf "$PACKAGE_PATH" -C "$SMOKE_DIR"
123- "$SMOKE_DIR/package/dist/index.js" --version
127+ tar -xzf "$RUNNER_TEMP/package.tgz" -C "$SMOKE_DIR"
128+ test "$("$SMOKE_DIR/package/dist/index.js" --version)" = "$VERSION"
124129
125130 - name : Verify version is unpublished
126- working-directory : packages/sim-cli
127131 env :
128132 VERSION : ${{ steps.release.outputs.version }}
129133 run : |
@@ -132,19 +136,47 @@ jobs:
132136 exit 1
133137 fi
134138
135- # `bun publish` runs `prepublishOnly`, which rebuilds `dist`, and that
136- # rebuild is what ships, so it needs the token as well.
139+ - name : Upload package
140+ uses : actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
141+ with :
142+ name : package
143+ path : ${{ runner.temp }}/package.tgz
144+ if-no-files-found : error
145+ retention-days : 1
146+
147+ # npm trusted publishing trades this job's OIDC token for a short-lived npm
148+ # credential, so no npm token is stored anywhere. npm accepts the token only
149+ # from GitHub-hosted runners, and only this job can mint one: it runs no
150+ # repository code, it publishes the tarball the build job tested. npm runs no
151+ # lifecycle scripts for a tarball, so nothing is rebuilt here, and provenance
152+ # is attached automatically.
153+ publish :
154+ name : publish
155+ needs : build
156+ runs-on : ubuntu-latest
157+ timeout-minutes : 10
158+ permissions :
159+ id-token : write
160+ steps :
161+ # Node 24 bundles npm 11.5.1+, which trusted publishing requires.
162+ - name : Setup Node
163+ uses : actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v6
164+ with :
165+ node-version : ' 24'
166+
167+ - name : Download package
168+ uses : actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
169+ with :
170+ name : package
171+ path : ${{ runner.temp }}
172+
137173 - name : Publish to npm
138- working-directory : packages/sim-cli
139174 env :
140- NPM_CONFIG_TOKEN : ${{ secrets.NPM_TOKEN }}
141- NPM_TAG : ${{ steps.release.outputs.tag }}
142- SIM_CLI_TELEMETRY_KEY : ${{ vars.SIM_CLI_TELEMETRY_KEY }}
143- SIM_CLI_TELEMETRY_HOST : ${{ vars.SIM_CLI_TELEMETRY_HOST }}
144- run : bun publish --access public --tag "$NPM_TAG" --no-save
175+ NPM_TAG : ${{ needs.build.outputs.tag }}
176+ run : npm publish "$RUNNER_TEMP/package.tgz" --access public --tag "$NPM_TAG"
145177
146178 - name : Summarize release
147179 env :
148- VERSION : ${{ steps.release .outputs.version }}
149- NPM_TAG : ${{ steps.release .outputs.tag }}
180+ VERSION : ${{ needs.build .outputs.version }}
181+ NPM_TAG : ${{ needs.build .outputs.tag }}
150182 run : echo "Published sim@$VERSION with the '$NPM_TAG' tag."
0 commit comments