safe-chains 0.230.5

Auto-allow safe bash commands in agentic coding tools
Documentation
name: CI

on:
  push:
    branches: ["**"]
  pull_request:

env:
  CARGO_TERM_COLOR: always

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}

permissions:
  contents: read

jobs:
  ci:
    name: Check, Test, Lint
    runs-on: ubuntu-latest
    timeout-minutes: 30
    steps:
      - uses: actions/checkout@v7

      # The version and components come from rust-toolchain.toml.
      - name: Install the pinned toolchain
        run: rustup toolchain install

      - uses: Swatinem/rust-cache@v2

      - name: cargo fmt
        run: |
          cargo fmt --all --check
          cargo fmt --manifest-path fuzz/Cargo.toml --all --check

      - name: cargo check
        run: cargo check --locked

      - name: cargo test
        run: cargo test --locked

      # The fuzz-corpus generator is feature-gated, so the plain run above never builds it.
      - name: cargo test (gen-fuzz-corpus)
        run: cargo test --locked --features fuzz-gen --bin gen-fuzz-corpus

      - name: cargo clippy
        run: cargo clippy --locked --all-targets --all-features -- -D warnings

      # A broken intra-doc link or a link to a private item fails here rather than on docs.rs.
      - name: cargo doc
        run: cargo doc --locked --no-deps --all-features
        env:
          RUSTDOCFLAGS: -D warnings

      # Also checked at release time. It belongs here too: release.yml only runs on a version bump,
      # so a stale or truncated COMMANDS.md can otherwise ride along for many pushes unnoticed.
      - name: Verify COMMANDS.md is up to date
        run: |
          cargo run --locked -- --list-commands > COMMANDS.md.check
          diff -u COMMANDS.md COMMANDS.md.check || {
            echo "::error::COMMANDS.md is out of date. Run ./generate-docs.sh and commit."
            exit 1
          }

      - uses: taiki-e/install-action@cargo-deny

      - name: cargo deny check
        run: cargo deny check

      - uses: taiki-e/install-action@cargo-machete

      - name: cargo machete
        run: cargo machete

      # Every tracked shell script, so a new one is checked the day it lands.
      - name: shellcheck
        run: git ls-files -z '*.sh' | xargs -0 shellcheck

  # The published crate declares `rust-version`; this is what makes that claim true.
  msrv:
    name: MSRV
    runs-on: ubuntu-latest
    timeout-minutes: 30
    steps:
      - uses: actions/checkout@v7

      - name: Install the declared minimum Rust
        run: |
          msrv=$(sed -n 's/^rust-version = "\(.*\)"/\1/p' Cargo.toml)
          test -n "$msrv"
          rustup toolchain install "$msrv" --profile minimal
          echo "MSRV=$msrv" >> "$GITHUB_ENV"
          # Every later step, rust-cache's key included, runs on the MSRV rather than installing
          # the toolchain rust-toolchain.toml pins.
          echo "RUSTUP_TOOLCHAIN=$msrv" >> "$GITHUB_ENV"

      - uses: Swatinem/rust-cache@v2

      - name: cargo check on the MSRV
        run: cargo +"$MSRV" check --locked