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
# Minimal CI: the same gates CONTRIBUTING.md asks for locally, plus the
# publish-readiness gates that only bite once the crate is on crates.io.
name: CI
on:
push:
branches:
pull_request:
# A force-push while the matrix is still running should not leave the
# old run burning minutes: the feature matrix alone is ~30 cargo
# invocations.
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
env:
CARGO_TERM_COLOR: always
jobs:
fmt:
name: rustfmt
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: cargo fmt --check
clippy:
name: clippy (-D warnings)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: rustup component add clippy
- uses: Swatinem/rust-cache@v2
- run: cargo clippy --all-features --all-targets -- -D warnings
test:
name: test (--all-features)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
# `--all-features` turns on `capture`, which builds cpal, which
# needs the ALSA headers. It has been working off whatever the
# runner image happened to ship; make the dependency explicit so a
# base-image change cannot break the build mysteriously.
- run: sudo apt-get update && sudo apt-get install -y libasound2-dev
- uses: Swatinem/rust-cache@v2
- run: cargo test --all-features
# rustdoc is a separate compiler with its own lint set, and
# `#![deny(missing_docs)]` plus intra-doc links mean it can break while
# `cargo build` and `cargo clippy` both stay green. Without this job the
# first sign of a broken doc build is a red badge on the published
# crate, because docs.rs builds on nightly and CI pins 1.96.1.
doc:
name: rustdoc (-D warnings)
runs-on: ubuntu-latest
env:
RUSTDOCFLAGS: -D warnings
steps:
- uses: actions/checkout@v4
- run: sudo apt-get update && sudo apt-get install -y libasound2-dev
- uses: Swatinem/rust-cache@v2
- run: cargo doc --all-features --no-deps
# Cargo.toml claims `rust-version = "1.96"`, but rust-toolchain.toml
# pins 1.96.1, so 1.96.0 -- the version the manifest actually promises
# -- is never exercised. RUSTUP_TOOLCHAIN overrides the toolchain file.
msrv:
name: MSRV 1.96.0
runs-on: ubuntu-latest
env:
RUSTUP_TOOLCHAIN: 1.96.0
steps:
- uses: actions/checkout@v4
- run: sudo apt-get update && sudo apt-get install -y libasound2-dev
- run: rustup toolchain install 1.96.0 --profile minimal
- uses: Swatinem/rust-cache@v2
- run: cargo check --all-features --all-targets
# docs.rs builds on current nightly and ignores rust-toolchain.toml.
# Nothing else in CI ever compiles this crate on a compiler newer than
# the pin, so a lint that tightens upstream lands as a surprise.
# Advisory only: a nightly regression must not block a PR.
stable:
name: stable + beta (advisory)
runs-on: ubuntu-latest
continue-on-error: true
strategy:
matrix:
channel:
env:
RUSTUP_TOOLCHAIN: ${{ matrix.channel }}
steps:
- uses: actions/checkout@v4
- run: sudo apt-get update && sudo apt-get install -y libasound2-dev
- run: rustup toolchain install ${{ matrix.channel }} --profile minimal
- uses: Swatinem/rust-cache@v2
- run: cargo check --all-features
# `cpal` and `serialport` are the platform-specific dependencies and
# have only ever been compiled against ALSA. A check-only job on the
# other two hosts is cheap next to finding out from a bug report.
cross-os:
name: check (${{ matrix.os }})
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os:
steps:
- uses: actions/checkout@v4
- uses: Swatinem/rust-cache@v2
- run: cargo check --all-features --all-targets
# `cargo publish` runs a verify build of the packaged tree, which is
# not the same tree as the working copy: `exclude` in Cargo.toml drops
# the corpora, and cargo auto-excludes the nested examples/esp32-riscv
# crate while still packaging tests/esp32_examples.rs. Find that out
# now rather than on release day.
package:
name: cargo publish --dry-run
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: sudo apt-get update && sudo apt-get install -y libasound2-dev
- uses: Swatinem/rust-cache@v2
- run: cargo publish --dry-run --all-features
# CONTRIBUTING.md: "no public function should be reachable by users and
# by nothing else". The recipe there found four unexercised functions
# by hand and then stopped being run. Pure text analysis, so this needs
# no toolchain and finishes in seconds.
public-api:
name: public API is exercised
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: scripts/check-public-api-exercised.sh
# docs/COVERAGE.md cites a few hundred tests by name and says they are
# checked mechanically. This is what does the checking; without it the
# claim decays into a few hundred hand-maintained rows that read as
# evidence after the tests behind them are renamed away.
coverage-citations:
name: docs/COVERAGE.md citations
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: sudo apt-get update && sudo apt-get install -y libasound2-dev
- uses: Swatinem/rust-cache@v2
- run: scripts/check-coverage-citations.sh
# #![forbid(unsafe_code)] covers this crate only. The CLI pulls cpal,
# serialport and the tokio stack, all of which are unsafe FFI, and the
# LICENSE story in third_party/ is documented but unenforced.
deny:
name: cargo-deny
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: EmbarkStudios/cargo-deny-action@v2
with:
command: check
embedded:
name: embedded no_std matrix
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
# Pass 1 of the script builds the LIBRARY for every no_std feature set
# on both bare-metal targets plus the detached ESP32 RISC-V examples
# sub-crate; only rustup target installation is needed. The `embedded`
# argument skips the host test-compilation pass, which the
# feature-matrix job below runs in parallel instead.
- run: rustup target add riscv32imac-unknown-none-elf riscv32imc-unknown-none-elf thumbv7em-none-eabihf
- uses: Swatinem/rust-cache@v2
- run: scripts/check-embedded.sh embedded
feature-matrix:
name: feature-set test compilation
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
# Pass 2 of the same script, on the HOST target: compiles (--no-run)
# the whole test suite once per feature set. Neither the `test` job
# above (--all-features only) nor the `embedded` job (library only,
# and bare-metal targets cannot host a test binary) ever compiles the
# tests for a PARTIAL feature set, which is how unresolved imports and
# alloc-dependent unit tests used to rot unnoticed. No rustup targets
# needed: this pass never leaves the host.
- uses: Swatinem/rust-cache@v2
- run: scripts/check-embedded.sh tests