# Copyright 2026 John Wilger

name: CI

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

permissions:
  contents: read

jobs:
  rust-ci:
    name: Rust CI
    runs-on: ubuntu-24.04
    timeout-minutes: 120
    steps:
      - uses: actions/checkout@v4
        with:
          persist-credentials: false

      - name: Install or reuse Nix
        run: ./.forgejo/scripts/install-nix.sh

      - name: Run Rust checks and tests
        run: |
          export PATH="/nix/var/nix/profiles/default/bin:$PATH"
          export XDG_STATE_HOME="${RUNNER_TEMP:-/tmp}/emc-state"
          mkdir -p "$XDG_STATE_HOME"
          nix develop --command just copyright-headers
          nix develop --command just fmt
          nix develop --command just clippy
          nix develop --command just test

  flake-check:
    name: Nix flake check
    runs-on: ubuntu-24.04
    timeout-minutes: 90
    steps:
      - uses: actions/checkout@v4
        with:
          persist-credentials: false

      - name: Install or reuse Nix
        run: ./.forgejo/scripts/install-nix.sh

      - name: Run flake check
        run: |
          export PATH="/nix/var/nix/profiles/default/bin:$PATH"
          nix flake check --print-build-logs

  semantic-review:
    name: Request auto_review semantic review
    if: ${{ github.event_name == 'pull_request' && github.event.action != 'closed' }}
    runs-on: ubuntu-24.04
    timeout-minutes: 10
    permissions:
      statuses: write
      pull-requests: read
    env:
      AUTO_REVIEW_GATEWAY_URL: ${{ vars.AUTO_REVIEW_GATEWAY_URL }}
      AR_CI_REVIEW_TOKEN: ${{ secrets.AR_CI_REVIEW_TOKEN }}
      IS_RELEASE_PR: ${{ startsWith(github.event.pull_request.head.ref, 'release-plz-') }}
    steps:
      # Automated release PRs (version bump + changelog regeneration) are
      # mechanical, but the auto_review metadata-quality gate is tuned for
      # feature PRs and repeatedly rejected release titles with contradictory
      # rationales. Skip the semantic review for release branches and
      # self-report the branch-protection-required `auto_review` status as
      # success so the required status checks pass. A human still approves the
      # release PR (branch protection requires one approval).
      - name: Self-report auto_review for automated release PRs
        if: ${{ env.IS_RELEASE_PR == 'true' }}
        run: |
          set -euo pipefail
          curl -fsS -X POST \
            -H "Authorization: token ${{ github.token }}" \
            -H "Content-Type: application/json" \
            --data '{"context":"auto_review","state":"success","description":"auto_review skipped for automated release PR"}' \
            "${{ github.server_url }}/api/v1/repos/${{ github.repository }}/statuses/${{ github.event.pull_request.head.sha }}"

      - name: Skip when auto_review configuration is not available
        if: ${{ env.IS_RELEASE_PR != 'true' && (env.AUTO_REVIEW_GATEWAY_URL == '' || env.AR_CI_REVIEW_TOKEN == '' || env.AUTO_REVIEW_GATEWAY_URL == github.server_url) }}
        run: |
          echo "auto_review semantic review skipped: repository variable AUTO_REVIEW_GATEWAY_URL must point at ar-gateway, secret AR_CI_REVIEW_TOKEN must match the gateway AR_CI_REVIEW_TOKEN, and the gateway URL must not be the Forgejo server URL"

      - name: Request auto_review review
        continue-on-error: true
        if: ${{ env.IS_RELEASE_PR != 'true' && env.AUTO_REVIEW_GATEWAY_URL != '' && env.AR_CI_REVIEW_TOKEN != '' && env.AUTO_REVIEW_GATEWAY_URL != github.server_url }}
        run: |
          set -euo pipefail
          json_payload='{"owner":"${{ github.repository_owner }}","repo":"${{ github.event.repository.name }}","pr_number":${{ github.event.pull_request.number }},"head_sha":"${{ github.event.pull_request.head.sha }}"}'
          response_file="$(mktemp)"
          status="$(curl -sS --connect-timeout 5 --max-time 30 -o "$response_file" -w '%{http_code}' -X POST \
            -H "Authorization: Bearer $AR_CI_REVIEW_TOKEN" \
            -H "Content-Type: application/json" \
            --data "$json_payload" \
            "${AUTO_REVIEW_GATEWAY_URL%/}/reviews/ci")"

          if [ "$status" -eq 401 ] || [ "$status" -eq 403 ]; then
            echo "auto_review semantic review authorization failed with HTTP $status; verify the AR_CI_REVIEW_TOKEN secret matches production AR_CI_REVIEW_TOKEN" >&2
            exit 1
          fi

          if [ "$status" -lt 200 ] || [ "$status" -ge 300 ]; then
            echo "auto_review semantic review request failed with HTTP $status" >&2
            cat "$response_file" >&2
            exit 1
          fi
