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
name: Release
on:
push:
tags:
permissions:
contents: write
jobs:
build:
name: Build ${{ matrix.target }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
include:
- target: aarch64-apple-darwin
os: macos-latest
archive: aiseo-aarch64-apple-darwin.tar.gz
- target: x86_64-apple-darwin
os: macos-latest
archive: aiseo-x86_64-apple-darwin.tar.gz
- target: x86_64-unknown-linux-gnu
os: ubuntu-latest
archive: aiseo-x86_64-unknown-linux-gnu.tar.gz
- target: aarch64-unknown-linux-gnu
os: ubuntu-latest
archive: aiseo-aarch64-unknown-linux-gnu.tar.gz
cross: true
steps:
- uses: actions/checkout@v4
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
with:
targets: ${{ matrix.target }}
- name: Install cross
if: matrix.cross
run: cargo install cross --locked
- uses: Swatinem/rust-cache@v2
with:
key: ${{ matrix.target }}
- name: Build (native)
if: '!matrix.cross'
run: cargo build --release --locked --target ${{ matrix.target }}
- name: Build (cross)
if: matrix.cross
run: cross build --release --locked --target ${{ matrix.target }}
# Run the test suite on every release target. Catches platform
# regressions that ship silently otherwise (e.g. the v0.6→v0.7
# aarch64-linux openssl-sys break). `cross test` runs the test
# binary under qemu user-mode emulation — slow but correct.
- name: Test (native)
if: '!matrix.cross'
run: cargo test --release --locked --target ${{ matrix.target }}
- name: Test (cross)
if: matrix.cross
run: cross test --release --locked --target ${{ matrix.target }}
- name: Package
run: |
cd target/${{ matrix.target }}/release
tar -czf ../../../${{ matrix.archive }} aiseo
cd ../../..
shasum -a 256 ${{ matrix.archive }} > ${{ matrix.archive }}.sha256
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.archive }}
path: |
${{ matrix.archive }}
${{ matrix.archive }}.sha256
release:
needs: build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Download artifacts
uses: actions/download-artifact@v4
with:
path: dist
merge-multiple: true
- name: Create release
uses: softprops/action-gh-release@v2
with:
files: |
dist/*.tar.gz
dist/*.sha256
generate_release_notes: true
fail_on_unmatched_files: true
publish-crate:
name: Publish to crates.io
needs: release
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
# Idempotent: if v0.x.y is already on crates.io (e.g. someone
# ran `cargo publish` locally before the tag landed), cargo
# publish errors with "already exists". Swallow that exact
# case so re-runs are safe; surface anything else.
- name: Publish
env:
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
run: |
set -o pipefail
if cargo publish --locked 2>&1 | tee /tmp/publish.log; then
echo "published"
else
if grep -q "already exists on crates.io" /tmp/publish.log; then
echo "version already on crates.io — no-op"
exit 0
fi
exit 1
fi