| name | github-ci-fundamentals |
| description | Standard GitHub Actions CI structure for Rust projects using ci-battery-pack |
GitHub CI Fundamentals
Standard CI structure generated by ci-battery-pack for Rust projects on GitHub Actions.
Setup:
cargo install cargo-bp
cargo bp new ci --name my-project
cargo bp add ci -t spellcheck
Workflow Structure
The core CI workflow (ci.yml) runs on PRs, merge queue, and pushes to main. It includes:
| Job | Purpose |
|---|
fmt | cargo fmt --check |
clippy | Lint with -D warnings |
warnings | cargo check with RUSTFLAGS="-Dwarnings" (separate from clippy so test failures don't hide warnings) |
docsrs | Docs build with all features under cfg(docsrs) |
build | Matrix: stable × nightly, --all-features × --no-default-features |
features | cargo hack check --feature-powerset --depth 2 --no-dev-deps |
msrv | cargo hack check --rust-version (verifies declared MSRV) |
lockfile | cargo update --workspace --locked (catches stale lockfiles) |
minimal-versions | Generates a minimal-version lockfile, then checks with stable |
semver | cargo-semver-checks (catches accidental breaking changes) |
audit.yml runs RustSec audit-check daily and on Cargo manifest, lockfile, or audit workflow changes. Set audit_issue=false to run cargo audit without issue creation.
dependency-policy.yml runs cargo-deny for licenses, bans, and sources. Set dependency_policy=false to skip it.
The Gate Job Pattern
All jobs feed into a single ci-pass job that uses jq to assert all dependencies succeeded or were skipped:
ci-pass:
needs: [fmt, clippy, warnings, docsrs, build, features, msrv, lockfile, minimal-versions, semver]
if: ${{ !cancelled() }}
runs-on: ubuntu-latest
steps:
- run: jq --exit-status 'all(.result == "success" or .result == "skipped")' <<< '${{ toJson(needs) }}'
Set ci-pass as the single required status check in branch protection. This avoids updating branch protection rules every time you add or remove a CI job.
SHA Pinning
All GitHub Actions are pinned to commit SHAs at generation time (e.g., actions/checkout@abc123 # v6.0.2). This follows GitHub's security hardening guidance. Dependabot keeps them updated via the generated dependabot.yml, which also handles Cargo dependency updates (major versions only, since Cargo resolves compatible versions automatically).
Concurrency
PR workflows use concurrency groups to cancel superseded runs:
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
Adding Features to an Existing Project
Each additional workflow or scaffold is available as a standalone template:
cargo bp add ci -t trusted-publishing
cargo bp add ci -t binary-release
cargo bp add ci -t fuzzing
cargo bp add ci -t benchmarks
cargo bp add ci -t security-scanning
cargo bp add ci -t dependency-policy
cargo bp add ci -t spellcheck
cargo bp add ci -t mutation-testing
cargo bp add ci -t clippy-sarif
cargo bp add ci -t mdbook
cargo bp add ci -t xtask
cargo bp add ci -t stress-test
Preview before applying: cargo bp show ci -t fuzzing
YAML and TOML files are merged additively (new keys added, existing preserved). Other file types prompt for skip/overwrite.
What the agent can do
- Run
cargo bp new ci --name <project> or cargo bp add ci -t <template> to generate files
- Edit generated workflow YAML,
deny.toml, _typos.toml, release-plz.toml
- Add or modify Cargo.toml sections (features, metadata, dependencies)
- Preview templates with
cargo bp show ci -t <template>
What requires human action (outside the repo)
These steps involve GitHub/crates.io web UIs that the agent cannot access. After generating files, instruct the user to complete:
- Set
ci-pass as the required status check in branch protection
- See the trusted-publishing skill for release pipeline setup (crates.io + GitHub settings)
- See the binary-releases skill for PAT and secret configuration