Skip to content

Commit bc16b38

Browse files
committed
ci: use nightly Rust for rustfmt check
Use cargo +nightly fmt for format checking to access latest formatting features while keeping clippy and doc checks on stable Rust for stability. Changes: - Install both stable (for clippy) and nightly (for rustfmt) toolchains - Run 'cargo +nightly fmt --all -- --check' for format validation - Keep clippy and doc generation on stable Rust
1 parent 5f48022 commit bc16b38

File tree

1 file changed

+301
-0
lines changed

1 file changed

+301
-0
lines changed

.github/workflows/ci.yml

Lines changed: 301 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,301 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [master, main, develop]
6+
pull_request:
7+
branches: [master, main, develop]
8+
schedule:
9+
# Weekly security audit on Sundays at midnight
10+
- cron: '0 0 * * 0'
11+
12+
env:
13+
CARGO_TERM_COLOR: always
14+
CARGO_INCREMENTAL: 0
15+
CARGO_NET_RETRY: 10
16+
RUST_BACKTRACE: short
17+
RUSTFLAGS: "-D warnings"
18+
RUSTUP_MAX_RETRIES: 10
19+
20+
# Cancel previous runs on new push
21+
concurrency:
22+
group: ${{ github.workflow }}-${{ github.ref }}
23+
cancel-in-progress: true
24+
25+
jobs:
26+
# Quick checks first - fail fast strategy
27+
check:
28+
name: Check
29+
runs-on: ubuntu-latest
30+
timeout-minutes: 15
31+
steps:
32+
- uses: actions/checkout@v5
33+
34+
- name: Install Rust stable
35+
uses: dtolnay/rust-toolchain@stable
36+
with:
37+
components: clippy
38+
39+
- name: Install Rust nightly (for rustfmt)
40+
uses: dtolnay/rust-toolchain@nightly
41+
with:
42+
components: rustfmt
43+
44+
- name: Cache Cargo
45+
uses: Swatinem/rust-cache@v2
46+
with:
47+
shared-key: "check"
48+
save-if: ${{ github.ref == 'refs/heads/master' || github.ref == 'refs/heads/main' }}
49+
50+
- name: Check formatting (nightly)
51+
run: cargo +nightly fmt --all -- --check
52+
53+
- name: Clippy (all targets, all features)
54+
run: cargo clippy --all-targets --all-features --workspace -- -D warnings
55+
56+
- name: Check documentation
57+
run: cargo doc --no-deps --all-features --workspace
58+
env:
59+
RUSTDOCFLAGS: "-D warnings"
60+
61+
# Security audit using cargo-audit
62+
security:
63+
name: Security Audit
64+
runs-on: ubuntu-latest
65+
timeout-minutes: 10
66+
steps:
67+
- uses: actions/checkout@v5
68+
69+
- name: Install Rust
70+
uses: dtolnay/rust-toolchain@stable
71+
72+
- name: Install cargo-audit
73+
uses: taiki-e/install-action@v2
74+
with:
75+
tool: cargo-audit
76+
77+
- name: Security audit
78+
run: cargo audit --deny warnings
79+
80+
# Cross-platform tests with matrix
81+
test:
82+
name: Test (${{ matrix.os }}, Rust ${{ matrix.rust }})
83+
needs: [check]
84+
runs-on: ${{ matrix.os }}
85+
timeout-minutes: 45
86+
strategy:
87+
fail-fast: false
88+
matrix:
89+
os: [ubuntu-latest, macos-latest, windows-latest]
90+
rust: [stable]
91+
include:
92+
# Test on beta channel on Linux only
93+
- os: ubuntu-latest
94+
rust: beta
95+
# Test on nightly (allow to fail)
96+
- os: ubuntu-latest
97+
rust: nightly
98+
continue-on-error: ${{ matrix.rust == 'nightly' }}
99+
100+
steps:
101+
- uses: actions/checkout@v5
102+
103+
- name: Install Rust ${{ matrix.rust }}
104+
uses: dtolnay/rust-toolchain@master
105+
with:
106+
toolchain: ${{ matrix.rust }}
107+
108+
# Setup sccache for faster compilation
109+
- name: Setup sccache
110+
uses: mozilla-actions/[email protected]
111+
112+
- name: Configure sccache
113+
shell: bash
114+
run: |
115+
echo "RUSTC_WRAPPER=sccache" >> $GITHUB_ENV
116+
echo "SCCACHE_GHA_ENABLED=true" >> $GITHUB_ENV
117+
118+
- name: Cache Cargo
119+
uses: Swatinem/rust-cache@v2
120+
with:
121+
shared-key: "test-${{ matrix.os }}-${{ matrix.rust }}"
122+
save-if: ${{ github.ref == 'refs/heads/master' || github.ref == 'refs/heads/main' }}
123+
124+
- name: Install nextest
125+
uses: taiki-e/install-action@v2
126+
with:
127+
tool: nextest
128+
129+
- name: Build (all targets, all features)
130+
run: cargo build --all-targets --all-features --workspace
131+
132+
- name: Run tests (nextest)
133+
run: cargo nextest run --all-features --workspace --no-fail-fast
134+
135+
- name: Run doctests
136+
run: cargo test --doc --all-features --workspace
137+
138+
- name: sccache stats
139+
run: sccache --show-stats
140+
141+
# Code coverage (Linux only for speed)
142+
coverage:
143+
name: Code Coverage
144+
needs: [check]
145+
runs-on: ubuntu-latest
146+
timeout-minutes: 30
147+
steps:
148+
- uses: actions/checkout@v5
149+
150+
- name: Install Rust
151+
uses: dtolnay/rust-toolchain@stable
152+
153+
- name: Install llvm-cov
154+
uses: taiki-e/install-action@v2
155+
with:
156+
tool: cargo-llvm-cov
157+
158+
- name: Install nextest
159+
uses: taiki-e/install-action@v2
160+
with:
161+
tool: nextest
162+
163+
- name: Cache Cargo
164+
uses: Swatinem/rust-cache@v2
165+
with:
166+
shared-key: "coverage"
167+
save-if: ${{ github.ref == 'refs/heads/master' || github.ref == 'refs/heads/main' }}
168+
169+
- name: Generate coverage (nextest)
170+
run: |
171+
cargo llvm-cov --all-features --workspace --lcov \
172+
--output-path lcov.info nextest
173+
174+
- name: Upload to codecov
175+
uses: codecov/codecov-action@v5
176+
with:
177+
token: ${{ secrets.CODECOV_TOKEN }}
178+
files: lcov.info
179+
fail_ci_if_error: false
180+
verbose: true
181+
flags: unittests
182+
name: codecov-umbrella
183+
184+
- name: Archive coverage report
185+
uses: actions/upload-artifact@v4
186+
with:
187+
name: coverage-report
188+
path: lcov.info
189+
retention-days: 30
190+
191+
# MSRV check (Minimum Supported Rust Version)
192+
msrv:
193+
name: Check MSRV (1.85)
194+
needs: [check]
195+
runs-on: ubuntu-latest
196+
timeout-minutes: 20
197+
steps:
198+
- uses: actions/checkout@v5
199+
200+
- name: Install Rust 1.85
201+
uses: dtolnay/rust-toolchain@master
202+
with:
203+
toolchain: "1.85"
204+
205+
- name: Cache Cargo
206+
uses: Swatinem/rust-cache@v2
207+
with:
208+
shared-key: "msrv"
209+
210+
- name: Check with MSRV
211+
run: cargo check --all-features --workspace
212+
213+
# Benchmarks (build only, don't run in CI)
214+
benchmark:
215+
name: Benchmark Build
216+
needs: [check]
217+
runs-on: ubuntu-latest
218+
timeout-minutes: 25
219+
steps:
220+
- uses: actions/checkout@v5
221+
222+
- name: Install Rust
223+
uses: dtolnay/rust-toolchain@stable
224+
225+
- name: Setup sccache
226+
uses: mozilla-actions/[email protected]
227+
228+
- name: Configure sccache
229+
run: |
230+
echo "RUSTC_WRAPPER=sccache" >> $GITHUB_ENV
231+
echo "SCCACHE_GHA_ENABLED=true" >> $GITHUB_ENV
232+
233+
- name: Cache Cargo
234+
uses: Swatinem/rust-cache@v2
235+
with:
236+
shared-key: "bench"
237+
238+
- name: Build benchmarks (no run)
239+
run: cargo bench --no-run --workspace
240+
241+
- name: sccache stats
242+
run: sccache --show-stats
243+
244+
# Release build check
245+
release:
246+
name: Release Build
247+
needs: [test]
248+
runs-on: ubuntu-latest
249+
timeout-minutes: 25
250+
steps:
251+
- uses: actions/checkout@v5
252+
253+
- name: Install Rust
254+
uses: dtolnay/rust-toolchain@stable
255+
256+
- name: Setup sccache
257+
uses: mozilla-actions/[email protected]
258+
259+
- name: Configure sccache
260+
run: |
261+
echo "RUSTC_WRAPPER=sccache" >> $GITHUB_ENV
262+
echo "SCCACHE_GHA_ENABLED=true" >> $GITHUB_ENV
263+
264+
- name: Cache Cargo
265+
uses: Swatinem/rust-cache@v2
266+
with:
267+
shared-key: "release"
268+
269+
- name: Build release
270+
run: cargo build --release --all-features --workspace
271+
272+
- name: Check binary sizes
273+
run: |
274+
echo "Binary sizes:"
275+
ls -lh target/release/ | grep -E "(mcp-cli|mcp-examples)" || true
276+
echo ""
277+
echo "Target directory size:"
278+
du -sh target/release/
279+
280+
- name: sccache stats
281+
run: sccache --show-stats
282+
283+
# All checks passed
284+
ci-success:
285+
name: CI Success
286+
needs: [check, security, test, coverage, msrv, benchmark]
287+
runs-on: ubuntu-latest
288+
if: always()
289+
steps:
290+
- name: Check all jobs
291+
run: |
292+
if [[ "${{ needs.check.result }}" != "success" ]] || \
293+
[[ "${{ needs.security.result }}" != "success" ]] || \
294+
[[ "${{ needs.test.result }}" != "success" ]] || \
295+
[[ "${{ needs.coverage.result }}" != "success" ]] || \
296+
[[ "${{ needs.msrv.result }}" != "success" ]] || \
297+
[[ "${{ needs.benchmark.result }}" != "success" ]]; then
298+
echo "One or more required jobs failed or were cancelled"
299+
exit 1
300+
fi
301+
echo "All required jobs passed successfully!"

0 commit comments

Comments
 (0)