name: Auto Fix CI Failures

on:
  workflow_run:
    workflows: ["CI"]
    types:
      - completed

permissions:
  contents: write
  pull-requests: write
  actions: read
  issues: write
  id-token: write # Required for OIDC token exchange

jobs:
  auto-fix:
    if: |
      github.event.workflow_run.conclusion == 'failure' &&
      github.event.workflow_run.pull_requests[0] &&
      !startsWith(github.event.workflow_run.head_branch, 'claude-auto-fix-ci-')
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v6
        with:
          ref: ${{ github.event.workflow_run.head_branch }}
          fetch-depth: 0
          token: ${{ secrets.GITHUB_TOKEN }}

      - name: Setup git identity
        run: |
          git config --global user.email "claude[bot]@users.noreply.github.com"
          git config --global user.name "claude[bot]"

      - name: Create fix branch
        id: branch
        run: |
          BRANCH_NAME="claude-auto-fix-ci-${{ github.event.workflow_run.head_branch }}-${{ github.run_id }}"
          git checkout -b "$BRANCH_NAME"
          echo "branch_name=$BRANCH_NAME" >> $GITHUB_OUTPUT

      # Backend Python/Poetry setup (so Claude can run linting/tests)
      - name: Set up Python
        uses: actions/setup-python@v5
        with:
          python-version: "3.11"

      - name: Set up Python dependency cache
        uses: actions/cache@v5
        with:
          path: ~/.cache/pypoetry
          key: poetry-${{ runner.os }}-${{ hashFiles('autogpt_platform/backend/poetry.lock') }}

      - name: Install Poetry
        run: |
          cd autogpt_platform/backend
          HEAD_POETRY_VERSION=$(python3 ../../.github/workflows/scripts/get_package_version_from_lockfile.py poetry)
          curl -sSL https://install.python-poetry.org | POETRY_VERSION=$HEAD_POETRY_VERSION python3 -
          echo "$HOME/.local/bin" >> $GITHUB_PATH

      - name: Install Python dependencies
        working-directory: autogpt_platform/backend
        run: poetry install

      - name: Generate Prisma Client
        working-directory: autogpt_platform/backend
        run: poetry run prisma generate && poetry run gen-prisma-stub

      # Frontend Node.js/pnpm setup (so Claude can run linting/tests)
      - name: Enable corepack
        run: corepack enable

      - name: Set up Node.js
        uses: actions/setup-node@v6
        with:
          node-version: "22"
          cache: "pnpm"
          cache-dependency-path: autogpt_platform/frontend/pnpm-lock.yaml

      - name: Install JavaScript dependencies
        working-directory: autogpt_platform/frontend
        run: pnpm install --frozen-lockfile

      - name: Get CI failure details
        id: failure_details
        uses: actions/github-script@v8
        with:
          script: |
            const run = await github.rest.actions.getWorkflowRun({
              owner: context.repo.owner,
              repo: context.repo.repo,
              run_id: ${{ github.event.workflow_run.id }}
            });

            const jobs = await github.rest.actions.listJobsForWorkflowRun({
              owner: context.repo.owner,
              repo: context.repo.repo,
              run_id: ${{ github.event.workflow_run.id }}
            });

            const failedJobs = jobs.data.jobs.filter(job => job.conclusion === 'failure');

            let errorLogs = [];
            for (const job of failedJobs) {
              const logs = await github.rest.actions.downloadJobLogsForWorkflowRun({
                owner: context.repo.owner,
                repo: context.repo.repo,
                job_id: job.id
              });
              errorLogs.push({
                jobName: job.name,
                logs: logs.data
              });
            }

            return {
              runUrl: run.data.html_url,
              failedJobs: failedJobs.map(j => j.name),
              errorLogs: errorLogs
            };

      - name: Fix CI failures with Claude
        id: claude
        uses: anthropics/claude-code-action@v1
        with:
          prompt: |
            /fix-ci 
            Failed CI Run: ${{ fromJSON(steps.failure_details.outputs.result).runUrl }}
            Failed Jobs: ${{ join(fromJSON(steps.failure_details.outputs.result).failedJobs, ', ') }}
            PR Number: ${{ github.event.workflow_run.pull_requests[0].number }}
            Branch Name: ${{ steps.branch.outputs.branch_name }}
            Base Branch: ${{ github.event.workflow_run.head_branch }}
            Repository: ${{ github.repository }}

            Error logs:
            ${{ toJSON(fromJSON(steps.failure_details.outputs.result).errorLogs) }}
          claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
          claude_args: "--allowedTools 'Edit,MultiEdit,Write,Read,Glob,Grep,LS,Bash(git:*),Bash(bun:*),Bash(npm:*),Bash(npx:*),Bash(gh:*)'"
