homeboy 0.74.0

CLI for multi-component deployment and development workflow automation
Documentation
# PR quality pipeline.
#
# Build once, then strict serial pipeline: audit+fix → lint+fix → test+fix
# A single build job compiles homeboy from source and shares the binary
# via artifact. Each stage downloads it instead of rebuilding.
# If fixes are committed, the App token push triggers a full re-run.
# Scoped to changed files only (--changed-since via scope module).
#
# Fork PRs: CI runs read-only checks (no autofix, no baseline writes).
# The checkout uses the PR head SHA which works for both same-repo and fork PRs.
# Secrets (App token) are unavailable for forks — continue-on-error handles this.

name: CI

on:
  pull_request:
    branches: [main]

permissions:
  contents: write
  pull-requests: write

jobs:
  # ── Stage 0: Build once ──
  # Compile homeboy from source once and share the binary with all
  # subsequent stages. Eliminates 3× redundant cargo builds.
  build:
    name: Build
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          ref: ${{ github.event.pull_request.head.sha }}

      - name: Install Rust toolchain
        uses: dtolnay/rust-toolchain@stable

      - name: Cache cargo
        uses: actions/cache@v4
        with:
          path: |
            ~/.cargo/registry
            ~/.cargo/git
            target
          key: ${{ runner.os }}-cargo-ci-${{ hashFiles('Cargo.lock') }}
          restore-keys: ${{ runner.os }}-cargo-ci-

      - name: Build homeboy
        run: cargo build --release

      - name: Upload binary
        uses: actions/upload-artifact@v4
        with:
          name: homeboy-binary
          path: target/release/homeboy
          retention-days: 1

  # ── Stage 1: Audit + Fix ──
  # Runs first — most likely to induce changes. Autofix applies code fixes
  # via --fix --write but does NOT ratchet the baseline (no --ratchet).
  # Baseline ratchet only happens on main to avoid homeboy.json conflicts.
  # Fork PRs: autofix skipped (action detects fork via SCOPE_IS_FORK).
  audit:
    name: Audit
    needs: [build]
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          ref: ${{ github.event.pull_request.head.sha }}
          fetch-depth: 0

      - name: Download homeboy binary
        uses: actions/download-artifact@v4
        with:
          name: homeboy-binary
          path: .homeboy-bin

      - name: Generate GitHub App token
        id: app-token
        uses: actions/create-github-app-token@v1
        continue-on-error: true
        with:
          app-id: ${{ secrets.HOMEBOY_APP_ID }}
          private-key: ${{ secrets.HOMEBOY_APP_PRIVATE_KEY }}

      - uses: Extra-Chill/homeboy-action@v1
        with:
          binary-path: .homeboy-bin/homeboy
          extension: rust
          component: homeboy
          commands: audit
          autofix: ${{ github.event.pull_request.head.repo.full_name == github.repository && 'true' || 'false' }}
          autofix-mode: 'on-failure'
          autofix-commands: 'audit --fix --write'
          autofix-max-commits: '3'
          app-token: ${{ steps.app-token.outputs.token || '' }}

  # ── Stage 2: Lint + Fix ──
  # Runs after audit passes. Cargo fmt and clippy. Autofixes formatting
  # and clippy warnings. If fixes are committed, App token push triggers
  # re-run of all stages.
  # Fork PRs: autofix skipped.
  lint:
    name: Lint
    needs: [build, audit]
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          ref: ${{ github.event.pull_request.head.sha }}
          fetch-depth: 0

      - name: Download homeboy binary
        uses: actions/download-artifact@v4
        with:
          name: homeboy-binary
          path: .homeboy-bin

      - name: Generate GitHub App token
        id: app-token
        uses: actions/create-github-app-token@v1
        continue-on-error: true
        with:
          app-id: ${{ secrets.HOMEBOY_APP_ID }}
          private-key: ${{ secrets.HOMEBOY_APP_PRIVATE_KEY }}

      - uses: Extra-Chill/homeboy-action@v1
        with:
          binary-path: .homeboy-bin/homeboy
          extension: rust
          component: homeboy
          commands: lint
          autofix: ${{ github.event.pull_request.head.repo.full_name == github.repository && 'true' || 'false' }}
          autofix-mode: 'on-failure'
          autofix-max-commits: '3'
          app-token: ${{ steps.app-token.outputs.token || '' }}

  # ── Stage 3: Test + Fix ──
  # Runs after lint passes. If tests fail and fixes are available,
  # commits and triggers re-run.
  # Fork PRs: autofix skipped.
  test:
    name: Test
    needs: [build, lint]
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          ref: ${{ github.event.pull_request.head.sha }}
          fetch-depth: 0

      - name: Download homeboy binary
        uses: actions/download-artifact@v4
        with:
          name: homeboy-binary
          path: .homeboy-bin

      - name: Generate GitHub App token
        id: app-token
        uses: actions/create-github-app-token@v1
        continue-on-error: true
        with:
          app-id: ${{ secrets.HOMEBOY_APP_ID }}
          private-key: ${{ secrets.HOMEBOY_APP_PRIVATE_KEY }}

      - uses: Extra-Chill/homeboy-action@v1
        with:
          binary-path: .homeboy-bin/homeboy
          extension: rust
          component: homeboy
          commands: test
          autofix: ${{ github.event.pull_request.head.repo.full_name == github.repository && 'true' || 'false' }}
          autofix-mode: 'on-failure'
          autofix-max-commits: '3'
          app-token: ${{ steps.app-token.outputs.token || '' }}