Skip to content
132 changes: 132 additions & 0 deletions .github/workflows/claude-ci-autofix.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
name: Claude CI Auto-Fix

on:
workflow_run:
workflows: ["test", "build", "lint"]
types:
- completed

permissions:
contents: write
pull-requests: write
actions: read
issues: write

jobs:
auto-fix:
# Only run on PR branches that failed, skip branches created by this workflow
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: Check actor is a maintainer
id: check-permission
uses: actions/github-script@v7
with:
script: |
const prNumber = context.payload.workflow_run.pull_requests[0]?.number;
if (!prNumber) {
core.notice('Skipping auto-fix: no associated PR found');
return false;
}
const { data: pr } = await github.rest.pulls.get({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: prNumber,
});
const allowed = ['OWNER', 'MEMBER', 'COLLABORATOR'].includes(pr.author_association);
if (!allowed) {
core.notice(`Skipping auto-fix: PR author association is ${pr.author_association}`);
}
return allowed;

- name: Checkout code
if: steps.check-permission.outputs.result == 'true'
uses: actions/checkout@v4
with:
ref: ${{ github.event.workflow_run.head_branch }}
fetch-depth: 0
token: ${{ secrets.GITHUB_TOKEN }}

- name: Setup git identity
if: steps.check-permission.outputs.result == 'true'
run: |
git config --global user.email "claude[bot]@users.noreply.github.com"
git config --global user.name "claude[bot]"

- name: Create fix branch
if: steps.check-permission.outputs.result == 'true'
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

- name: Get CI failure details
if: steps.check-permission.outputs.result == 'true'
id: failure_details
uses: actions/github-script@v7
with:
script: |
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.slice(0, 3)) {
try {
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.substring(0, 8000) });
} catch (e) {
errorLogs.push({ jobName: job.name, logs: `(could not fetch logs: ${e.message})` });
}
}

return {
runUrl: '${{ github.event.workflow_run.html_url }}',
workflowName: '${{ github.event.workflow_run.name }}',
failedJobs: failedJobs.map(j => j.name),
errorLogs: errorLogs
};

- name: Fix CI failures with Claude
if: steps.check-permission.outputs.result == 'true'
uses: anthropics/claude-code-action@v1
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
github_token: ${{ secrets.GITHUB_TOKEN }}
claude_args: "--allowedTools 'Edit,MultiEdit,Write,Read,Glob,Grep,LS,Bash(git:*),Bash(cargo:*),Bash(gh:*)'"
prompt: |
The ${{ github.event.workflow_run.name }} CI workflow failed on branch
`${{ github.event.workflow_run.head_branch }}` (PR #${{ github.event.workflow_run.pull_requests[0].number }}).

Failed jobs: ${{ join(fromJSON(steps.failure_details.outputs.result).failedJobs, ', ') }}
CI run URL: ${{ fromJSON(steps.failure_details.outputs.result).runUrl }}

Error logs:
${{ toJSON(fromJSON(steps.failure_details.outputs.result).errorLogs) }}

miden-base is a Rust project. Please:
1. Analyse the failure logs above to identify the root cause.
2. Make the minimal code changes needed to fix the failure (compilation errors,
test failures, lint errors, etc.). Do NOT change unrelated code.
3. Commit the fixes to the current branch (`${{ steps.branch.outputs.branch_name }}`).
4. Open a PR against `${{ github.event.workflow_run.head_branch }}` with:
- Title: "fix(ci): auto-fix ${{ github.event.workflow_run.name }} failures on ${{ github.event.workflow_run.head_branch }}"
- Body explaining what was changed and why.
5. Comment on PR #${{ github.event.workflow_run.pull_requests[0].number }} linking
to the new fix PR.

If the failure is not something you can fix automatically (e.g. infrastructure issue,
missing secret, upstream breakage), just post a comment on the PR explaining what
you found and why it cannot be auto-fixed.
44 changes: 44 additions & 0 deletions .github/workflows/claude-pr-triage.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
name: Claude PR Triage

on:
pull_request:
types: [opened, edited, reopened, synchronize]

jobs:
triage-pr:
runs-on: ubuntu-latest
timeout-minutes: 10
permissions:
contents: read
pull-requests: write

steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 1

- name: Run Claude PR Triage
uses: anthropics/claude-code-action@v1
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
github_token: ${{ secrets.GITHUB_TOKEN }}
allowed_non_write_users: "*"
prompt: |
Triage the following pull request in the miden-base repository by adding appropriate labels.

Repository: ${{ github.repository }}
PR number: ${{ github.event.pull_request.number }}

Steps:
1. Run `gh label list` to see all available labels.
2. Run `gh pr view ${{ github.event.pull_request.number }} --json title,body,files` to inspect the PR.
3. Apply the most relevant labels using `gh pr edit ${{ github.event.pull_request.number }} --add-label <label>`.

Label selection guidance for miden-base:
- Type: bug, enhancement, refactor, documentation, chore, breaking-change
- Area: based on changed files (accounts, notes, transactions, block-kernel, crypto, etc.)
- Maintainer: add "pr-from-maintainers" if the PR author's association is OWNER,
MEMBER, or COLLABORATOR. The author's association is: ${{ github.event.pull_request.author_association }}

Only add labels that exist in the repo. Do not post any comments.
67 changes: 67 additions & 0 deletions .github/workflows/claude.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
name: Claude Code

on:
issue_comment:
types: [created]
pull_request_review_comment:
types: [created]
issues:
types: [opened, assigned]
pull_request_review:
types: [submitted]

jobs:
claude:
if: |
(github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) ||
(github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) ||
(github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude')) ||
(github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude')))
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: read
issues: read
id-token: write
actions: read # Required for Claude to read CI results on PRs
steps:
- name: Check actor is a maintainer
id: check-permission
uses: actions/github-script@v7
with:
script: |
const association =
context.payload.comment?.author_association ||
context.payload.review?.author_association ||
context.payload.issue?.author_association;
const allowed = ['OWNER', 'MEMBER', 'COLLABORATOR'].includes(association);
if (!allowed) {
core.notice(`Skipping: author association is ${association}`);
}
return allowed;

- name: Checkout repository
if: steps.check-permission.outputs.result == 'true'
uses: actions/checkout@v4
with:
fetch-depth: 1

- name: Run Claude Code
if: steps.check-permission.outputs.result == 'true'
id: claude
uses: anthropics/claude-code-action@v1
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}

# This is an optional setting that allows Claude to read CI results on PRs
additional_permissions: |
actions: read

# Optional: Give a custom prompt to Claude. If this is not specified, Claude will perform the instructions specified in the comment that tagged it.
# prompt: 'Update the pull request description to include a summary of changes.'

# Optional: Add claude_args to customize behavior and configuration
# See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md
# or https://code.claude.com/docs/en/cli-reference for available options
# claude_args: '--allowed-tools Bash(gh pr:*)'

Loading