Skip to content

Add CI workflow: run test suite on PRs and pushes to main #31

@codesoda

Description

@codesoda

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

  1. Branch protection — Enable "Require status checks to pass before merging" on main with the Rust checks job as required
  2. 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
  3. 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 runschedule: 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions