Skip to content

Commit 2930653

Browse files
committed
ci: Revert back to cargo-dist for releases
This reverts commit d815c6e.
1 parent 832e4bf commit 2930653

4 files changed

Lines changed: 391 additions & 61 deletions

File tree

.github/workflows/release.yml

Lines changed: 360 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,372 @@
1+
# This file was autogenerated by dist: https://axodotdev.github.io/cargo-dist
2+
#
3+
# Copyright 2022-2024, axodotdev
4+
# SPDX-License-Identifier: MIT or Apache-2.0
5+
#
6+
# CI that:
7+
#
8+
# * checks for a Git Tag that looks like a release
9+
# * builds artifacts with dist (archives, installers, hashes)
10+
# * uploads those artifacts to temporary workflow zip
11+
# * on success, uploads the artifacts to a GitHub Release
12+
#
13+
# Note that the GitHub Release will be created with a generated
14+
# title/body based on your changelogs.
15+
116
name: Release
17+
permissions:
18+
"contents": "write"
219

20+
# This task will run whenever you push a git tag that looks like a version
21+
# like "1.0.0", "v0.1.0-prerelease.1", "my-app/0.1.0", "releases/v1.0.0", etc.
22+
# Various formats will be parsed into a VERSION and an optional PACKAGE_NAME, where
23+
# PACKAGE_NAME must be the name of a Cargo package in your workspace, and VERSION
24+
# must be a Cargo-style SemVer Version (must have at least major.minor.patch).
25+
#
26+
# If PACKAGE_NAME is specified, then the announcement will be for that
27+
# package (erroring out if it doesn't have the given version or isn't dist-able).
28+
#
29+
# If PACKAGE_NAME isn't specified, then the announcement will be for all
30+
# (dist-able) packages in the workspace with that version (this mode is
31+
# intended for workspaces with only one dist-able package, or with all dist-able
32+
# packages versioned/released in lockstep).
33+
#
34+
# If you push multiple tags at once, separate instances of this workflow will
35+
# spin up, creating an independent announcement for each one. However, GitHub
36+
# will hard limit this to 3 tags per commit, as it will assume more tags is a
37+
# mistake.
38+
#
39+
# If there's a prerelease-style suffix to the version, then the release(s)
40+
# will be marked as a prerelease.
341
on:
42+
pull_request:
443
push:
544
tags:
6-
- v*
7-
8-
permissions:
9-
contents: write # Create releases, upload artifacts, and update the repository
10-
id-token: write # Required for attest build provenance
11-
attestations: write # Required for attest build provenance
45+
- '**[0-9]+.[0-9]+.[0-9]+*'
1246

1347
jobs:
14-
goreleaser:
15-
runs-on: ubuntu-latest
48+
# Run 'dist plan' (or host) to determine what tasks we need to do
49+
plan:
50+
runs-on: "ubuntu-22.04"
51+
outputs:
52+
val: ${{ steps.plan.outputs.manifest }}
53+
tag: ${{ !github.event.pull_request && github.ref_name || '' }}
54+
tag-flag: ${{ !github.event.pull_request && format('--tag={0}', github.ref_name) || '' }}
55+
publishing: ${{ !github.event.pull_request }}
56+
env:
57+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
58+
steps:
59+
- uses: actions/checkout@v4
60+
with:
61+
persist-credentials: false
62+
submodules: recursive
63+
- name: Install dist
64+
# we specify bash to get pipefail; it guards against the `curl` command
65+
# failing. otherwise `sh` won't catch that `curl` returned non-0
66+
shell: bash
67+
run: "curl --proto '=https' --tlsv1.2 -LsSf https://github.com/axodotdev/cargo-dist/releases/download/v0.30.2/cargo-dist-installer.sh | sh"
68+
- name: Cache dist
69+
uses: actions/upload-artifact@v4
70+
with:
71+
name: cargo-dist-cache
72+
path: ~/.cargo/bin/dist
73+
# sure would be cool if github gave us proper conditionals...
74+
# so here's a doubly-nested ternary-via-truthiness to try to provide the best possible
75+
# functionality based on whether this is a pull_request, and whether it's from a fork.
76+
# (PRs run on the *source* but secrets are usually on the *target* -- that's *good*
77+
# but also really annoying to build CI around when it needs secrets to work right.)
78+
- id: plan
79+
run: |
80+
dist ${{ (!github.event.pull_request && format('host --steps=create --tag={0}', github.ref_name)) || 'plan' }} --output-format=json > plan-dist-manifest.json
81+
echo "dist ran successfully"
82+
cat plan-dist-manifest.json
83+
echo "manifest=$(jq -c "." plan-dist-manifest.json)" >> "$GITHUB_OUTPUT"
84+
- name: "Upload dist-manifest.json"
85+
uses: actions/upload-artifact@v4
86+
with:
87+
name: artifacts-plan-dist-manifest
88+
path: plan-dist-manifest.json
89+
90+
# Build and packages all the platform-specific things
91+
build-local-artifacts:
92+
name: build-local-artifacts (${{ join(matrix.targets, ', ') }})
93+
# Let the initial task tell us to not run (currently very blunt)
94+
needs:
95+
- plan
96+
if: ${{ fromJson(needs.plan.outputs.val).ci.github.artifacts_matrix.include != null && (needs.plan.outputs.publishing == 'true' || fromJson(needs.plan.outputs.val).ci.github.pr_run_mode == 'upload') }}
97+
strategy:
98+
fail-fast: false
99+
# Target platforms/runners are computed by dist in create-release.
100+
# Each member of the matrix has the following arguments:
101+
#
102+
# - runner: the github runner
103+
# - dist-args: cli flags to pass to dist
104+
# - install-dist: expression to run to install dist on the runner
105+
#
106+
# Typically there will be:
107+
# - 1 "global" task that builds universal installers
108+
# - N "local" tasks that build each platform's binaries and platform-specific installers
109+
matrix: ${{ fromJson(needs.plan.outputs.val).ci.github.artifacts_matrix }}
110+
runs-on: ${{ matrix.runner }}
111+
container: ${{ matrix.container && matrix.container.image || null }}
112+
env:
113+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
114+
BUILD_MANIFEST_NAME: target/distrib/${{ join(matrix.targets, '-') }}-dist-manifest.json
115+
permissions:
116+
"attestations": "write"
117+
"contents": "read"
118+
"id-token": "write"
119+
steps:
120+
- name: enable windows longpaths
121+
run: |
122+
git config --global core.longpaths true
123+
- uses: actions/checkout@v4
124+
with:
125+
persist-credentials: false
126+
submodules: recursive
127+
- name: Install Rust non-interactively if not already installed
128+
if: ${{ matrix.container }}
129+
run: |
130+
if ! command -v cargo > /dev/null 2>&1; then
131+
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
132+
echo "$HOME/.cargo/bin" >> $GITHUB_PATH
133+
fi
134+
- name: Install dist
135+
run: ${{ matrix.install_dist.run }}
136+
# Get the dist-manifest
137+
- name: Fetch local artifacts
138+
uses: actions/download-artifact@v4
139+
with:
140+
pattern: artifacts-*
141+
path: target/distrib/
142+
merge-multiple: true
143+
- name: Install cargo-auditable
144+
run: ${{ matrix.install_cargo_auditable.run }}
145+
- name: Install dependencies
146+
run: |
147+
${{ matrix.packages_install }}
148+
- name: Build artifacts
149+
run: |
150+
# Actually do builds and make zips and whatnot
151+
dist build ${{ needs.plan.outputs.tag-flag }} --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json
152+
echo "dist ran successfully"
153+
- name: Attest
154+
uses: actions/attest-build-provenance@v2
155+
with:
156+
subject-path: "target/distrib/*${{ join(matrix.targets, ', ') }}*"
157+
- id: cargo-dist
158+
name: Post-build
159+
# We force bash here just because github makes it really hard to get values up
160+
# to "real" actions without writing to env-vars, and writing to env-vars has
161+
# inconsistent syntax between shell and powershell.
162+
shell: bash
163+
run: |
164+
# Parse out what we just built and upload it to scratch storage
165+
echo "paths<<EOF" >> "$GITHUB_OUTPUT"
166+
dist print-upload-files-from-manifest --manifest dist-manifest.json >> "$GITHUB_OUTPUT"
167+
echo "EOF" >> "$GITHUB_OUTPUT"
168+
169+
cp dist-manifest.json "$BUILD_MANIFEST_NAME"
170+
- name: "Upload artifacts"
171+
uses: actions/upload-artifact@v4
172+
with:
173+
name: artifacts-build-local-${{ join(matrix.targets, '_') }}
174+
path: |
175+
${{ steps.cargo-dist.outputs.paths }}
176+
${{ env.BUILD_MANIFEST_NAME }}
177+
178+
# Build and package all the platform-agnostic(ish) things
179+
build-global-artifacts:
180+
needs:
181+
- plan
182+
- build-local-artifacts
183+
runs-on: "ubuntu-22.04"
184+
env:
185+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
186+
BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json
187+
steps:
188+
- uses: actions/checkout@v4
189+
with:
190+
persist-credentials: false
191+
submodules: recursive
192+
- name: Install cached dist
193+
uses: actions/download-artifact@v4
194+
with:
195+
name: cargo-dist-cache
196+
path: ~/.cargo/bin/
197+
- run: chmod +x ~/.cargo/bin/dist
198+
- name: Install cargo-cyclonedx
199+
# we specify bash to get pipefail; it guards against the `curl` command
200+
# failing. otherwise `sh` won't catch that `curl` return non-0
201+
run: "curl --proto '=https' --tlsv1.2 -LsSf https://github.com/CycloneDX/cyclonedx-rust-cargo/releases/download/cargo-cyclonedx-0.5.5/cargo-cyclonedx-installer.sh | sh"
202+
shell: bash
203+
# Get all the local artifacts for the global tasks to use (for e.g. checksums)
204+
- name: Fetch local artifacts
205+
uses: actions/download-artifact@v4
206+
with:
207+
pattern: artifacts-*
208+
path: target/distrib/
209+
merge-multiple: true
210+
- id: cargo-dist
211+
shell: bash
212+
run: |
213+
dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json "--artifacts=global" > dist-manifest.json
214+
echo "dist ran successfully"
215+
216+
# Parse out what we just built and upload it to scratch storage
217+
echo "paths<<EOF" >> "$GITHUB_OUTPUT"
218+
jq --raw-output ".upload_files[]" dist-manifest.json >> "$GITHUB_OUTPUT"
219+
echo "EOF" >> "$GITHUB_OUTPUT"
220+
221+
cp dist-manifest.json "$BUILD_MANIFEST_NAME"
222+
- id: cargo-cyclonedx
223+
shell: bash
224+
run: |
225+
# Generate SBOM (.cdx.xml) files.
226+
cargo cyclonedx -v
227+
228+
# Move all SBOM (.cdx.xml) files under target/distrib/ since
229+
# we expect all artifacts to be in that folder.
230+
find . -name '*.cdx.xml' -exec mv '{}' target/distrib/ ';'
231+
232+
echo "paths<<EOF" >> "$GITHUB_OUTPUT"
233+
find . -name '*.cdx.xml' | tee -a "$GITHUB_OUTPUT"
234+
echo "EOF" >> "$GITHUB_OUTPUT"
235+
- name: "Upload artifacts"
236+
uses: actions/upload-artifact@v4
237+
with:
238+
name: artifacts-build-global
239+
path: |
240+
${{ steps.cargo-dist.outputs.paths }}
241+
${{ steps.cargo-cyclonedx.output.paths }}
242+
${{ env.BUILD_MANIFEST_NAME }}
243+
# Determines if we should publish/announce
244+
host:
245+
needs:
246+
- plan
247+
- build-local-artifacts
248+
- build-global-artifacts
249+
# Only run if we're "publishing", and only if plan, local and global didn't fail (skipped is fine)
250+
if: ${{ always() && needs.plan.result == 'success' && 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') }}
251+
env:
252+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
253+
runs-on: "ubuntu-22.04"
254+
outputs:
255+
val: ${{ steps.host.outputs.manifest }}
16256
steps:
17-
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
257+
- uses: actions/checkout@v4
258+
with:
259+
persist-credentials: false
260+
submodules: recursive
261+
- name: Install cached dist
262+
uses: actions/download-artifact@v4
263+
with:
264+
name: cargo-dist-cache
265+
path: ~/.cargo/bin/
266+
- run: chmod +x ~/.cargo/bin/dist
267+
# Fetch artifacts from scratch-storage
268+
- name: Fetch artifacts
269+
uses: actions/download-artifact@v4
18270
with:
19-
fetch-depth: 0
20-
- uses: actions-rust-lang/setup-rust-toolchain@02be93da58aa71fb456aa9c43b301149248829d8 # v1.15.1
21-
- uses: mlugg/setup-zig@8d6198c65fb0feaa111df26e6b467fea8345e46f # v2.0.5
22-
- name: Run GoReleaser
23-
uses: goreleaser/goreleaser-action@9c156ee8a17a598857849441385a2041ef570552 # v6.3.0
271+
pattern: artifacts-*
272+
path: target/distrib/
273+
merge-multiple: true
274+
- id: host
275+
shell: bash
276+
run: |
277+
dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json > dist-manifest.json
278+
echo "artifacts uploaded and released successfully"
279+
cat dist-manifest.json
280+
echo "manifest=$(jq -c "." dist-manifest.json)" >> "$GITHUB_OUTPUT"
281+
- name: "Upload dist-manifest.json"
282+
uses: actions/upload-artifact@v4
24283
with:
25-
version: '~> v2'
26-
args: release --clean
284+
# Overwrite the previous copy
285+
name: artifacts-dist-manifest
286+
path: dist-manifest.json
287+
# Create a GitHub Release while uploading all files to it
288+
- name: "Download GitHub Artifacts"
289+
uses: actions/download-artifact@v4
290+
with:
291+
pattern: artifacts-*
292+
path: artifacts
293+
merge-multiple: true
294+
- name: Cleanup
295+
run: |
296+
# Remove the granular manifests
297+
rm -f artifacts/*-dist-manifest.json
298+
- name: Create GitHub Release
27299
env:
28-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
29-
HOMEBREW_TAP_TOKEN: ${{ secrets.HOMEBREW_TAP_TOKEN }}
30-
- uses: actions/attest-build-provenance@977bb373ede98d70efdf65b84cb5f73e068dcc2a # v3.0.0
300+
PRERELEASE_FLAG: "${{ fromJson(steps.host.outputs.manifest).announcement_is_prerelease && '--prerelease' || '' }}"
301+
ANNOUNCEMENT_TITLE: "${{ fromJson(steps.host.outputs.manifest).announcement_title }}"
302+
ANNOUNCEMENT_BODY: "${{ fromJson(steps.host.outputs.manifest).announcement_github_body }}"
303+
RELEASE_COMMIT: "${{ github.sha }}"
304+
run: |
305+
# Write and read notes from a file to avoid quoting breaking things
306+
echo "$ANNOUNCEMENT_BODY" > $RUNNER_TEMP/notes.txt
307+
308+
gh release create "${{ needs.plan.outputs.tag }}" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/*
309+
310+
publish-homebrew-formula:
311+
needs:
312+
- plan
313+
- host
314+
runs-on: "ubuntu-22.04"
315+
env:
316+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
317+
PLAN: ${{ needs.plan.outputs.val }}
318+
GITHUB_USER: "axo bot"
319+
GITHUB_EMAIL: "admin+bot@axo.dev"
320+
if: ${{ !fromJson(needs.plan.outputs.val).announcement_is_prerelease || fromJson(needs.plan.outputs.val).publish_prereleases }}
321+
steps:
322+
- uses: actions/checkout@v4
323+
with:
324+
persist-credentials: true
325+
repository: "marcfrederick/homebrew-tap"
326+
token: ${{ secrets.HOMEBREW_TAP_TOKEN }}
327+
# So we have access to the formula
328+
- name: Fetch homebrew formulae
329+
uses: actions/download-artifact@v4
330+
with:
331+
pattern: artifacts-*
332+
path: Formula/
333+
merge-multiple: true
334+
# This is extra complex because you can make your Formula name not match your app name
335+
# so we need to find releases with a *.rb file, and publish with that filename.
336+
- name: Commit formula files
337+
run: |
338+
git config --global user.name "${GITHUB_USER}"
339+
git config --global user.email "${GITHUB_EMAIL}"
340+
341+
for release in $(echo "$PLAN" | jq --compact-output '.releases[] | select([.artifacts[] | endswith(".rb")] | any)'); do
342+
filename=$(echo "$release" | jq '.artifacts[] | select(endswith(".rb"))' --raw-output)
343+
name=$(echo "$filename" | sed "s/\.rb$//")
344+
version=$(echo "$release" | jq .app_version --raw-output)
345+
346+
export PATH="/home/linuxbrew/.linuxbrew/bin:$PATH"
347+
brew update
348+
# We avoid reformatting user-provided data such as the app description and homepage.
349+
brew style --except-cops FormulaAudit/Homepage,FormulaAudit/Desc,FormulaAuditStrict --fix "Formula/${filename}" || true
350+
351+
git add "Formula/${filename}"
352+
git commit -m "${name} ${version}"
353+
done
354+
git push
355+
356+
announce:
357+
needs:
358+
- plan
359+
- host
360+
- publish-homebrew-formula
361+
# use "always() && ..." to allow us to wait for all publish jobs while
362+
# still allowing individual publish jobs to skip themselves (for prereleases).
363+
# "host" however must run to completion, no skipping allowed!
364+
if: ${{ always() && needs.host.result == 'success' && (needs.publish-homebrew-formula.result == 'skipped' || needs.publish-homebrew-formula.result == 'success') }}
365+
runs-on: "ubuntu-22.04"
366+
env:
367+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
368+
steps:
369+
- uses: actions/checkout@v4
31370
with:
32-
subject-checksums: ./dist/checksums.txt
371+
persist-credentials: false
372+
submodules: recursive

.gitignore

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1 @@
1-
dist/
2-
target/
1+
/target

0 commit comments

Comments
 (0)