fallow-cov-protocol 0.3.0

Versioned JSON envelope types shared between the fallow CLI and the fallow-cov production-coverage sidecar.
Documentation
name: CI

# CI BUDGET NOTE (temporary):
# The account is near its Actions minute quota. Per-push/PR CI is trimmed to
# ubuntu-latest only; the macOS + Windows matrix entries, MSRV job, and
# publish-dry-run are gated behind `workflow_dispatch` and must be run
# manually (Actions tab → "Run workflow") or locally before a release:
#
#   cargo test --all-targets
#   cargo clippy --all-targets -- -D warnings
#   cargo fmt --all -- --check
#   cargo +1.75.0 check --all-targets        # MSRV
#   cargo publish --dry-run                  # before tagging
#
# Revert to per-push by removing the `if:` gates below and restoring the
# full matrix once the quota resets.

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]
  workflow_dispatch:

permissions: {}

concurrency:
  group: ci-${{ github.ref }}
  cancel-in-progress: true

env:
  CARGO_TERM_COLOR: always

jobs:
  check:
    name: Check (${{ matrix.os }})
    runs-on: ${{ matrix.os }}
    timeout-minutes: 15
    permissions:
      contents: read
    strategy:
      fail-fast: false
      matrix:
        # ubuntu is always included; macOS (10x billing) and Windows (2x) only
        # on manual dispatch while the Actions quota is tight.
        os: ${{ github.event_name == 'workflow_dispatch' && fromJSON('["ubuntu-latest","macos-latest","windows-latest"]') || fromJSON('["ubuntu-latest"]') }}
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
      - uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
        with:
          key: check-${{ matrix.os }}

      - name: Run tests
        run: cargo test --all-targets

      - name: Clippy
        run: cargo clippy --all-targets -- -D warnings

      - name: Format
        run: cargo fmt --all -- --check

      - name: Check for uncommitted changes
        run: git diff --exit-code

  doc:
    name: Documentation
    runs-on: ubuntu-latest
    timeout-minutes: 10
    permissions:
      contents: read
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
      - uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
        with:
          key: doc
      - name: Check documentation
        env:
          RUSTDOCFLAGS: "-D warnings"
        run: cargo doc --no-deps --document-private-items

  typos:
    name: Typos
    runs-on: ubuntu-latest
    timeout-minutes: 5
    permissions:
      contents: read
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
      - uses: crate-ci/typos@cf5f1c29a8ac336af8568821ec41919923b05a83 # v1

  audit:
    name: Security Audit
    runs-on: ubuntu-latest
    timeout-minutes: 10
    permissions:
      contents: read
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
      - uses: taiki-e/install-action@9b29ffac42f36c4efe76140737435c61cfb92383 # cargo-audit
      - run: cargo audit

  deny:
    name: Cargo Deny
    runs-on: ubuntu-latest
    timeout-minutes: 10
    permissions:
      contents: read
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
      - uses: EmbarkStudios/cargo-deny-action@3fd3802e88374d3fe9159b834c7714ec57d6c979 # v2

  shear:
    name: Unused Dependencies
    runs-on: ubuntu-latest
    timeout-minutes: 10
    permissions:
      contents: read
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
      - uses: taiki-e/install-action@b9da40722b5dc25d162879fdf6a098f2d71926cc # cargo-shear
      - run: cargo shear

  zizmor:
    name: Actions Security
    runs-on: ubuntu-latest
    timeout-minutes: 10
    permissions:
      contents: read
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
      - uses: astral-sh/setup-uv@cec208311dfd045dd5311c1add060b2062131d57 # v8.0.0
      - run: uvx zizmor --min-confidence medium --format plain .

  msrv:
    name: MSRV (1.75)
    # Temporarily manual-only to stay under the Actions quota; run locally via
    # `cargo +1.75.0 check --all-targets` before merging MSRV-sensitive changes.
    if: github.event_name == 'workflow_dispatch'
    runs-on: ubuntu-latest
    timeout-minutes: 15
    permissions:
      contents: read
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
      - name: Install pinned MSRV toolchain
        run: |
          rustup toolchain install 1.75.0 --profile minimal
          rustup override set 1.75.0
      - uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
        with:
          key: msrv
      - run: cargo check --all-targets

  publish-dry-run:
    name: Publish (dry run)
    # Manual-only while the Actions quota is tight; the release skill runs
    # `cargo publish --dry-run` locally before tagging.
    if: github.event_name == 'workflow_dispatch'
    runs-on: ubuntu-latest
    timeout-minutes: 15
    permissions:
      contents: read
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
      - uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
        with:
          key: publish-dry-run
      - run: cargo publish --dry-run

  ci-ok:
    name: CI
    if: always()
    needs: [check, doc, typos, audit, deny, shear, zizmor, msrv, publish-dry-run]
    runs-on: ubuntu-latest
    timeout-minutes: 5
    permissions: {}
    steps:
      - name: All checks passed
        env:
          RESULTS: ${{ toJSON(needs.*.result) }}
        run: |
          for result in $(echo "$RESULTS" | jq -r '.[]'); do
            if [ "$result" != "success" ] && [ "$result" != "skipped" ]; then
              echo "::error::Job failed with result: $result"
              exit 1
            fi
          done