@@ -3,6 +3,8 @@ name: Publish
33# One workflow publishes every channel, since npm trusted publishing names a single workflow file.
44# - canary / dev: every push to that branch
55# - latest: run by hand on `main`; publishes each package whose version is not on npm yet
6+ # dev and latest also build the standalone binary and attach it to a GitHub Release: `devel`, one
7+ # prerelease replaced on every dev push, or `cli-v<version>`, marked latest. canary stays npm-only.
68on :
79 push :
810 branches : [canary, dev]
2628jobs :
2729 guard :
2830 runs-on : ubuntu-latest
31+ # The run's release id, computed once so every job publishes under the same version.
32+ outputs :
33+ id : ${{ steps.release.outputs.id }}
2934 steps :
3035 - if : github.event_name == 'workflow_dispatch' && github.ref_name != 'main'
3136 run : echo "::error::latest is published from main only" && exit 1
37+ - uses : actions/checkout@v6
38+ - uses : voidzero-dev/setup-vp@v1.21.1
39+ with :
40+ node-version : 24
41+ run-install : false
42+ cache : false
43+ - id : release
44+ run : echo "id=$(node scripts/version.mjs "$CHANNEL")" >> "$GITHUB_OUTPUT"
3245
3346 tui :
3447 needs : guard
7588 retention-days : 1
7689
7790 publish :
78- needs : tui
91+ needs : [guard, tui]
7992 runs-on : ubuntu-latest
93+ env :
94+ CODEWORK_RELEASE_ID : ${{ needs.guard.outputs.id }}
8095 steps :
8196 - uses : actions/checkout@v6
8297 - uses : voidzero-dev/setup-vp@v1.21.1
@@ -95,3 +110,93 @@ jobs:
95110 pattern : tui-*
96111 path : packages/tui/dist/bin
97112 - run : vp run release "$CHANNEL"
113+
114+ binary :
115+ needs : [guard, tui]
116+ if : github.ref_name != 'canary'
117+ name : binary (${{ matrix.binary }})
118+ runs-on : ${{ matrix.runner }}
119+ strategy :
120+ fail-fast : true
121+ matrix :
122+ # Each on its own platform: --build-sea runs that platform's Node, and macOS signs.
123+ include :
124+ - binary : cli-darwin-arm64
125+ tui : tui-darwin-arm64
126+ runner : macos-14
127+ - binary : cli-linux-arm64
128+ tui : tui-linux-arm64
129+ runner : ubuntu-24.04-arm
130+ - binary : cli-linux-x64
131+ tui : tui-linux-x64
132+ runner : ubuntu-24.04
133+ env :
134+ CODEWORK_RELEASE_ID : ${{ needs.guard.outputs.id }}
135+ steps :
136+ - uses : actions/checkout@v6
137+ # node-liblzma builds against the system liblzma at install. The bundle rebuilds it with xz
138+ # linked statically, which needs cmake; the runners ship it.
139+ - if : runner.os == 'Linux'
140+ run : sudo apt-get update && sudo apt-get install -y liblzma-dev
141+ - uses : voidzero-dev/setup-vp@v1.21.1
142+ with :
143+ node-version : 24
144+ run-install : false
145+ cache : false
146+ - run : vp install --frozen-lockfile --filter '!@codeworksh/www'
147+ - uses : actions/download-artifact@v8
148+ with :
149+ name : ${{ matrix.tui }}
150+ path : tui
151+ - run : |
152+ chmod +x tui/codework-tui
153+ echo "CODEWORK_TUI_BIN=$GITHUB_WORKSPACE/tui/codework-tui" >> "$GITHUB_ENV"
154+ echo "CODEWORK_VERSION=$(node scripts/version.mjs "$CHANNEL" packages/codework)" >> "$GITHUB_ENV"
155+ - working-directory : packages/codework
156+ run : vp run bundle && vp run sea
157+ # Without API keys only the offline case runs: the binary with no Node on PATH unpacks its
158+ # assets and runs a plugin through its own effect.
159+ - working-directory : packages/codework
160+ run : vp test test/sea.test.ts
161+ - run : tar -czf ${{ matrix.binary }}.tar.gz -C packages/codework/dist/sea codework
162+ - uses : actions/upload-artifact@v7
163+ with :
164+ name : ${{ matrix.binary }}
165+ path : ${{ matrix.binary }}.tar.gz
166+ if-no-files-found : error
167+ retention-days : 1
168+
169+ # After npm, so a release never names a version npm does not have.
170+ release :
171+ needs : [guard, publish, binary]
172+ if : github.ref_name != 'canary'
173+ runs-on : ubuntu-latest
174+ permissions :
175+ contents : write
176+ env :
177+ CODEWORK_RELEASE_ID : ${{ needs.guard.outputs.id }}
178+ GH_TOKEN : ${{ github.token }}
179+ steps :
180+ - uses : actions/checkout@v6
181+ - uses : voidzero-dev/setup-vp@v1.21.1
182+ with :
183+ node-version : 24
184+ run-install : false
185+ cache : false
186+ - uses : actions/download-artifact@v8
187+ with :
188+ pattern : cli-*
189+ path : release
190+ merge-multiple : true
191+ - run : |
192+ version="$(node scripts/version.mjs "$CHANNEL" packages/codework)"
193+ if [ "$CHANNEL" = dev ]; then
194+ gh release delete devel --cleanup-tag --yes || true
195+ gh release create devel release/*.tar.gz --prerelease --target "$GITHUB_SHA" \
196+ --title "CLI $version" --notes "Development build $version, from $GITHUB_SHA."
197+ elif gh release view "cli-v$version" > /dev/null 2>&1; then
198+ echo "cli-v$version is already released"
199+ else
200+ gh release create "cli-v$version" release/*.tar.gz --latest --target "$GITHUB_SHA" \
201+ --title "CLI $version" --generate-notes
202+ fi
0 commit comments