# Secret scan — the authoritative, non-bypassable secret gate (PLA-545, plan §1c).
#
# Local pre-commit hooks (lefthook.yml) are ADVISORY: a developer can skip them with
# `git commit --no-verify`. This CI check cannot be skipped, so it is the real wall that
# keeps credentials out of the repository's history.
#
# It runs gitleaks at a PINNED version (matching the Brewfile / local hook) so a finding
# locally is a finding here, and vice-versa (no "green locally, red on CI" drift):
#   - gitleaks — git-history-aware; on a PR it scans the commit range, so a secret is
#                caught even if a later commit in the same PR deletes it.
#
# (detect-secrets was previously run here too but was removed: `detect-secrets-hook`
# rewrites .secrets.baseline in place to refresh line numbers of already-acknowledged
# secrets, then exits 3 whenever any baseline-tracked file's line numbers drift — falsely
# failing master with no actual new secret. gitleaks is now the sole scanner.)
#
# To make this a TRUE gate, mark the "secret-scan" check as REQUIRED in the repo's branch
# protection rules for `master` (Settings → Branches). Code alone cannot enforce that.
name: Secret scan

on:
  pull_request:
    types: [opened, synchronize, reopened]
  push:
    branches: [master]
  workflow_dispatch:

concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
  cancel-in-progress: true

permissions:
  contents: read

env:
  # Pin gitleaks so CI matches the Brewfile / local hook (plan §1c, Decisions #3).
  # Bump in lockstep with the Brewfile.
  GITLEAKS_VERSION: "8.30.1"

jobs:
  secret-scan:
    runs-on: ubuntu-latest
    timeout-minutes: 10
    steps:
      - name: Checkout (full history)
        uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
        with:
          # gitleaks scans the PR commit RANGE (base..head), which needs both endpoints
          # present in the local clone — the default shallow fetch has neither.
          fetch-depth: 0

      - name: Install gitleaks (pinned)
        run: |
          set -euo pipefail
          tarball="gitleaks_${GITLEAKS_VERSION}_linux_x64.tar.gz"
          url="https://github.com/gitleaks/gitleaks/releases/download/v${GITLEAKS_VERSION}/${tarball}"
          curl --fail --silent --show-error --location "$url" -o "/tmp/${tarball}"
          tar -xzf "/tmp/${tarball}" -C /tmp gitleaks
          sudo install -m 0755 /tmp/gitleaks /usr/local/bin/gitleaks
          gitleaks version

      - name: gitleaks
        env:
          BASE_SHA: ${{ github.event.pull_request.base.sha }}
          HEAD_SHA: ${{ github.event.pull_request.head.sha }}
        run: |
          set -euo pipefail
          if [ "${GITHUB_EVENT_NAME}" = "pull_request" ]; then
            echo "Scanning PR commit range ${BASE_SHA}..${HEAD_SHA}"
            gitleaks git \
              --config .gitleaks.toml \
              --redact --no-banner --verbose \
              --log-opts="${BASE_SHA}..${HEAD_SHA}"
          else
            echo "Scanning the full working tree"
            gitleaks dir \
              --config .gitleaks.toml \
              --redact --no-banner --verbose \
              .
          fi
