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
name: CI
on:
push:
branches:
pull_request:
branches:
# Dependency drift happens with no commit of ours to trigger it, so the
# newest-dependencies job needs a clock as well as a push.
schedule:
- cron: '0 7 * * 1'
env:
CARGO_TERM_COLOR: always
jobs:
check:
name: Compile & Lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Rust Toolchain
uses: dtolnay/rust-toolchain@stable
with:
components: clippy, rustfmt
- name: Cargo Cache
uses: actions/cache@v4
with:
path: |
~/.cargo/bin/
~/.cargo/registry/index/
~/.cargo/registry/cache/
~/.cargo/git/db/
target/
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
- name: Check Formatting
run: cargo fmt --check
- name: Compile
run: cargo check --all-targets
- name: Run Linter (Clippy)
run: cargo clippy --all-targets -- -D warnings
test:
name: Test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Rust Toolchain
uses: dtolnay/rust-toolchain@stable
- name: Cargo Cache
uses: actions/cache@v4
with:
path: |
~/.cargo/bin/
~/.cargo/registry/index/
~/.cargo/registry/cache/
~/.cargo/git/db/
target/
key: ${{ runner.os }}-cargo-test-${{ hashFiles('**/Cargo.lock') }}
# Covers unit tests, the examples, and the doc examples in lib.rs.
- name: Run Tests
run: cargo test --all-targets
- name: Run Doc Tests
run: cargo test --doc
msrv:
name: Minimum Supported Rust Version
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
# Keep in sync with `rust-version` in Cargo.toml.
- name: Install Rust 1.86
uses: dtolnay/rust-toolchain@1.86
- name: Compile on MSRV
run: cargo check --all-targets
latest-deps:
name: Newest Dependencies
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Rust Toolchain
uses: dtolnay/rust-toolchain@stable
# The committed lockfile is what every other job builds against, so a
# dependency that has silently stopped resolving to its newest version is
# invisible to them. That is not a hypothetical: 0.5.0 shipped asking
# reqwest for a feature 0.13.4 had removed, cargo backtracked to 0.13.1
# without a word, and the break surfaced only in a downstream consumer.
- name: Check for held-back direct dependencies
run: .github/scripts/check-dependency-drift.sh
# And then actually build against the newest of everything, which catches
# the ordinary case the check above cannot: an upstream release that
# resolves fine but no longer compiles against this code.
- name: Update to newest compatible versions
run: cargo update
- name: Compile
run: cargo check --all-targets
- name: Run Tests
run: cargo test --all-targets
- name: Run Doc Tests
run: cargo test --doc
minimal-versions:
name: Minimum Dependency Versions
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
# -Z direct-minimal-versions is nightly-only. It is used here purely as a
# resolver, to build the lockfile; the build and tests then run on stable.
- name: Install Rust Toolchains
uses: dtolnay/rust-toolchain@stable
- name: Install Nightly (resolver only)
uses: dtolnay/rust-toolchain@nightly
# Every version floor in Cargo.toml is a promise that the crate works with
# that version. Nothing else in CI tests it: the lockfile pins the newest
# of everything, so an understated floor is invisible until a consumer
# with an older tree fails to build. This resolves each direct dependency
# down to its declared minimum and checks the promise is real.
- name: Resolve to minimum declared versions
run: cargo +nightly update -Z direct-minimal-versions
- name: Compile
run: cargo check --all-targets
- name: Run Tests
run: cargo test --all-targets
audit:
name: Security Audit
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: rustsec/audit-check@v2
with:
token: ${{ secrets.GITHUB_TOKEN }}
docs:
name: Docs
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Rust Toolchain
uses: dtolnay/rust-toolchain@stable
# Catches broken intra-doc links before they reach docs.rs.
- name: Build Documentation
run: cargo doc --no-deps
env:
RUSTDOCFLAGS: -D warnings