-
Notifications
You must be signed in to change notification settings - Fork 0
196 lines (171 loc) · 6.27 KB
/
Copy pathrelease.yml
File metadata and controls
196 lines (171 loc) · 6.27 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
name: Release
# Publishes a Linux and a Windows binary whenever a v* tag is pushed.
#
# git tag -a v0.2.0 -m "v0.2.0" && git push origin v0.2.0
#
# Run it manually from the Actions tab to build the artifacts without
# publishing anything (useful for checking a release before tagging).
on:
push:
tags:
- "v*"
workflow_dispatch:
permissions:
contents: read
env:
CARGO_TERM_COLOR: always
jobs:
# The SPA is embedded into the executable at compile time, so it must be
# built before cargo runs. It is built once here and shared with every
# platform build, which guarantees both binaries ship an identical bundle.
frontend:
name: Build web UI
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: actions/setup-node@v7
with:
node-version: "22"
cache: npm
cache-dependency-path: frontend/package-lock.json
- run: npm --prefix frontend ci
- run: npm --prefix frontend run build
# build.rs substitutes a "Frontend not built" placeholder page when the
# bundle is missing and only emits a cargo warning, so a broken UI would
# otherwise sail through into a published release. Fail loudly instead.
- name: Verify the real UI was built
run: |
if [ ! -f frontend/dist/index.html ]; then
echo "::error::frontend/dist/index.html missing after the vite build"
exit 1
fi
if grep -q 'Frontend not built' frontend/dist/index.html; then
echo "::error::frontend/dist/index.html is the build.rs placeholder"
exit 1
fi
- uses: actions/upload-artifact@v7
with:
name: frontend-dist
path: frontend/dist
retention-days: 1
if-no-files-found: error
build:
name: ${{ matrix.target }}
needs: frontend
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
include:
# Statically linked against musl so the binary runs on any x86_64
# Linux regardless of the host glibc version.
- os: ubuntu-latest
target: x86_64-unknown-linux-musl
bin: red-clippy
- os: windows-latest
target: x86_64-pc-windows-msvc
bin: red-clippy.exe
steps:
- uses: actions/checkout@v7
- uses: actions/download-artifact@v8
with:
name: frontend-dist
path: frontend/dist
- name: Confirm the bundle survived the transfer
shell: bash
run: |
test -f frontend/dist/index.html
! grep -q 'Frontend not built' frontend/dist/index.html
# Refuse to publish a tag that disagrees with the crate version, which
# would otherwise produce v0.2.0 archives containing a 0.1.0 binary.
- name: Check tag matches Cargo.toml version
if: startsWith(github.ref, 'refs/tags/v')
shell: bash
run: |
crate="$(sed -n 's/^version = "\(.*\)"$/\1/p' Cargo.toml | head -1)"
tag="${GITHUB_REF_NAME#v}"
if [ "$crate" != "$tag" ]; then
echo "::error::tag $GITHUB_REF_NAME does not match Cargo.toml version $crate"
exit 1
fi
- uses: dtolnay/rust-toolchain@stable
with:
targets: ${{ matrix.target }}
- uses: Swatinem/rust-cache@v2
with:
key: ${{ matrix.target }}
# SQLite is compiled from C and linked statically, so the musl target
# needs a musl C compiler as well as the Rust std for that target.
- name: Install musl toolchain
if: matrix.target == 'x86_64-unknown-linux-musl'
run: |
sudo apt-get update
sudo apt-get install -y --no-install-recommends musl-tools
# reqwest's TLS pulls aws-lc-sys, whose x86_64 Windows build assembles
# with NASM and hard-fails ("NASM command not found") when it is absent.
# Installed explicitly rather than trusted to the runner image, which
# carries no such guarantee across image updates. choco ships with the
# runner, so this adds no third-party action to a publishing workflow.
- name: Install NASM
if: matrix.target == 'x86_64-pc-windows-msvc'
shell: pwsh
run: |
choco install nasm -y --no-progress
"C:\Program Files\NASM" | Out-File -FilePath $env:GITHUB_PATH -Append -Encoding utf8
- name: Confirm NASM is on PATH
if: matrix.target == 'x86_64-pc-windows-msvc'
shell: pwsh
run: nasm -version
- name: Build
shell: bash
env:
CC_x86_64_unknown_linux_musl: musl-gcc
CARGO_TARGET_X86_64_UNKNOWN_LINUX_MUSL_LINKER: musl-gcc
run: cargo build --release --locked --target ${{ matrix.target }}
- name: Smoke test the binary
shell: bash
run: ./target/${{ matrix.target }}/release/${{ matrix.bin }} --version
- name: Package
shell: bash
run: |
version="$(sed -n 's/^version = "\(.*\)"$/\1/p' Cargo.toml | head -1)"
name="red-clippy-v${version}-${{ matrix.target }}"
mkdir -p "dist/$name"
cp "target/${{ matrix.target }}/release/${{ matrix.bin }}" "dist/$name/"
cp README.md LICENSE red-clippy.toml.example "dist/$name/"
cd dist
if [ "${{ runner.os }}" = "Windows" ]; then
7z a -tzip "$name.zip" "$name" > /dev/null
else
tar czf "$name.tar.gz" "$name"
fi
rm -rf "$name"
- uses: actions/upload-artifact@v7
with:
name: release-${{ matrix.target }}
path: dist/*
if-no-files-found: error
release:
name: Publish release
needs: build
if: startsWith(github.ref, 'refs/tags/v')
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/download-artifact@v8
with:
pattern: release-*
path: dist
merge-multiple: true
- name: Generate checksums
run: |
cd dist
find . -maxdepth 1 -type f ! -name SHA256SUMS -printf '%P\n' \
| sort | xargs -r sha256sum > SHA256SUMS
cat SHA256SUMS
- uses: softprops/action-gh-release@v3
with:
files: dist/*
generate_release_notes: true
fail_on_unmatched_files: true