Summary
There is currently no CI workflow that runs on pull requests or pushes to main. The only Rust checks (cargo fmt --check, clippy, build, test) live inside release.yml, which only triggers on v* tags. PRs can be merged with broken tests, formatting violations, or clippy warnings — issues are only caught at release time.
Current state
| Workflow |
Trigger |
Runs tests? |
release.yml |
push: tags: v* |
Yes, but only at release time |
docs.yml |
push: main, paths: docs/** |
No (docs build only) |
| CI (missing) |
pull_request / push: main |
Does not exist |
Proposed: .github/workflows/ci.yml
Based on codesoda/agentmark's CI workflow and Rust CI best practices:
name: CI
on:
push:
branches: [main]
pull_request:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
rust:
name: Rust checks
runs-on: ubuntu-latest
env:
CARGO_TERM_COLOR: always
CARGO_INCREMENTAL: "0"
RUSTFLAGS: "-D warnings"
RUST_BACKTRACE: 1
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt, clippy
- uses: Swatinem/rust-cache@v2
with:
cache-on-failure: true
- name: Check formatting
run: cargo fmt --check
- name: Clippy
run: cargo clippy --all-targets -- -D warnings
- name: Build
run: cargo build --all-targets
- name: Test
run: cargo test
Key design decisions
| Decision |
Rationale |
Swatinem/rust-cache@v2 with cache-on-failure: true |
Community standard for Rust caching. Caches registry, git deps, and target dir. cache-on-failure preserves partial work even on broken builds. |
concurrency with cancel-in-progress |
Cancels stale CI runs when new commits are pushed to the same PR. Saves runner minutes. |
CARGO_INCREMENTAL: "0" |
Incremental compilation wastes cache space in CI without benefit between fresh runs. |
RUSTFLAGS: "-D warnings" |
Treats warnings as errors. Matches existing release.yml behavior. |
RUST_BACKTRACE: 1 |
Full backtraces on test failures for easier debugging. |
--all-targets on build and clippy |
Catches issues in tests, examples, and integration tests — not just the main binary. |
| Separate fmt/clippy/build/test steps |
Clear feedback on exactly which check failed. |
| Single job (not matrix) |
Bugatti currently targets only aarch64-apple-darwin. A single ubuntu-latest job for checks is sufficient — the release workflow already validates the macOS build. Expand to a matrix if/when more targets are added. |
Follow-up items after merging
- Branch protection — Enable "Require status checks to pass before merging" on
main with the Rust checks job as required
- Simplify release.yml — The
check job in release.yml duplicates the CI workflow. Consider either:
- Removing it and relying on branch protection (CI already ran on the PR)
- Converting to
workflow_call to reuse the CI workflow
- Dependabot for Actions — Add
.github/dependabot.yml with package-ecosystem: github-actions to keep action versions current
Future considerations
- Cross-platform matrix — If Linux/Windows targets are added, expand to
matrix: os: [ubuntu-latest, macos-latest, windows-latest]
- MSRV testing — If a minimum supported Rust version is declared in
Cargo.toml, add cargo hack check --rust-version
--locked on release builds — Ensure release.yml uses cargo build --release --locked to pin exact Cargo.lock versions
- Weekly schedule run —
schedule: cron: '0 6 * * 1' catches upstream Rust/dependency breakage between PRs
Why this matters
Without PR-level CI, the first time broken code is detected is at release-tag time. At that point the broken code is already on main and the release is blocked until a fix lands.
Summary
There is currently no CI workflow that runs on pull requests or pushes to main. The only Rust checks (
cargo fmt --check,clippy,build,test) live insiderelease.yml, which only triggers onv*tags. PRs can be merged with broken tests, formatting violations, or clippy warnings — issues are only caught at release time.Current state
release.ymlpush: tags: v*docs.ymlpush: main, paths: docs/**pull_request/push: mainProposed:
.github/workflows/ci.ymlBased on codesoda/agentmark's CI workflow and Rust CI best practices:
Key design decisions
Swatinem/rust-cache@v2withcache-on-failure: truecache-on-failurepreserves partial work even on broken builds.concurrencywithcancel-in-progressCARGO_INCREMENTAL: "0"RUSTFLAGS: "-D warnings"release.ymlbehavior.RUST_BACKTRACE: 1--all-targetson build and clippyaarch64-apple-darwin. A singleubuntu-latestjob for checks is sufficient — the release workflow already validates the macOS build. Expand to a matrix if/when more targets are added.Follow-up items after merging
mainwith theRust checksjob as requiredcheckjob inrelease.ymlduplicates the CI workflow. Consider either:workflow_callto reuse the CI workflow.github/dependabot.ymlwithpackage-ecosystem: github-actionsto keep action versions currentFuture considerations
matrix: os: [ubuntu-latest, macos-latest, windows-latest]Cargo.toml, addcargo hack check --rust-version--lockedon release builds — Ensurerelease.ymlusescargo build --release --lockedto pin exactCargo.lockversionsschedule: cron: '0 6 * * 1'catches upstream Rust/dependency breakage between PRsWhy this matters
Without PR-level CI, the first time broken code is detected is at release-tag time. At that point the broken code is already on
mainand the release is blocked until a fix lands.