name: Security Audit

permissions:
  contents: read

on:
  push:
    branches: ["main"]
  pull_request:
    types: [opened, synchronize, reopened]
  schedule:
    - cron: "17 4 * * 1"
  workflow_dispatch:

jobs:
  dependency-audit:
    name: Dependency audit
    if: ${{ github.event_name != 'schedule' }}
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
        with:
          fetch-depth: 0

      - name: Install uv
        uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0

      - name: Set up Python
        uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6
        with:
          python-version: "3.14"

      - name: Check committed audit requirements are current
        env:
          DEPENDENCY_DIFF_BASE: ${{ github.event.pull_request.base.sha || github.event.before || '' }}
          DEPENDENCY_DIFF_HEAD: ${{ github.sha }}
          GENERATED_REQUIREMENTS: ${{ runner.temp }}/security-audit-requirements.txt
        run: python .github/scripts/check_security_requirements.py

      - name: Run pip-audit (committed requirements)
        run: uvx --from pip-audit==2.10.0 pip-audit --disable-pip --require-hashes -r .github/security-audit-requirements.txt --progress-spinner off

  dependency-audit-scheduled:
    name: Dependency audit scheduled (${{ matrix.os }}, Python ${{ matrix.python-version }})
    if: ${{ github.event_name == 'schedule' }}
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false
      matrix:
        os: [ubuntu-latest, windows-latest]
        python-version: ["3.11", "3.12", "3.13", "3.14"]
    steps:
      - name: Checkout
        uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

      - name: Install uv
        uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0

      - name: Set up Python ${{ matrix.python-version }}
        uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6
        with:
          python-version: ${{ matrix.python-version }}

      # The committed .github/security-audit-requirements.txt is generated with
      # --universal (resolves across all interpreters/platforms) and is what
      # push/PR/workflow_dispatch runs audit. The scheduled job instead compiles
      # per matrix entry with --python-version so it can surface advisories in
      # wheels that only resolve on a specific interpreter (e.g. 3.11-only) —
      # coverage the universal file may not exercise. This broadening is
      # intentional; non-scheduled runs trade that depth for determinism against
      # the committed snapshot.
      - name: Compile scheduled audit requirements
        run: |
          uv pip compile pyproject.toml --extra test --python-version "${{ matrix.python-version }}" --upgrade --generate-hashes --quiet --output-file "${{ runner.temp }}/spec-kit-audit-requirements.txt"

      - name: Run pip-audit (scheduled live resolution)
        run: uvx --from pip-audit==2.10.0 pip-audit --disable-pip --require-hashes -r "${{ runner.temp }}/spec-kit-audit-requirements.txt" --progress-spinner off
