name: Pyrefly Type Coverage

on:
  pull_request:
    paths:
      - 'api/**/*.py'

permissions:
  contents: read

jobs:
  pyrefly-type-coverage:
    runs-on: depot-ubuntu-24.04
    permissions:
      contents: read
      issues: write
      pull-requests: write
    steps:
      - name: Checkout PR branch
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
        with:
          fetch-depth: 0

      - name: Setup Python & UV
        uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
        with:
          enable-cache: true

      - name: Install dependencies
        run: uv sync --project api --dev

      - name: Run pyrefly report on PR branch
        run: |
          uv run --directory api --dev pyrefly report 2>/dev/null > /tmp/pyrefly_report_pr.tmp && \
            mv /tmp/pyrefly_report_pr.tmp /tmp/pyrefly_report_pr.json || \
            echo '{}' > /tmp/pyrefly_report_pr.json

      - name: Save helper script from base branch
        run: |
          git show ${{ github.event.pull_request.base.sha }}:api/libs/pyrefly_type_coverage.py > /tmp/pyrefly_type_coverage.py 2>/dev/null \
            || cp api/libs/pyrefly_type_coverage.py /tmp/pyrefly_type_coverage.py

      - name: Checkout base branch
        run: git checkout ${{ github.base_ref }}

      - name: Run pyrefly report on base branch
        run: |
          uv run --directory api --dev pyrefly report 2>/dev/null > /tmp/pyrefly_report_base.tmp && \
            mv /tmp/pyrefly_report_base.tmp /tmp/pyrefly_report_base.json || \
            echo '{}' > /tmp/pyrefly_report_base.json

      - name: Generate coverage comparison
        id: coverage
        run: |
          comment_body="$(uv run --directory api python /tmp/pyrefly_type_coverage.py \
            --base /tmp/pyrefly_report_base.json \
            < /tmp/pyrefly_report_pr.json)"

          {
            echo "### Pyrefly Type Coverage"
            echo ""
            echo "$comment_body"
          } | tee -a "$GITHUB_STEP_SUMMARY" > /tmp/type_coverage_comment.md

          # Save structured data for the fork-PR comment workflow
          cp /tmp/pyrefly_report_pr.json pr_report.json
          cp /tmp/pyrefly_report_base.json base_report.json
          # Keep fork-PR comments correct while the trusted workflow_run job is
          # still using the default-branch renderer, which resolves --base from api/.
          cp /tmp/pyrefly_report_base.json api/base_report.json

      - name: Save PR number
        run: |
          echo ${{ github.event.pull_request.number }} > pr_number.txt

      - name: Upload type coverage artifact
        uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
        with:
          name: pyrefly_type_coverage
          path: |
            pr_report.json
            base_report.json
            api/base_report.json
            pr_number.txt

      - name: Comment PR with type coverage
        if: ${{ github.event.pull_request.head.repo.full_name == github.repository }}
        uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
        with:
          github-token: ${{ secrets.GITHUB_TOKEN }}
          script: |
            const fs = require('fs');
            const marker = '### Pyrefly Type Coverage';
            let body;
            try {
              body = fs.readFileSync('/tmp/type_coverage_comment.md', { encoding: 'utf8' });
            } catch {
              body = `${marker}\n\n_Coverage report unavailable._`;
            }
            const prNumber = context.payload.pull_request.number;

            // Update existing comment if one exists, otherwise create new
            const { data: comments } = await github.rest.issues.listComments({
              issue_number: prNumber,
              owner: context.repo.owner,
              repo: context.repo.repo,
            });
            const existing = comments.find(c => c.body.startsWith(marker));

            if (existing) {
              await github.rest.issues.updateComment({
                comment_id: existing.id,
                owner: context.repo.owner,
                repo: context.repo.repo,
                body,
              });
            } else {
              await github.rest.issues.createComment({
                issue_number: prNumber,
                owner: context.repo.owner,
                repo: context.repo.repo,
                body,
              });
            }
