1
- # This is largely adapted from past and recent versions of the ripgrep release workflow.
1
+ # Much of this workflow is adapted from the ripgrep release workflow.
2
2
# https://github.com/BurntSushi/ripgrep/blob/master/.github/workflows/release.yml
3
3
4
4
name : release
12
12
tags :
13
13
- ' v*'
14
14
15
- env :
16
- RUST_BACKTRACE : 1
17
- CARGO_TERM_COLOR : always
18
- CLICOLOR : 1
19
-
20
15
defaults :
21
16
run :
22
17
shell : bash
23
18
24
19
jobs :
25
- # The create-release job runs purely to initialize the GitHub release itself,
26
- # and names the release after the version tag that was pushed. It's separate
27
- # from building the release so that we only create the release once.
20
+ # Create a draft release, initially with no binary assets attached.
28
21
create-release :
29
- name : create-release
30
22
runs-on : ubuntu-latest
23
+
31
24
# env:
32
25
# # Set to force version number, e.g., when no tag exists.
33
26
# VERSION: TEST-0.0.0
27
+
34
28
steps :
35
- - name : Create artifacts directory
36
- run : mkdir artifacts
29
+ - name : Checkout repository
30
+ uses : actions/checkout@v4
37
31
38
32
- name : Get the release version from the tag
39
33
if : env.VERSION == ''
40
- run : echo 'VERSION=${{ github.ref_name }}' >> "$GITHUB_ENV"
34
+ run : echo "VERSION=$REF_NAME" >> "$GITHUB_ENV"
35
+ env :
36
+ REF_NAME : ${{ github.ref_name }}
41
37
42
- - name : Create GitHub release
43
- id : release
44
- uses : ncipollo/release-action@v1
45
- with :
46
- tag : ${{ env.VERSION }}
47
- name : ${{ env.VERSION }}
48
- allowUpdates : true
49
- omitBody : true
50
- omitPrereleaseDuringUpdate : true
51
- token : ${{ secrets.GITHUB_TOKEN }}
38
+ - name : Validate version against Cargo.toml
39
+ run : |
40
+ manifest_version="$(yq -r .package.version Cargo.toml)"
41
+ echo "version to name the release: $VERSION"
42
+ echo "version Cargo.toml suggests: v$manifest_version"
52
43
53
- - name : Save release upload URL to artifact
54
- run : echo '${{ steps.release.outputs.upload_url }}' > artifacts/release-upload-url
44
+ case "$VERSION" in
45
+ "v$manifest_version" )
46
+ echo 'OK: Release name/version agrees with Cargo.toml version.'
47
+ ;;
48
+ TEST-* | *-DO-NOT-USE )
49
+ echo 'OK: Release name/version is strange but marked as such.'
50
+ ;;
51
+ "$manifest_version" )
52
+ echo 'STOPPING: Release name/version is missing the leading "v".'
53
+ exit 1
54
+ ;;
55
+ * )
56
+ echo 'STOPPING: Release name/version and Cargo.toml version do not match.'
57
+ echo 'STOPPING: Usually this means either a wrong tag name or wrong version in Cargo.toml.'
58
+ echo 'STOPPING: If intended, prepend `TEST-` or append `-DO-NOT-USE` to the release name.'
59
+ exit 1
60
+ ;;
61
+ esac
55
62
56
- - name : Save version number to artifact
57
- run : echo "$VERSION" > artifacts/release-version
63
+ - name : Create GitHub release
64
+ run : gh release create "$VERSION" --title="$VERSION" --draft
65
+ env :
66
+ GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
58
67
59
- - name : Upload artifacts
60
- uses : actions/upload-artifact@v4
61
- with :
62
- name : artifacts
63
- path : artifacts
68
+ outputs :
69
+ version : ${{ env.VERSION }}
64
70
71
+ # Build for a particular feature and target, and attach an archive for it.
65
72
build-release :
66
- name : build-release
67
-
68
73
needs : [ create-release ]
69
74
70
75
strategy :
78
83
- x86_64-pc-windows-gnu
79
84
- i686-pc-windows-msvc
80
85
- aarch64-pc-windows-msvc
81
- feature :
82
- - small
83
- - lean
84
- - max
85
- - max-pure
86
+ # When changing these features, make the same change in build-macos-universal2-release.
87
+ feature : [ small, lean, max, max-pure ]
86
88
include :
87
89
- target : x86_64-unknown-linux-musl
88
90
os : ubuntu-latest
@@ -128,21 +130,28 @@ jobs:
128
130
runs-on : ${{ matrix.os }}
129
131
130
132
env :
131
- CARGO : cargo # On Linux, this will be changed to `cross` later.
133
+ RUST_BACKTRACE : ' 1' # Emit backtraces on panics.
134
+ CARGO_TERM_COLOR : always
135
+ CLICOLOR : ' 1'
136
+ CARGO : cargo # On Linux, this will be changed to `cross` in a later step.
137
+ FEATURE : ${{ matrix.feature }}
138
+ VERSION : ${{ needs.create-release.outputs.version }}
139
+ TARGET : ${{ matrix.target }}
132
140
TARGET_FLAGS : --target=${{ matrix.target }}
133
- TARGET_DIR : ./target/${{ matrix.target }}
134
- RUST_BACKTRACE : 1 # Emit backtraces on panics.
141
+ TARGET_DIR : target/${{ matrix.target }}
135
142
136
143
steps :
137
144
- name : Checkout repository
138
145
uses : actions/checkout@v4
139
146
140
147
- name : Install packages (Ubuntu)
141
- # Because openssl doesn't work on musl by default, we resort to max-pure. And that won't need any dependency, so we can skip this.continue-on-error
148
+ # Because openssl doesn't work on musl by default, we resort to max-pure.
149
+ # And that won't need any dependency, so we can skip this or use `continue-on-error`.
142
150
# Once we want to support better zlib performance, we might have to re-add it.
143
151
if : matrix.os == 'ubuntu-latest-disabled'
144
152
run : |
145
- sudo apt-get update && sudo apt-get install -y --no-install-recommends xz-utils liblz4-tool musl-tools
153
+ sudo apt-get update
154
+ sudo apt-get install -y --no-install-recommends xz-utils liblz4-tool musl-tools
146
155
147
156
- name : Install Rust
148
157
uses : dtolnay/rust-toolchain@master
@@ -162,20 +171,9 @@ jobs:
162
171
echo "target flag is: $TARGET_FLAGS"
163
172
echo "target dir is: $TARGET_DIR"
164
173
165
- - name : Get release download URL
166
- uses : actions/download-artifact@v4
167
- with :
168
- name : artifacts
169
- path : artifacts
170
-
171
- - name : Set release upload URL and release version
172
- run : |
173
- echo "UPLOAD_URL=$(< artifacts/release-upload-url)" >> "$GITHUB_ENV"
174
- echo "VERSION=$(< artifacts/release-version)" >> "$GITHUB_ENV"
175
-
176
174
- name : Build release binary
177
175
run : |
178
- "$CARGO" build --verbose --release "$TARGET_FLAGS" --no-default-features --features ${{ matrix.feature }}
176
+ "$CARGO" build --verbose --release "$TARGET_FLAGS" --no-default-features --features "$FEATURE"
179
177
180
178
- name : Strip release binary (x86-64 Linux, and all macOS)
181
179
if : matrix.target == 'x86_64-unknown-linux-musl' || matrix.os == 'macos-latest'
@@ -191,31 +189,164 @@ jobs:
191
189
/target/arm-unknown-linux-gnueabihf/release/ein \
192
190
/target/arm-unknown-linux-gnueabihf/release/gix
193
191
194
- - name : Build archive
192
+ - name : Determine archive basename
193
+ run : echo "ARCHIVE=gitoxide-$FEATURE-$VERSION-$TARGET" >> "$GITHUB_ENV"
194
+
195
+ - name : Pre-populate directory for archive
195
196
run : |
196
- staging='gitoxide-${{ matrix.feature }}-${{ env.VERSION }}-${{ matrix.target }}'
197
- mkdir -p -- "$staging "
197
+ mkdir -- "$ARCHIVE"
198
+ cp {README.md,LICENSE-*,CHANGELOG.md} "$ARCHIVE/ "
198
199
199
- cp {README.md,LICENSE-*,CHANGELOG.md} "$staging/"
200
+ - name : Build archive (Windows)
201
+ if : matrix.os == 'windows-latest'
202
+ run : |
203
+ file -- "$TARGET_DIR"/release/{ein,gix}.exe
204
+ cp -- "$TARGET_DIR"/release/{ein,gix}.exe "$ARCHIVE/"
205
+ 7z a "$ARCHIVE.zip" "$ARCHIVE"
206
+ /usr/bin/core_perl/shasum --algorithm=256 --binary "$ARCHIVE.zip" > "$ARCHIVE.zip.sha256"
207
+ echo "ASSET=$ARCHIVE.zip" >> "$GITHUB_ENV"
208
+ echo "ASSET_SUM=$ARCHIVE.zip.sha256" >> "$GITHUB_ENV"
200
209
201
- if [ '${{ matrix.os }}' = 'windows-latest' ]; then
202
- file -- "$TARGET_DIR"/release/{ein,gix}.exe
203
- cp -- "$TARGET_DIR"/release/{ein,gix}.exe "$staging/"
204
- 7z a "$staging.zip" "$staging"
205
- echo "ASSET=$staging.zip" >> "$GITHUB_ENV"
206
- else
207
- file -- "$TARGET_DIR"/release/{ein,gix}
208
- cp -- "$TARGET_DIR"/release/{ein,gix} "$staging/"
209
- tar czf "$staging.tar.gz" "$staging"
210
- echo "ASSET=$staging.tar.gz" >> "$GITHUB_ENV"
211
- fi
210
+ - name : Build archive (Unix)
211
+ if : matrix.os != 'windows-latest'
212
+ run : |
213
+ file -- "$TARGET_DIR"/release/{ein,gix}
214
+ cp -- "$TARGET_DIR"/release/{ein,gix} "$ARCHIVE/"
215
+ tar czf "$ARCHIVE.tar.gz" "$ARCHIVE"
216
+ shasum --algorithm=256 --binary "$ARCHIVE.tar.gz" > "$ARCHIVE.tar.gz.sha256"
217
+ echo "ASSET=$ARCHIVE.tar.gz" >> "$GITHUB_ENV"
218
+ echo "ASSET_SUM=$ARCHIVE.tar.gz.sha256" >> "$GITHUB_ENV"
212
219
213
220
- name : Upload release archive
214
- uses : actions/upload-release-asset@v1.0.2
221
+ run : gh release upload "$VERSION" "$ASSET" "$ASSET_SUM"
222
+ env :
223
+ GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
224
+
225
+ # Add a macOS universal binary archive for a feature using its built aarch64 and x86_64 assets.
226
+ build-macos-universal2-release :
227
+ runs-on : macos-latest
228
+
229
+ needs : [ create-release, build-release ]
230
+
231
+ strategy :
232
+ matrix :
233
+ # These features need to be exactly the same as the features in build-release.
234
+ feature : [ small, lean, max, max-pure ]
235
+
236
+ env :
237
+ BASH_ENV : ./helpers.sh
238
+ REPOSITORY : ${{ github.repository }}
239
+ FEATURE : ${{ matrix.feature }}
240
+ VERSION : ${{ needs.create-release.outputs.version }}
241
+
242
+ steps :
243
+ - name : Define helper function
244
+ run : |
245
+ name() { echo "gitoxide-$FEATURE-$VERSION-$1-apple-darwin"; }
246
+ declare -f name >> "$BASH_ENV"
247
+
248
+ - name : Obtain single-architecture releases
249
+ run : |
250
+ gh release --repo="$REPOSITORY" download "$VERSION" \
251
+ --pattern="$(name aarch64).tar.gz" --pattern="$(name aarch64).tar.gz.sha256" \
252
+ --pattern="$(name x86_64).tar.gz" --pattern="$(name x86_64).tar.gz.sha256"
253
+ env :
254
+ GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
255
+
256
+ - name : Unpack single-architecture releases
257
+ run : |
258
+ shasum --check "$(name aarch64).tar.gz.sha256" "$(name x86_64).tar.gz.sha256"
259
+ tar xf "$(name aarch64).tar.gz"
260
+ tar xf "$(name x86_64).tar.gz"
261
+
262
+ - name : Determine archive basename
263
+ run : echo "ARCHIVE=$(name universal)" >> "$GITHUB_ENV"
264
+
265
+ - name : Pre-populate directory for archive
266
+ run : |
267
+ cp -R -- "$(name aarch64)" "$ARCHIVE"
268
+ rm -- "$ARCHIVE"/{ein,gix}
269
+
270
+ - name : Create Universal 2 binaries
271
+ run : |
272
+ for bin in ein gix; do
273
+ lipo -create "$(name aarch64)/$bin" "$(name x86_64)/$bin" -output "$ARCHIVE/$bin"
274
+ file -- "$ARCHIVE/$bin"
275
+ done
276
+
277
+ - name : Build archive
278
+ run : |
279
+ tar czf "$ARCHIVE.tar.gz" "$ARCHIVE"
280
+ shasum --algorithm=256 --binary "$ARCHIVE.tar.gz" > "$ARCHIVE.tar.gz.sha256"
281
+ echo "ASSET=$ARCHIVE.tar.gz" >> "$GITHUB_ENV"
282
+ echo "ASSET_SUM=$ARCHIVE.tar.gz.sha256" >> "$GITHUB_ENV"
283
+
284
+ - name : Upload release archive
285
+ run : gh release --repo="$REPOSITORY" upload "$VERSION" "$ASSET" "$ASSET_SUM"
286
+ env :
287
+ GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
288
+
289
+ # Check for some problems, consolidate checksum files into one, and mark the release non-draft.
290
+ publish-release :
291
+ runs-on : ubuntu-latest
292
+
293
+ needs : [ create-release, build-release, build-macos-universal2-release ]
294
+
295
+ env :
296
+ REPOSITORY : ${{ github.repository }}
297
+ VERSION : ${{ needs.create-release.outputs.version }}
298
+
299
+ steps :
300
+ - name : Discover assets
301
+ run : |
302
+ gh release --repo="$REPOSITORY" view "$VERSION" --json assets --jq '.assets.[].name' > assets.txt
303
+ env :
304
+ GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
305
+
306
+ - name : Show all individual asset names
307
+ run : cat assets.txt
308
+
309
+ # The `features` array is repeated because GHA doen't support YAML anchors.
310
+ # We will check that the macOS `universal` features match the others exactly.
311
+ # In the future this and the next step may be removed, or expanded to do more validation.
312
+ - name : Extract macOS asset names by architecture
313
+ run : |
314
+ for arch in aarch64 x86_64 universal; do
315
+ grep -Fw "$arch-apple-darwin" assets.txt | sort | tee -- "$arch.txt"
316
+ done
317
+
318
+ - name : Check macOS archive features
319
+ run : |
320
+ mask() { sed -r 's/\w+-apple-darwin/<arch>-apple-darwin/' -- "$1.txt"; }
321
+ diff -- <(mask aarch64) <(mask universal)
322
+ diff -- <(mask x86_64) <(mask universal)
323
+
324
+ - name : Clean up local temporary macOS asset list files
325
+ run : rm {assets,aarch64,x86_64,universal}.txt
326
+
327
+ - name : Retrieve all individual checksums
328
+ run : gh release --repo="$REPOSITORY" download "$VERSION" --pattern='gitoxide-*.sha256'
329
+ env :
330
+ GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
331
+
332
+ - name : Concatenate checksums into one file
333
+ run : cat gitoxide-*.sha256 > hashes.sha256
334
+
335
+ - name : Upload the combined checksum file
336
+ run : gh release --repo="$REPOSITORY" upload "$VERSION" hashes.sha256
337
+ env :
338
+ GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
339
+
340
+ # If any step of any job fails before this, the draft still has the individual checksum files.
341
+ - name : Remove the individual checksum file assets
342
+ run : |
343
+ for sumfile in gitoxide-*.sha256; do
344
+ gh release --repo="$REPOSITORY" delete-asset "$VERSION" "$sumfile" --yes
345
+ done
346
+ env :
347
+ GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
348
+
349
+ - name : Publish the release
350
+ run : gh release --repo="$REPOSITORY" edit "$VERSION" --draft=false
215
351
env :
216
352
GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
217
- with :
218
- upload_url : ${{ env.UPLOAD_URL }}
219
- asset_path : ${{ env.ASSET }}
220
- asset_name : ${{ env.ASSET }}
221
- asset_content_type : application/octet-stream
0 commit comments