gbd 1.9.0

The Beads agent workflow on GitHub Issues and Projects
Documentation
name: ci

on:
  push:
    branches: [main]
  pull_request:
  # The merge queue builds a temporary branch and fires this event. Without
  # it no check ever reports on a queue entry and every entry times out.
  merge_group:

env:
  CARGO_TERM_COLOR: always
  RUST_BACKTRACE: 1
  # See release.yml for rationale; Node.js 20 actions are deprecated and
  # forced-to-Node-24 default lands 2026-06-02.
  FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: "true"

# Toolchain comes from rust-toolchain.toml: a step reads `channel` and feeds
# it to dtolnay/rust-toolchain (which requires an explicit toolchain), so
# local and CI lint with the same clippy and there is one place to bump.
jobs:
  fmt:
    name: fmt
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
      - name: Read pinned toolchain
        id: toolchain
        run: echo "channel=$(sed -n 's/^channel = "\(.*\)"/\1/p' rust-toolchain.toml)" >> "$GITHUB_OUTPUT"
      - uses: dtolnay/rust-toolchain@02cb101ec7c40f2c49e1d9714d64511d8e1b74de # master
        with:
          toolchain: ${{ steps.toolchain.outputs.channel }}
          components: rustfmt
      - run: cargo fmt --check

  # One OS: there is no cfg(target_os) code, so a second clippy run only
  # adds queue time. Tests still run on both.
  clippy:
    name: clippy
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
      - name: Read pinned toolchain
        id: toolchain
        run: echo "channel=$(sed -n 's/^channel = "\(.*\)"/\1/p' rust-toolchain.toml)" >> "$GITHUB_OUTPUT"
      - uses: dtolnay/rust-toolchain@02cb101ec7c40f2c49e1d9714d64511d8e1b74de # master
        with:
          toolchain: ${{ steps.toolchain.outputs.channel }}
          components: clippy
      - uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2
      - run: cargo clippy --all-targets -- -D warnings

  test:
    name: test (${{ matrix.os }})
    strategy:
      fail-fast: false
      matrix:
        os: [ubuntu-latest, macos-latest]
    runs-on: ${{ matrix.os }}
    steps:
      - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
      - name: Read pinned toolchain
        id: toolchain
        run: echo "channel=$(sed -n 's/^channel = "\(.*\)"/\1/p' rust-toolchain.toml)" >> "$GITHUB_OUTPUT"
      - uses: dtolnay/rust-toolchain@02cb101ec7c40f2c49e1d9714d64511d8e1b74de # master
        with:
          toolchain: ${{ steps.toolchain.outputs.channel }}
      - uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2
      - run: cargo test --all-targets

  # Cargo.toml's rust-version is a promise; this keeps it true. `cargo +X`
  # overrides rust-toolchain.toml for the one invocation.
  msrv:
    name: msrv
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
      - name: Read rust-version
        id: msrv
        run: echo "version=$(sed -n 's/^rust-version = "\(.*\)"/\1/p' Cargo.toml)" >> "$GITHUB_OUTPUT"
      - uses: dtolnay/rust-toolchain@02cb101ec7c40f2c49e1d9714d64511d8e1b74de # master
        with:
          toolchain: ${{ steps.msrv.outputs.version }}
      - uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2
        with:
          key: msrv
      - run: cargo +${{ steps.msrv.outputs.version }} check --locked --all-targets

  deny:
    name: cargo-deny
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
      - uses: EmbarkStudios/cargo-deny-action@3c6349835b2b7b196a839186cb8b78e02f7b5f25 # v2.1.1
        with:
          command: check advisories licenses bans sources