name: PR Failure Codex Dispatch

on:
  workflow_run:
    workflows: ["PR-tests"]
    types: [completed]

jobs:
  codex_on_failure:
    if: >
      ${{ github.event.workflow_run.conclusion == 'failure' &&
          github.event.workflow_run.pull_requests &&
          github.event.workflow_run.pull_requests[0] &&
          !startsWith(github.event.workflow_run.head_commit.message, 'Fix CI failures for PR #') }}
    runs-on: ubuntu-latest
    permissions:
      contents: write
      pull-requests: write
      issues: write
      actions: read

    steps:
      - name: Resolve PR context
        id: pr_context
        env:
          PR_NUMBER: ${{ github.event.workflow_run.pull_requests[0].number }}
          GH_TOKEN: ${{ github.token }}
        run: |
          pr_author=$(gh api -H "Accept: application/vnd.github+json" \
            /repos/${{ github.repository }}/pulls/${PR_NUMBER} \
            --jq '.user.login')
          pr_head_repo=$(gh api -H "Accept: application/vnd.github+json" \
            /repos/${{ github.repository }}/pulls/${PR_NUMBER} \
            --jq '.head.repo.full_name')
          pr_head_branch=$(gh api -H "Accept: application/vnd.github+json" \
            /repos/${{ github.repository }}/pulls/${PR_NUMBER} \
            --jq '.head.ref')
          {
            echo "number=${PR_NUMBER}"
            echo "author=${pr_author}"
            echo "head_repo=${pr_head_repo}"
            echo "head_branch=${pr_head_branch}"
          } >> "$GITHUB_OUTPUT"

      - name: Comment on PR with failure info
        if: ${{ steps.pr_context.outputs.author == 'carlospolop' }}
        uses: actions/github-script@v7
        env:
          PR_NUMBER: ${{ steps.pr_context.outputs.number }}
          RUN_URL: ${{ github.event.workflow_run.html_url }}
          WORKFLOW_NAME: ${{ github.event.workflow_run.name }}
        with:
          github-token: ${{ github.token }}
          script: |
            const prNumber = Number(process.env.PR_NUMBER);
            const body = `PR #${prNumber} had a failing workflow "${process.env.WORKFLOW_NAME}".\n\nRun: ${process.env.RUN_URL}\n\nLaunching Codex to attempt a fix.`;
            await github.rest.issues.createComment({
              owner: context.repo.owner,
              repo: context.repo.repo,
              issue_number: prNumber,
              body,
            });

      - name: Checkout PR head
        if: ${{ steps.pr_context.outputs.author == 'carlospolop' }}
        uses: actions/checkout@v5
        with:
          repository: ${{ steps.pr_context.outputs.head_repo }}
          ref: ${{ github.event.workflow_run.head_sha }}
          fetch-depth: 0
          persist-credentials: true

      - name: Configure git author
        if: ${{ steps.pr_context.outputs.author == 'carlospolop' }}
        run: |
          git config user.name "codex-action"
          git config user.email "codex-action@users.noreply.github.com"

      - name: Fetch failure summary
        if: ${{ steps.pr_context.outputs.author == 'carlospolop' }}
        env:
          GH_TOKEN: ${{ github.token }}
          RUN_ID: ${{ github.event.workflow_run.id }}
        run: |
          gh api -H "Accept: application/vnd.github+json" \
            /repos/${{ github.repository }}/actions/runs/$RUN_ID/jobs \
            --paginate > /tmp/jobs.json
          python3 - <<'PY'
          import json

          data = json.load(open('/tmp/jobs.json'))
          lines = []
          for job in data.get('jobs', []):
            if job.get('conclusion') == 'failure':
              lines.append(f"Job: {job.get('name')} (id {job.get('id')})")
              lines.append(f"URL: {job.get('html_url')}")
              for step in job.get('steps', []):
                if step.get('conclusion') == 'failure':
                  lines.append(f"  Step: {step.get('name')}")
              lines.append("")

          summary = "\n".join(lines).strip() or "No failing job details found."
          with open('codex_failure_summary.txt', 'w') as handle:
            handle.write(summary)
          PY

      - name: Create Codex prompt
        if: ${{ steps.pr_context.outputs.author == 'carlospolop' }}
        env:
          PR_NUMBER: ${{ steps.pr_context.outputs.number }}
          RUN_URL: ${{ github.event.workflow_run.html_url }}
          HEAD_BRANCH: ${{ steps.pr_context.outputs.head_branch }}
        run: |
          {
            echo "You are fixing CI failures for PR #${PR_NUMBER} in ${{ github.repository }}."
            echo "The failing workflow run is: ${RUN_URL}"
            echo "The PR branch is: ${HEAD_BRANCH}"
            echo ""
            echo "Failure summary:"
            cat codex_failure_summary.txt
            echo ""
            echo "Please identify the cause, apply a easy, simple and minimal fix, and update files accordingly."
            echo "Run any fast checks you can locally (no network)."
            echo "Leave the repo in a state ready to commit as when you finish, it'll be automatically committed and pushed."
          } > codex_prompt.txt

      - name: Run Codex
        if: ${{ steps.pr_context.outputs.author == 'carlospolop' }}
        id: run_codex
        uses: openai/codex-action@v1
        with:
          openai-api-key: ${{ secrets.OPENAI_API_KEY }}
          prompt-file: codex_prompt.txt
          sandbox: workspace-write
          model: gpt-5.2-codex

      - name: Commit and push if changed
        if: ${{ steps.pr_context.outputs.author == 'carlospolop' }}
        env:
          TARGET_BRANCH: ${{ steps.pr_context.outputs.head_branch }}
          PR_NUMBER: ${{ steps.pr_context.outputs.number }}
        run: |
          if git diff --quiet; then
            echo "No changes to commit."
            exit 0
          fi
          rm -f codex_failure_summary.txt codex_prompt.txt
          git add -A
          git reset -- codex_failure_summary.txt codex_prompt.txt
          git commit -m "Fix CI failures for PR #${PR_NUMBER}"
          git push origin HEAD:${TARGET_BRANCH}

      - name: Comment with Codex result
        if: ${{ steps.pr_context.outputs.author == 'carlospolop' && steps.run_codex.outputs.final-message != '' }}
        uses: actions/github-script@v7
        env:
          PR_NUMBER: ${{ steps.pr_context.outputs.number }}
          CODEX_MESSAGE: ${{ steps.run_codex.outputs.final-message }}
        with:
          github-token: ${{ github.token }}
          script: |
            await github.rest.issues.createComment({
              owner: context.repo.owner,
              repo: context.repo.repo,
              issue_number: Number(process.env.PR_NUMBER),
              body: process.env.CODEX_MESSAGE,
            });
