88# * checks for a Git Tag that looks like a release
99# * builds artifacts with dist (archives, installers, hashes)
1010# * uploads those artifacts to temporary workflow zip
11- # * on success, uploads the artifacts to Axo Releases and makes an Announcement
1211# * on success, uploads the artifacts to a GitHub Release
1312#
1413# Note that the GitHub Release will be created with a generated
5049jobs :
5150 # Run 'dist plan' (or host) to determine what tasks we need to do
5251 plan :
53- runs-on : " ubuntu-24.04 "
52+ runs-on : " ubuntu-latest "
5453 outputs :
5554 val : ${{ steps.plan.outputs.manifest }}
5655 tag : ${{ !github.event.pull_request && github.ref_name || '' }}
5756 tag-flag : ${{ !github.event.pull_request && format('--tag={0}', github.ref_name) || '' }}
5857 publishing : ${{ !github.event.pull_request }}
5958 env :
6059 GH_TOKEN : ${{ secrets.GITHUB_TOKEN }}
61- AXO_RELEASES_TOKEN : ${{ secrets.AXO_RELEASES_TOKEN }}
6260 steps :
6361 - uses : actions/checkout@v4
6462 with :
6765 # we specify bash to get pipefail; it guards against the `curl` command
6866 # failing. otherwise `sh` won't catch that `curl` returned non-0
6967 shell : bash
70- run : " curl --proto '=https' --tlsv1.2 -LsSf https://github.com/oxidecomputer /cargo-dist/releases/download/v1.0.0-rc.1 /cargo-dist-installer.sh | sh"
68+ run : " curl --proto '=https' --tlsv1.2 -LsSf https://github.com/axodotdev /cargo-dist/releases/download/v0.28.0 /cargo-dist-installer.sh | sh"
7169 - name : Cache dist
7270 uses : actions/upload-artifact@v4
7371 with :
8078 # but also really annoying to build CI around when it needs secrets to work right.)
8179 - id : plan
8280 run : |
83- dist ${{ (!github.event.pull_request && format('host --steps=create --tag={0}', github.ref_name)) || (env.AXO_RELEASES_TOKEN && 'host --steps=check') || 'plan' }} --output-format=json > plan-dist-manifest.json
81+ dist ${{ (!github.event.pull_request && format('host --steps=create --tag={0}', github.ref_name)) || 'plan' }} --output-format=json > plan-dist-manifest.json
8482 echo "dist ran successfully"
8583 cat plan-dist-manifest.json
8684 echo "manifest=$(jq -c "." plan-dist-manifest.json)" >> "$GITHUB_OUTPUT"
@@ -147,7 +145,7 @@ jobs:
147145 dist build ${{ needs.plan.outputs.tag-flag }} --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json
148146 echo "dist ran successfully"
149147 - name : Attest
150- uses : actions/attest-build-provenance@v2
148+ uses : actions/attest-build-provenance@v1
151149 with :
152150 subject-path : " target/distrib/*${{ join(matrix.targets, ', ') }}*"
153151 - id : cargo-dist
@@ -176,7 +174,7 @@ jobs:
176174 needs :
177175 - plan
178176 - build-local-artifacts
179- runs-on : " ubuntu-24.04 "
177+ runs-on : " ubuntu-latest "
180178 env :
181179 GH_TOKEN : ${{ secrets.GITHUB_TOKEN }}
182180 BUILD_MANIFEST_NAME : target/distrib/global-dist-manifest.json
@@ -216,16 +214,7 @@ jobs:
216214 path : |
217215 ${{ steps.cargo-dist.outputs.paths }}
218216 ${{ env.BUILD_MANIFEST_NAME }}
219- # Uploads the artifacts to Axo Releases and tentatively creates Releases for them.
220- # This makes perma URLs like /v1.0.0/ live for subsequent publish steps to use, but
221- # leaves them "disconnected" from the release history (for the purposes of
222- # "list the releases" or "give me the latest releases").
223- #
224- # If all the subsequent "publish" steps succeed, the "announce" job will "connect"
225- # the releases and concepts like "latest" will be updated. Otherwise you're hopefully
226- # in a decent position to roll back the release without anyone noticing it!
227- # This is imperfect with things like "publish to crates.io" being irreversible, but
228- # at worst you're in a better position to yank the version with minimum disruption.
217+ # Determines if we should publish/announce
229218 host :
230219 needs :
231220 - plan
@@ -235,8 +224,7 @@ jobs:
235224 if : ${{ always() && needs.plan.outputs.publishing == 'true' && (needs.build-global-artifacts.result == 'skipped' || needs.build-global-artifacts.result == 'success') && (needs.build-local-artifacts.result == 'skipped' || needs.build-local-artifacts.result == 'success') }}
236225 env :
237226 GH_TOKEN : ${{ secrets.GITHUB_TOKEN }}
238- AXO_RELEASES_TOKEN : ${{ secrets.AXO_RELEASES_TOKEN }}
239- runs-on : " ubuntu-24.04"
227+ runs-on : " ubuntu-latest"
240228 outputs :
241229 val : ${{ steps.host.outputs.manifest }}
242230 steps :
@@ -256,8 +244,6 @@ jobs:
256244 pattern : artifacts-*
257245 path : target/distrib/
258246 merge-multiple : true
259- # Upload files to Axo Releases and create the Releases
260- # This is a harmless no-op for GitHub Releases, hosting for that happens in "announce"
261247 - id : host
262248 shell : bash
263249 run : |
@@ -271,149 +257,41 @@ jobs:
271257 # Overwrite the previous copy
272258 name : artifacts-dist-manifest
273259 path : dist-manifest.json
274-
275- publish-homebrew-formula :
276- needs :
277- - plan
278- - host
279- runs-on : " ubuntu-24.04"
280- env :
281- GH_TOKEN : ${{ secrets.GITHUB_TOKEN }}
282- PLAN : ${{ needs.plan.outputs.val }}
283- GITHUB_USER : " axo bot"
284- GITHUB_EMAIL : " admin+bot@axo.dev"
285- if : ${{ !fromJson(needs.plan.outputs.val).announcement_is_prerelease || fromJson(needs.plan.outputs.val).publish_prereleases }}
286- steps :
287- - uses : actions/checkout@v4
288- with :
289- repository : " axodotdev/homebrew-tap"
290- token : ${{ secrets.HOMEBREW_TAP_TOKEN }}
291- # So we have access to the formula
292- - name : Fetch homebrew formulae
260+ # Create a GitHub Release while uploading all files to it
261+ - name : " Download GitHub Artifacts"
293262 uses : actions/download-artifact@v4
294263 with :
295264 pattern : artifacts-*
296- path : Formula/
265+ path : artifacts
297266 merge-multiple : true
298- # This is extra complex because you can make your Formula name not match your app name
299- # so we need to find releases with a *.rb file, and publish with that filename.
300- - name : Commit formula files
267+ - name : Cleanup
301268 run : |
302- git config --global user.name "${GITHUB_USER}"
303- git config --global user.email "${GITHUB_EMAIL}"
304-
305- for release in $(echo "$PLAN" | jq --compact-output '.releases[] | select([.artifacts[] | endswith(".rb")] | any)'); do
306- filename=$(echo "$release" | jq '.artifacts[] | select(endswith(".rb"))' --raw-output)
307- name=$(echo "$filename" | sed "s/\.rb$//")
308- version=$(echo "$release" | jq .app_version --raw-output)
309-
310- export PATH="/home/linuxbrew/.linuxbrew/bin:$PATH"
311- brew update
312- # We avoid reformatting user-provided data such as the app description and homepage.
313- brew style --except-cops FormulaAudit/Homepage,FormulaAudit/Desc,FormulaAuditStrict --fix "Formula/${filename}" || true
314-
315- git add "Formula/${filename}"
316- git commit -m "${name} ${version}"
317- done
318- git push
319-
320- publish-npm :
321- needs :
322- - plan
323- - host
324- runs-on : " ubuntu-24.04"
325- env :
326- GH_TOKEN : ${{ secrets.GITHUB_TOKEN }}
327- PLAN : ${{ needs.plan.outputs.val }}
328- if : ${{ !fromJson(needs.plan.outputs.val).announcement_is_prerelease || fromJson(needs.plan.outputs.val).publish_prereleases }}
329- steps :
330- - name : Fetch npm packages
331- uses : actions/download-artifact@v4
332- with :
333- pattern : artifacts-*
334- path : npm/
335- merge-multiple : true
336- - uses : actions/setup-node@v4
337- with :
338- node-version : ' 20.x'
339- registry-url : ' https://registry.npmjs.org'
340- - run : |
341- for release in $(echo "$PLAN" | jq --compact-output '.releases[] | select([.artifacts[] | endswith("-npm-package.tar.gz")] | any)'); do
342- pkg=$(echo "$release" | jq '.artifacts[] | select(endswith("-npm-package.tar.gz"))' --raw-output)
343- npm publish --access public "./npm/${pkg}"
344- done
269+ # Remove the granular manifests
270+ rm -f artifacts/*-dist-manifest.json
271+ - name : Create GitHub Release
345272 env :
346- NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
273+ PRERELEASE_FLAG : " ${{ fromJson(steps.host.outputs.manifest).announcement_is_prerelease && '--prerelease' || '' }}"
274+ ANNOUNCEMENT_TITLE : " ${{ fromJson(steps.host.outputs.manifest).announcement_title }}"
275+ ANNOUNCEMENT_BODY : " ${{ fromJson(steps.host.outputs.manifest).announcement_github_body }}"
276+ RELEASE_COMMIT : " ${{ github.sha }}"
277+ run : |
278+ # Write and read notes from a file to avoid quoting breaking things
279+ echo "$ANNOUNCEMENT_BODY" > $RUNNER_TEMP/notes.txt
347280
348- custom-publish-crates :
349- needs :
350- - plan
351- - host
352- if : ${{ !fromJson(needs.plan.outputs.val).announcement_is_prerelease || fromJson(needs.plan.outputs.val).publish_prereleases }}
353- uses : ./.github/workflows/publish-crates.yml
354- with :
355- plan : ${{ needs.plan.outputs.val }}
356- secrets : inherit
357- # publish jobs get escalated permissions
358- permissions :
359- " id-token " : " write"
360- " packages " : " write"
281+ gh release create "${{ needs.plan.outputs.tag }}" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/*
361282
362- # Create an Announcement for all the Axo Releases, updating the "latest" release
363- # Create a GitHub Release while uploading all files to it
364283 announce :
365284 needs :
366285 - plan
367286 - host
368- - publish-homebrew-formula
369- - publish-npm
370- - custom-publish-crates
371287 # use "always() && ..." to allow us to wait for all publish jobs while
372288 # still allowing individual publish jobs to skip themselves (for prereleases).
373289 # "host" however must run to completion, no skipping allowed!
374- if : ${{ always() && needs.host.result == 'success' && (needs.publish-homebrew-formula.result == 'skipped' || needs.publish-homebrew-formula.result == 'success') && (needs.publish-npm.result == 'skipped' || needs.publish-npm.result == 'success') && (needs.custom-publish-crates.result == 'skipped' || needs.custom-publish-crates.result == 'success') }}
375- runs-on : " ubuntu-24.04 "
290+ if : ${{ always() && needs.host.result == 'success' }}
291+ runs-on : " ubuntu-latest "
376292 env :
377293 GH_TOKEN : ${{ secrets.GITHUB_TOKEN }}
378- AXO_RELEASES_TOKEN : ${{ secrets.AXO_RELEASES_TOKEN }}
379294 steps :
380295 - uses : actions/checkout@v4
381296 with :
382297 submodules : recursive
383- - name : Install cached dist
384- uses : actions/download-artifact@v4
385- with :
386- name : cargo-dist-cache
387- path : ~/.cargo/bin/
388- - run : chmod +x ~/.cargo/bin/dist
389- - name : Fetch Axo Artifacts
390- uses : actions/download-artifact@v4
391- with :
392- pattern : artifacts-*
393- path : target/distrib/
394- merge-multiple : true
395- - name : Announce Axo Releases
396- run : |
397- dist host --steps=announce ${{ needs.plan.outputs.tag-flag }}
398- # Create a GitHub Release while uploading all files to it
399- - name : " Download GitHub Artifacts"
400- uses : actions/download-artifact@v4
401- with :
402- pattern : artifacts-*
403- path : artifacts
404- merge-multiple : true
405- - name : Cleanup
406- run : |
407- # Remove the granular manifests
408- rm -f artifacts/*-dist-manifest.json
409- - name : Create GitHub Release
410- env :
411- PRERELEASE_FLAG : " ${{ fromJson(needs.host.outputs.val).announcement_is_prerelease && '--prerelease' || '' }}"
412- ANNOUNCEMENT_TITLE : " ${{ fromJson(needs.host.outputs.val).announcement_title }}"
413- ANNOUNCEMENT_BODY : " ${{ fromJson(needs.host.outputs.val).announcement_github_body }}"
414- RELEASE_COMMIT : " ${{ github.sha }}"
415- run : |
416- # Write and read notes from a file to avoid quoting breaking things
417- echo "$ANNOUNCEMENT_BODY" > $RUNNER_TEMP/notes.txt
418-
419- gh release create "${{ needs.plan.outputs.tag }}" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/*
0 commit comments