-
Notifications
You must be signed in to change notification settings - Fork 0
300 lines (261 loc) · 9.64 KB
/
ci.yml
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
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
name: CI
on:
push:
branches: ["main"]
env:
CARGO_TERM_COLOR: always
RUSTFLAGS: -Dwarnings
RUST_BACKTRACE: 1
# Change to specific Rust release to pin
rust_stable: stable
rust_nightly: nightly-2024-12-02
permissions:
contents: read
defaults:
run:
shell: bash
jobs:
define-matrix:
needs:
- tests
- nextest_with_coverage
- asan
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Discover benches
id: discover
run: |
set -euo pipefail
# We'll find all sub-crates, then find *.rs files under each sub-crate's benches/ directory.
# We assume structure like: implementations/SUBCRATE/benches/BENCH.rs
# Adjust globbing if needed.
# Find all sub crates under implementations
SUBCRATES=$(find implementations -mindepth 1 -maxdepth 1 -type d -printf '%f\n' || true)
# Convert the list of subcrates to a JSON array
SUBCRATES_JSON=$(echo "$SUBCRATES" | jq -R . | jq -s . | jq -c .)
# Output the JSON array to GitHub Actions output
echo "subcrates=$SUBCRATES_JSON" >> "$GITHUB_OUTPUT"
SUBCRATES_FOR_BENCHES=$(echo "$SUBCRATES" || true)
# Build a JSON array of objects
# Each object: { "subcrate": "xxx", "bench": "yyy" }
# For each subcrate, we look under benches/ for *.rs files
JSON='['
first=true
for crate in $SUBCRATES_FOR_BENCHES; do
BENCH_FILES=$(find "implementations/$crate/benches" -maxdepth 1 -name '*.rs' -printf '%f\n' 2>/dev/null || true)
for bf in $BENCH_FILES; do
bench_name="${bf%.rs}" # remove .rs extension
if [ "$first" = true ]; then
first=false
else
JSON="$JSON,"
fi
JSON="$JSON{\"subcrate\":\"$crate\",\"bench\":\"$bench_name\"}"
done
done
JSON="$JSON]"
echo "benches=$JSON" >> "$GITHUB_OUTPUT"
outputs:
benches: ${{ steps.discover.outputs.benches }}
subcrates: ${{ steps.discover.outputs.subcrates }}
bench:
needs: define-matrix
runs-on: ubuntu-latest
strategy:
# Parse the JSON output from define-matrix job
matrix:
combo: ${{ fromJSON(needs.define-matrix.outputs.benches) }}
steps:
- uses: actions/checkout@v4
# Nightly Rust is used for cargo llvm-cov --doc below.
- name: Install Rust ${{ env.rust_nightly }}
uses: dtolnay/rust-toolchain@stable
with:
toolchain: ${{ env.rust_nightly }}
components: llvm-tools-preview
- uses: Swatinem/rust-cache@v2
- name: Install Dependencies
run: |
sudo apt update && sudo apt install -y gnuplot jq
- name: Build and Run Benchmarks
# Run the benchmark for the specified subcrate and bench target
# each sub crate adjust its settings by Cargo.toml
run: |
BENCH_METRICS_PATH=/tmp/${{ matrix.combo.subcrate }}/${{ matrix.combo.bench }}.json
mkdir -p "$(dirname "$BENCH_METRICS_PATH")"
echo "BENCH_METRICS_PATH=$BENCH_METRICS_PATH" >> $GITHUB_ENV
# Use GNU time on Ubuntu, max_rss in KB, cpu_usage in percent
/usr/bin/time -f '{"max_rss_in_kb": %M, "cpu_percentage": "%P", "wall_clock_in_seconds": %e}' -o $BENCH_METRICS_PATH cargo bench -p ${{ matrix.combo.subcrate }} --bench ${{ matrix.combo.bench }}
# Validate JSON using jq
jq empty $BENCH_METRICS_PATH || (echo "Invalid JSON format in $BENCH_METRICS_PATH"; exit 1)
- name: Install cargo-llvm-cov
uses: taiki-e/install-action@v2
with:
tool: cargo-llvm-cov
- name: Generate metrics.json
run: |
envsubst < .github/templates/metrics_template.json > metrics.json
jq empty metrics.json || (echo "Invalid JSON format in metrics.json"; exit 1)
cat metrics.json
env:
SUB_CRATE: ${{ matrix.combo.subcrate }}
BENCH: ${{ matrix.combo.bench }}
BENCH_METRICS_PATH: ${{ env.BENCH_METRICS_PATH }}
- name:
Send Benchmark Data to InfluxDB, along with collecting coverage data
run: |
cargo llvm-cov run --release -p bench_util --lcov --output-path lcov_bench_util.info -- update-db --metrics-config="metrics.json" --sub-crate=${{ matrix.combo.subcrate }} --bench=${{ matrix.combo.bench }}
env:
INFLUXDB_URL: ${{ secrets.INFLUXDB_URL }}
INFLUXDB_TOKEN: ${{ secrets.INFLUXDB_TOKEN }}
INFLUXDB_ORG: ${{ secrets.INFLUXDB_ORG }}
INFLUXDB_BUCKET: ${{ secrets.INFLUXDB_BUCKET }}
- name: Upload coverage data to codecov
uses: codecov/codecov-action@v5
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
with:
files: lcov_bench_util.info
update-dashboard-time-range:
needs: bench
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Rust ${{ env.rust_nightly }}
uses: dtolnay/rust-toolchain@stable
with:
toolchain: ${{ env.rust_nightly }}
components: llvm-tools-preview
- uses: Swatinem/rust-cache@v2
- name: Install cargo-llvm-cov
uses: taiki-e/install-action@v2
with:
tool: cargo-llvm-cov
- name:
Adjust Grafana dashboard's time range, along with collecting coverage
data
run: |
cargo llvm-cov run --release -p bench_util --lcov --output-path lcov_bench_util.info -- update-dashboard-time-range
env:
INFLUXDB_URL: ${{ secrets.INFLUXDB_URL }}
INFLUXDB_TOKEN: ${{ secrets.INFLUXDB_TOKEN }}
INFLUXDB_ORG: ${{ secrets.INFLUXDB_ORG }}
INFLUXDB_BUCKET: ${{ secrets.INFLUXDB_BUCKET }}
GRAFANA_URL: ${{ secrets.GRAFANA_URL }}
GRAFANA_SERVICE_ACCOUNT_TOKEN:
${{ secrets.GRAFANA_SERVICE_ACCOUNT_TOKEN }}
GRAFANA_DASHBOARD_UID: ${{ secrets.GRAFANA_DASHBOARD_UID }}
- name: Upload coverage data to codecov
uses: codecov/codecov-action@v5
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
with:
files: lcov_bench_util.info
miri:
name: miri
needs: define-matrix
runs-on: ubuntu-latest
strategy:
matrix:
subcrate: ${{ fromJSON(needs.define-matrix.outputs.subcrates) }}
steps:
- uses: actions/checkout@v4
- name: Install Rust ${{ env.rust_nightly }}
uses: dtolnay/rust-toolchain@stable
with:
toolchain: ${{ env.rust_nightly }}
components: miri
- name: Install cargo-nextest
uses: taiki-e/install-action@v2
with:
tool: cargo-nextest
- uses: Swatinem/rust-cache@v2
- name: miri
run: |
echo ${{ matrix.subcrate }}
cargo miri nextest run -p ${{ matrix.subcrate }} --lib --tests --no-fail-fast
env:
MIRIFLAGS:
-Zmiri-disable-isolation -Zmiri-strict-provenance
-Zmiri-retag-fields
asan:
name: asan
needs: basics
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install llvm
# Required to resolve symbols in sanitizer output
run: sudo apt-get install -y llvm
- name: Install Rust ${{ env.rust_nightly }}
uses: dtolnay/rust-toolchain@stable
with:
toolchain: ${{ env.rust_nightly }}
- uses: Swatinem/rust-cache@v2
- name: asan
run:
cargo test --workspace --all-features --target
x86_64-unknown-linux-gnu --tests -- --test-threads 1 --nocapture
env:
RUSTFLAGS: -Z sanitizer=address
# Ignore `trybuild` errors as they are irrelevant and flaky on nightly
TRYBUILD: overwrite
nextest_with_coverage:
name: nextest_with_coverage
needs:
- basics
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
# Nightly Rust is used for cargo llvm-cov --doc below.
- name: Install Rust ${{ env.rust_nightly }}
uses: dtolnay/rust-toolchain@stable
with:
toolchain: ${{ env.rust_nightly }}
components: llvm-tools-preview
- uses: Swatinem/rust-cache@v2
- name: Install cargo-nextest
uses: taiki-e/install-action@v2
with:
tool: cargo-nextest
- name: Install cargo-llvm-cov
uses: taiki-e/install-action@v2
with:
tool: cargo-llvm-cov
- name: Collect coverage data
# Generate separate reports for nextest and doctests, and combine them.
run: |
cargo llvm-cov --no-report nextest
cargo llvm-cov --no-report --doc
cargo llvm-cov report --doctests --lcov --output-path lcov.info
- name: Upload coverage data to codecov
uses: codecov/codecov-action@v5
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
with:
files: lcov.info
tests:
name: tests
runs-on: ubuntu-latest
needs:
- basics
steps:
- uses: actions/checkout@v4
- name: Install Rust ${{ env.rust_nightly }}
uses: dtolnay/rust-toolchain@stable
with:
toolchain: ${{ env.rust_nightly }}
- uses: Swatinem/rust-cache@v2
# Test **all** crates in the workspace with all features.
- name: test all --all-features
run: |
cargo test --workspace --all-features
# Basic actions that must pass before we kick off more expensive tests.
basics:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/basics
with:
rust_nightly: ${{ env.rust_nightly }}