44 push :
55 branches : [main]
66 pull_request :
7- branches : [main]
7+
8+ permissions : {}
89
910env :
1011 CARGO_TERM_COLOR : always
11- RUST_BACKTRACE : 1
12+ RUSTFLAGS : " -D warnings "
1213
13- permissions : {}
14+ concurrency :
15+ group : ${{ github.workflow }}-${{ github.ref }}
16+ cancel-in-progress : true
1417
1518jobs :
16- check :
17- name : Check
19+ detect-changes :
20+ name : Detect Changes
1821 runs-on : ubuntu-latest
19- permissions :
20- contents : read
22+ timeout-minutes : 2
23+ outputs :
24+ run-full-ci : ${{ steps.classify.outputs.run-full-ci }}
2125 steps :
22- - uses : actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # actions/checkout v6
23- - uses : dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # dtolnay/rust-toolchain stable
24- - uses : Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # Swatinem/rust-cache v2
25- - run : cargo check --all-targets --all-features
26+ - uses : actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
27+ - name : Filter changed paths
28+ uses : dorny/paths-filter@fbd0ab8f3e69293af611ebaee6363fc25e6d187d # v4.0.1
29+ id : filter
30+ with :
31+ filters : |
32+ code:
33+ - 'crates/**'
34+ - 'Cargo.toml'
35+ - 'Cargo.lock'
36+ workflows:
37+ - '.github/workflows/**'
38+ - '.cargo/**'
39+ - name : Classify changes
40+ id : classify
41+ run : |
42+ CODE="${{ steps.filter.outputs.code }}"
43+ WORKFLOWS="${{ steps.filter.outputs.workflows }}"
44+
45+ if [[ "$CODE" == "true" || "$WORKFLOWS" == "true" ]]; then
46+ echo "run-full-ci=true" >> "$GITHUB_OUTPUT"
47+ else
48+ echo "run-full-ci=false" >> "$GITHUB_OUTPUT"
49+ fi
2650
2751 fmt :
28- name : Format
52+ name : Lint (fmt)
53+ needs : detect-changes
54+ if : needs.detect-changes.outputs.run-full-ci == 'true'
2955 runs-on : ubuntu-latest
56+ timeout-minutes : 5
3057 permissions :
3158 contents : read
3259 steps :
33- - uses : actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # actions/checkout v6
34- - run : rustup toolchain install nightly --component rustfmt --allow-downgrade
35- - run : cargo +nightly fmt --all -- --check
60+ - uses : actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
61+ - uses : dtolnay/rust-toolchain@5b842231ba77f5c045dba54ac5560fed2db780e2 # nightly
62+ with :
63+ toolchain : nightly
64+ components : rustfmt
65+ - name : Check formatting
66+ run : cargo +nightly fmt --all -- --check
3667
3768 clippy :
38- name : Clippy
69+ name : Lint (clippy)
70+ needs : detect-changes
71+ if : needs.detect-changes.outputs.run-full-ci == 'true'
3972 runs-on : ubuntu-latest
73+ timeout-minutes : 10
4074 permissions :
4175 contents : read
4276 steps :
43- - uses : actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # actions/checkout v6
44- - uses : dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # dtolnay/rust-toolchain stable
77+ - uses : actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
78+ - uses : dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable
4579 with :
80+ toolchain : stable
4681 components : clippy
47- - uses : Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # Swatinem/rust-cache v2
48- - run : cargo clippy --all-targets --all-features -- -D warnings
82+ - uses : Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
83+ with :
84+ shared-key : " ci"
85+ - name : Clippy
86+ run : cargo clippy --all-targets --all-features --workspace -- -D warnings
4987
5088 test :
5189 name : Test
52- runs-on : ${{ matrix.os }}
90+ needs : [detect-changes, fmt, clippy]
91+ if : needs.detect-changes.outputs.run-full-ci == 'true'
92+ runs-on : ubuntu-latest
93+ timeout-minutes : 20
5394 permissions :
5495 contents : read
55- strategy :
56- fail-fast : false
57- matrix :
58- os : [ubuntu-latest, macos-latest, windows-latest]
59- rust : [stable]
60- include :
61- - os : ubuntu-latest
62- rust : beta
63- - os : ubuntu-latest
64- rust : " 1.88" # MSRV
96+ env :
97+ RUSTC_WRAPPER : sccache
98+ SCCACHE_GHA_ENABLED : " true"
6599 steps :
66- - uses : actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # actions/checkout v6
67- - uses : dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # dtolnay/rust-toolchain master
100+ - uses : actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
101+ - uses : dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable
68102 with :
69- toolchain : ${{ matrix.rust }}
70- - uses : Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # Swatinem/rust-cache v2
71- - uses : taiki-e/install-action@dee540ee3f3ff5c6a0665fed9996875d0ba04ca2 # taiki-e/install-action nextest
72- - run : cargo nextest run --all-features
103+ toolchain : stable
104+ - uses : Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
105+ with :
106+ cache-targets : " false"
107+ shared-key : " ci"
108+ - uses : mozilla-actions/sccache-action@7d986dd989559c6ecdb630a3fd2557667be217ad # v0.0.9
109+ - uses : taiki-e/install-action@dee540ee3f3ff5c6a0665fed9996875d0ba04ca2 # nextest
110+ - name : Run tests
111+ run : cargo nextest run --workspace --all-features --lib --bins
112+
113+ msrv :
114+ name : MSRV check (1.88)
115+ needs : detect-changes
116+ if : needs.detect-changes.outputs.run-full-ci == 'true'
117+ runs-on : ubuntu-latest
118+ timeout-minutes : 15
119+ permissions :
120+ contents : read
121+ steps :
122+ - uses : actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
123+ - uses : dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable
124+ with :
125+ toolchain : " 1.88"
126+ - uses : Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
127+ with :
128+ shared-key : " msrv"
129+ - name : cargo check (MSRV)
130+ run : cargo check --workspace --all-targets --all-features --locked
73131
74132 docs :
75- name : Documentation
133+ name : Rustdoc
134+ needs : detect-changes
135+ if : needs.detect-changes.outputs.run-full-ci == 'true'
76136 runs-on : ubuntu-latest
137+ timeout-minutes : 10
77138 permissions :
78139 contents : read
140+ env :
141+ RUSTDOCFLAGS : " -D warnings"
79142 steps :
80- - uses : actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # actions/checkout v6
81- - uses : dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # dtolnay/rust-toolchain stable
82- - uses : Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # Swatinem/rust-cache v2
83- - run : cargo doc --no-deps --all-features
84- env :
85- RUSTDOCFLAGS : -D warnings
143+ - uses : actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
144+ - uses : dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable
145+ with :
146+ toolchain : stable
147+ - uses : Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
148+ with :
149+ shared-key : " ci"
150+ - name : Build docs
151+ run : cargo doc --no-deps --all-features
86152
87153 security :
88154 name : Security Audit
89155 runs-on : ubuntu-latest
156+ timeout-minutes : 5
90157 permissions :
91158 contents : read
92159 steps :
93- - uses : actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # actions/checkout v6
94- - uses : EmbarkStudios/cargo-deny-action@91bf2b620e09e18d6eb78b92e7861937469acedb # EmbarkStudios/cargo-deny-action v2
160+ - uses : actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
161+ - uses : EmbarkStudios/cargo-deny-action@91bf2b620e09e18d6eb78b92e7861937469acedb # v2
95162
96163 coverage :
97164 name : Coverage
165+ if : github.event_name == 'push' && github.ref == 'refs/heads/main' && needs.detect-changes.outputs.run-full-ci == 'true'
166+ needs : [detect-changes, fmt, clippy]
98167 runs-on : ubuntu-latest
168+ timeout-minutes : 20
99169 permissions :
100170 contents : read
171+ # RUSTFLAGS reset: -C instrument-coverage conflicts with -D warnings from the
172+ # global env; linting is enforced by the dedicated clippy job.
173+ env :
174+ RUSTC_WRAPPER : sccache
175+ SCCACHE_GHA_ENABLED : " true"
176+ RUSTFLAGS : " "
101177 steps :
102- - uses : actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # actions/checkout v6
103- - uses : dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # dtolnay/rust-toolchain stable
178+ - uses : actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
179+ - uses : dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable
180+ with :
181+ toolchain : stable
182+ - uses : Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
104183 with :
105- components : llvm-tools-preview
106- - uses : Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # Swatinem/rust-cache v2
107- - uses : taiki-e/install-action@caf4aedf2bfe5bfb679703b29290921f4711b2f3 # taiki-e/install-action cargo-llvm-cov
108- - run : cargo llvm-cov --all-features --lcov --output-path lcov.info
109- - uses : codecov/codecov-action@57e3a136b779b570ffcdbf80b3bdc90e7fab3de2 # codecov/codecov-action v6
184+ cache-targets : " false"
185+ shared-key : " coverage"
186+ - uses : mozilla-actions/sccache-action@7d986dd989559c6ecdb630a3fd2557667be217ad # v0.0.9
187+ - uses : taiki-e/install-action@caf4aedf2bfe5bfb679703b29290921f4711b2f3 # cargo-llvm-cov
188+ - uses : taiki-e/install-action@dee540ee3f3ff5c6a0665fed9996875d0ba04ca2 # nextest
189+ - name : Generate coverage
190+ run : cargo llvm-cov nextest --workspace --all-features --lib --bins --lcov --output-path lcov.info
191+ - name : Upload coverage
192+ uses : codecov/codecov-action@57e3a136b779b570ffcdbf80b3bdc90e7fab3de2 # v6
110193 with :
111194 token : ${{ secrets.CODECOV_TOKEN }}
112195 files : lcov.info
@@ -115,11 +198,25 @@ jobs:
115198 ci-gate :
116199 name : CI Gate
117200 if : always()
118- needs : [check, fmt, clippy, test, docs, security, coverage]
201+ needs : [fmt, clippy, test, msrv , docs, security, coverage]
119202 runs-on : ubuntu-latest
203+ timeout-minutes : 1
120204 steps :
121- - run : |
122- if [[ "${{ contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') }}" == "true" ]]; then
123- echo "::error::One or more CI jobs failed or were cancelled"
124- exit 1
125- fi
205+ - name : Check all jobs
206+ run : |
207+ results=(
208+ "${{ needs.fmt.result }}"
209+ "${{ needs.clippy.result }}"
210+ "${{ needs.test.result }}"
211+ "${{ needs.msrv.result }}"
212+ "${{ needs.docs.result }}"
213+ "${{ needs.security.result }}"
214+ "${{ needs.coverage.result }}"
215+ )
216+ for r in "${results[@]}"; do
217+ if [[ "$r" != "success" && "$r" != "skipped" ]]; then
218+ echo "::error::One or more CI jobs failed or were cancelled"
219+ exit 1
220+ fi
221+ done
222+ echo "All jobs passed"
0 commit comments