Just shippedBest skills for each job.See the picks →

ClaudeCI failureNot executed· 1 caveat

CI failure auto-fix: Claude pushes a fix branch when CI fails

When CI fails on a pull request, Claude reads the failure logs, makes a fix, and pushes it to a new branch for you to review. The upstream file warns that it runs PR code with write permissions, so use it only on trusted branches.

workflow_run: CI completed (failure)

How it works

From event to result

1
Trigger
GitHub starts a run when the workflow named CI finishes.
2
Agent
Claude Code, via anthropics/claude-code-action.
3
What it does
When CI fails on a pull request, Claude reads the failure logs, makes a fix, and pushes it to a new branch for you to review. The upstream file warns that it runs PR code with write permissions, so use it only on trusted branches.
4
What you get
This listing does not state a pull request or a comment. Read the prompt, and treat the result as not executed.

Setup

Where to paste this

  1. Create .github/workflows/claude-code-action-ci-failure-auto-fix.yml
  2. Paste the workflow below into that file. The notes beside the YAML are not part of the file.
  3. Add these repository secrets: GITHUB_TOKEN, ANTHROPIC_API_KEY. The file reads them as secrets.NAME. Do not paste the key into the YAML.

Let your agent do it

Copy a prompt for Claude Code, Codex, or Cursor.

Paste it into your coding agent in this repo. It does the setup and asks before anything leaves your machine.

Runs in GitHub Actions on your Claude Pro or Max plan through an OAuth token from claude setup-token. No API credits.

Set up the "CI failure auto-fix: Claude pushes a fix branch when CI fails" GitHub workflow from AgentFlows (https://agentflows.sh/flows/claude-code-action-ci-failure-auto-fix) so it runs on my Claude Pro or Max subscription instead of API credits.

Install these agent skills first. Download each SKILL.md from its source (respect its license) into .claude/skills/<name>/SKILL.md, or wherever this agent loads skills from:
- Debug: https://github.com/anthropics/knowledge-work-plugins/blob/main/engineering/skills/debug/SKILL.md (Apache-2.0), notes at https://agentflows.sh/skills/debug
- Iterate on a PR until CI passes and review feedback is addressed: https://github.com/getsentry/skills/tree/main/skills/iterate-pr (Apache-2.0), notes at https://agentflows.sh/skills/getsentry-iterate-pr

Save this file as .github/workflows/claude-code-action-ci-failure-auto-fix.yml:

```yaml
name: Auto Fix CI Failures

# ⚠️ SECURITY NOTE
#
# This workflow checks out the PR branch and runs build/test commands
# (npm, bun, etc.) against it with elevated permissions (contents:write,
# id-token:write). This means code from the PR branch executes in a
# trusted context with access to secrets and the ability to push to the
# repository.
#
# Only use this workflow in repositories where everyone with write access
# is fully trusted with these permissions. Do not use this in repositories
# that accept contributions from untrusted or semi-trusted collaborators.
#
# The pull_requests[0] check below limits this to same-repo PRs (fork PRs
# are excluded), but anyone who can push a branch to this repository can
# control what code runs here.

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
        env:
          HEAD_BRANCH: ${{ github.event.workflow_run.head_branch }}
          RUN_ID: ${{ github.run_id }}
        run: |
          SAFE_BRANCH=$(printf '%s' "$HEAD_BRANCH" | tr -cd 'a-zA-Z0-9/_.-')
          BRANCH_NAME="claude-auto-fix-ci-${SAFE_BRANCH}-${RUN_ID}"
          git checkout -b "$BRANCH_NAME"
          echo "branch_name=$BRANCH_NAME" >> "$GITHUB_OUTPUT"

      - name: Get CI failure details
        id: failure_details
        uses: actions/github-script@v7
        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:*)'"
```

It authenticates with CLAUDE_CODE_OAUTH_TOKEN. Tell me to run `claude setup-token` in my own terminal to create it, then run `gh secret set CLAUDE_CODE_OAUTH_TOKEN` and let me paste it. Never write the token into a file.

It runs on: workflow_run: CI completed (failure). Runs count against my subscription's usage limits, and GitHub Actions minutes still apply.

Show me the diff, then commit on a new branch and open a pull request.

The file

Workflow YAML

Copy the file as-is. The notes beside each block explain it.

.github/workflows/claude-code-action-ci-failure-auto-fix.yml

Name

The name GitHub shows in the Actions tab. The file path is under Where to paste this.

name: Auto Fix CI Failures# ⚠️ SECURITY NOTE## This workflow checks out the PR branch and runs build/test commands# (npm, bun, etc.) against it with elevated permissions (contents:write,# id-token:write). This means code from the PR branch executes in a# trusted context with access to secrets and the ability to push to the# repository.## Only use this workflow in repositories where everyone with write access# is fully trusted with these permissions. Do not use this in repositories# that accept contributions from untrusted or semi-trusted collaborators.## The pull_requests[0] check below limits this to same-repo PRs (fork PRs# are excluded), but anyone who can push a branch to this repository can# control what code runs here.

Trigger

GitHub starts a run when the workflow named CI finishes.

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

Permissions

This token may push commits, comment on pull requests and open them, read Actions logs, and comment on issues and change labels. Anything not listed is not granted.

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

Jobs

Each job is one runner. The steps inside it run top to bottom.

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

These steps run in order on that job.

    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        env:          HEAD_BRANCH: ${{ github.event.workflow_run.head_branch }}          RUN_ID: ${{ github.run_id }}        run: |          SAFE_BRANCH=$(printf '%s' "$HEAD_BRANCH" | tr -cd 'a-zA-Z0-9/_.-')          BRANCH_NAME="claude-auto-fix-ci-${SAFE_BRANCH}-${RUN_ID}"          git checkout -b "$BRANCH_NAME"          echo "branch_name=$BRANCH_NAME" >> "$GITHUB_OUTPUT"      - name: Get CI failure details        id: failure_details        uses: actions/github-script@v7        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

Agent

Runs Claude Code with anthropics/claude-code-action@v1. Inputs: prompt (the task); anthropic_api_key (the Claude API key secret); claude_args (Claude Code flags, including allowed tools).

        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) }}          anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}          claude_args: "--allowedTools 'Edit,MultiEdit,Write,Read,Glob,Grep,LS,Bash(git:*),Bash(bun:*),Bash(npm:*),Bash(npx:*),Bash(gh:*)'"

Keep going

More workflows

All workflows
  • ClaudePull request
    01

    Claude auto PR review

    Copied from the official Solutions Guide basic example (prompt shortened).

    pull_request: opened, synchronize

    Est. cost per run~$0.18Checked Oct 16, 2026

    Not executed
  • ClaudePull request
    02

    Claude PR review with progress tracking

    `track_progress: true` posts a checkbox tracking comment (per Solutions Guide).

    pull_request: opened, synchronize, ready_for_review, reopened

    Est. cost per run~$0.22Checked Oct 16, 2026

    Not executed
  • ClaudeComment
    03

    @claude mention assistant on issues and PRs

    No `prompt` → the action runs in tag/interactive mode and responds to the comment. `trigger_phrase` default is `@claude` (usage.md).

    issue_comment / pull_request_review_comment containing @claude

    Est. cost per run~$0.27Checked Oct 16, 2026

    Not executed· 1 caveat

Weekly

New picks, once a week.

Workflow changes, skill picks, and measured run costs. One email.

Emails are sent through Kit. Every email has an unsubscribe link.