# tenon in GitHub Actions.
#
# Copy it to .github/workflows/tenon.yml and ci/tenon.toml next to your code
# (see docs/ci.md).
#
# Secrets to define in the repository settings:
#   MISTRAL_API_KEY  the provider key.
# Never expose it to pull requests from forks: a fork author controls
# ci/tenon.toml and the task. The condition below skips them.
#
# The exit code of the job is the exit code of tenon (0, 1, 3 or 4).
name: tenon
on:
  workflow_dispatch:
    inputs:
      task:
        description: Task given to tenon
        required: true
  pull_request:

permissions:
  contents: read

jobs:
  tenon:
    # Runner image pinned to an explicit version.
    runs-on: ubuntu-24.04
    if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository
    env:
      TENON_TASK: ${{ github.event.inputs.task || 'Review the changes of this pull request and run the tests.' }}
    steps:
      # Consider pinning actions by commit SHA for stronger supply-chain guarantees.
      - uses: actions/checkout@v4.2.2
        with:
          persist-credentials: false
      - uses: actions/setup-go@v5.1.0
        with:
          go-version: "1.26.9"
      - name: Install tenon
        run: |
          set -eu
          sudo apt-get update -qq
          sudo apt-get install -y --no-install-recommends ca-certificates curl minisign
          # Pinned version; the signature is mandatory.
          # To install from a mirror, uncomment the next line. The signature is
          # still verified, so a compromised mirror cannot serve a forged binary.
          # export TENON_DOWNLOAD_BASE="https://mirror.example.eu/tenon"
          # For an air-gapped or mirror install, also fetch install.sh itself from
          # the mirror (or vendor it in your repository) and pin it with a
          # "sha256sum -c" check: it carries the minisign public key.
          curl -fsSL -o install.sh https://raw.githubusercontent.com/tenon-code-eu/tenon/v0.8.0/install.sh
          TENON_VERSION=v0.8.0 TENON_REQUIRE_SIGNATURE=1 sh install.sh
          echo "$HOME/.local/bin" >> "$GITHUB_PATH"
      - name: Run tenon
        env:
          MISTRAL_API_KEY: ${{ secrets.MISTRAL_API_KEY }}
        run: |
          set -eu
          rc=0
          tenon --config ci/tenon.toml -p "$TENON_TASK" --strict --output json > tenon-events.jsonl || rc=$?
          exit "$rc"
      - name: Verify and export the audit log
        if: always()
        run: |
          set -eu
          # The run step already fails the job on a tenon error; verify and
          # export always run to archive the evidence.
          # The audit log lives in tenon's default data dir, outside the
          # workspace (the sandbox denies it to commands): copy it into the
          # workspace so the artifact upload can find it.
          mkdir -p tenon-audit-log
          cp -R "${XDG_DATA_HOME:-$HOME/.local/share}/tenon/audit/." tenon-audit-log/ || true
          vrc=0
          tenon --config ci/tenon.toml audit verify || vrc=$?
          tenon --config ci/tenon.toml audit export --all-projects --out tenon-audit
          exit "$vrc"
      - name: Archive the evidence
        if: always()
        uses: actions/upload-artifact@v4.4.3
        with:
          name: tenon-evidence
          include-hidden-files: true
          if-no-files-found: warn
          retention-days: 90
          path: |
            tenon-events.jsonl
            tenon-audit/
            tenon-audit-log/
