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
name: CI
on:
push:
pull_request:
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
# `-D warnings` is deliberately *not* set here. The beta and nightly legs
# compile the crate against lints that do not exist on stable yet — an upstream
# deprecation landing in nightly would otherwise turn every open PR red for a
# reason no PR caused. Jobs on a pinned toolchain opt in individually.
env:
CARGO_TERM_COLOR: always
jobs:
fmt:
name: Rustfmt
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt
- run: cargo fmt --all --check
clippy:
name: Clippy
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
with:
components: clippy
- uses: Swatinem/rust-cache@v2
- run: cargo clippy --all-targets --locked -- -D warnings
test:
name: Test (${{ matrix.os }}, ${{ matrix.toolchain }})
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os:
toolchain:
include:
- os: ubuntu-latest
toolchain: beta
env:
# Stable is the leg that has to stay warning-clean; beta is here to give
# early warning of test failures, not to fail on a new lint.
RUSTFLAGS: ${{ matrix.toolchain == 'stable' && '-D warnings' || '' }}
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@master
with:
toolchain: ${{ matrix.toolchain }}
- uses: Swatinem/rust-cache@v2
# Examples are cfg-gated per platform (`unix_socket` and `steal` are Unix
# only), so building all targets on all three is what proves the gates are
# right rather than just absent.
- name: Build (all targets, incl. examples and benches)
run: cargo build --all-targets --locked
- name: Test
run: cargo test --all-targets --locked
- name: Doc tests
run: cargo test --doc --locked
msrv:
name: MSRV (1.88)
runs-on: ubuntu-latest
env:
RUSTFLAGS: -D warnings
steps:
- uses: actions/checkout@v4
# Not 1.85, which edition 2024 alone would allow: `compio` pulls in
# `thin-cell`, which uses `cell_update`, stable since 1.88. Keep this in
# step with `rust-version` in Cargo.toml and the note in README.md.
- uses: dtolnay/rust-toolchain@1.88.0
- uses: Swatinem/rust-cache@v2
# `--lib` only: dev-dependencies do not bind downstream users, and pinning
# the test-only deps to the MSRV would just make this job a maintenance tax.
- run: cargo build --lib --locked
docs:
name: Docs
runs-on: ubuntu-latest
env:
RUSTDOCFLAGS: -D warnings
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- run: cargo doc --no-deps --locked
miri:
name: Miri (undefined behaviour in the lock-free paths)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@nightly
with:
components: miri
- uses: Swatinem/rust-cache@v2
# The whole unit suite is runtime-free — the exchange tests poll by hand
# with `Waker::noop`, everything else is pure logic — so it runs under Miri
# unmodified. This is what keeps the CAS-based admission of decision 0006
# and the relaxed counters of decision 0008 honest; neither is provable by
# a test that only ever observes the happy interleaving.
- name: cargo miri test --lib
run: cargo miri test --lib --locked
env:
MIRIFLAGS: -Zmiri-strict-provenance -Zmiri-disable-isolation
fuzz:
name: Fuzz targets build and run briefly
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@nightly
- uses: Swatinem/rust-cache@v2
with:
workspaces: |
. -> target
fuzz -> fuzz/target
# A prebuilt binary; `cargo install cargo-fuzz` costs a couple of minutes
# of compile on every run and is not cached by rust-cache.
- uses: taiki-e/install-action@v2
with:
tool: cargo-fuzz
# A smoke run, not a campaign: enough to catch a target that stopped
# compiling or an invariant that now trips immediately. The real campaigns
# run nightly in soak.yml.
- name: pool_ops
run: cargo +nightly fuzz run pool_ops -- -runs=2000 -max_len=256
working-directory: fuzz
- name: reservoir_ops
run: cargo +nightly fuzz run reservoir_ops -- -runs=20000 -max_len=256
working-directory: fuzz
- name: Upload crash reproducer
if: failure()
uses: actions/upload-artifact@v4
with:
name: fuzz-artifacts
path: fuzz/artifacts/
if-no-files-found: ignore
minimal-features:
name: Library builds with its declared features only
runs-on: ubuntu-latest
env:
RUSTFLAGS: -D warnings
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
# `cargo build --lib` ignores dev-dependencies, so this catches any
# accidental reliance on compio features only enabled for tests.
- run: cargo build --lib --locked
links:
name: Doc cross-links resolve
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
# README and docs/ link into each other and into docs/decisions/ heavily;
# a renamed file is otherwise invisible until a reader hits the 404.
# `--offline` checks relative paths only, so this never fails on a flaky
# external host.
- uses: lycheeverse/lychee-action@v2
with:
args: --offline --no-progress --verbose "**/*.md"
fail: true