|
| 1 | +# Auto-fix build failures using Copilot agent |
| 2 | +# |
| 3 | +# Triggers when the staging CI workflow completes with a failure. |
| 4 | +# Extracts error logs and opens an issue with structured error context |
| 5 | +# that can be picked up by Copilot Workspace or a custom agent. |
| 6 | +# |
| 7 | +# To enable full agentic auto-fix (create PRs automatically), set the |
| 8 | +# COPILOT_API_KEY secret and uncomment the auto-fix step. |
| 9 | + |
| 10 | +name: Auto-Fix Build Failures |
| 11 | + |
| 12 | +on: |
| 13 | + workflow_run: |
| 14 | + workflows: ["Staging"] |
| 15 | + types: [completed] |
| 16 | + |
| 17 | +permissions: |
| 18 | + contents: read |
| 19 | + issues: write |
| 20 | + actions: read |
| 21 | + |
| 22 | +jobs: |
| 23 | + detect-and-report: |
| 24 | + if: ${{ github.event.workflow_run.conclusion == 'failure' }} |
| 25 | + runs-on: ubuntu-24.04 |
| 26 | + |
| 27 | + steps: |
| 28 | + - name: Collect failed job logs |
| 29 | + id: logs |
| 30 | + env: |
| 31 | + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} |
| 32 | + run: | |
| 33 | + RUN_ID=${{ github.event.workflow_run.id }} |
| 34 | + echo "run_id=$RUN_ID" >> "$GITHUB_OUTPUT" |
| 35 | +
|
| 36 | + # Get failed jobs |
| 37 | + FAILED_JOBS=$(gh api "repos/${{ github.repository }}/actions/runs/$RUN_ID/jobs" \ |
| 38 | + --jq '.jobs[] | select(.conclusion == "failure") | .id') |
| 39 | +
|
| 40 | + ERROR_LOG="" |
| 41 | + for JOB_ID in $FAILED_JOBS; do |
| 42 | + JOB_NAME=$(gh api "repos/${{ github.repository }}/actions/jobs/$JOB_ID" --jq '.name') |
| 43 | + echo "Fetching logs for: $JOB_NAME (job $JOB_ID)" |
| 44 | +
|
| 45 | + # Download and extract error lines |
| 46 | + JOB_ERRORS=$(gh api "repos/${{ github.repository }}/actions/jobs/$JOB_ID/logs" 2>/dev/null \ |
| 47 | + | grep -i "error:" | head -20 || echo "(no error lines found)") |
| 48 | +
|
| 49 | + ERROR_LOG="${ERROR_LOG} |
| 50 | + ### ${JOB_NAME} |
| 51 | + \`\`\` |
| 52 | + ${JOB_ERRORS} |
| 53 | + \`\`\` |
| 54 | + " |
| 55 | + done |
| 56 | +
|
| 57 | + # Write to file (avoid GITHUB_OUTPUT multiline issues) |
| 58 | + echo "$ERROR_LOG" > /tmp/error_log.md |
| 59 | +
|
| 60 | + - name: Check for existing auto-fix issue |
| 61 | + id: existing |
| 62 | + env: |
| 63 | + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} |
| 64 | + run: | |
| 65 | + COUNT=$(gh issue list -R "${{ github.repository }}" \ |
| 66 | + --label "auto-fix" --state open --json number --jq 'length') |
| 67 | + echo "open_count=$COUNT" >> "$GITHUB_OUTPUT" |
| 68 | +
|
| 69 | + - name: Create or update issue |
| 70 | + if: steps.existing.outputs.open_count == '0' |
| 71 | + env: |
| 72 | + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} |
| 73 | + run: | |
| 74 | + RUN_URL="https://github.com/${{ github.repository }}/actions/runs/${{ steps.logs.outputs.run_id }}" |
| 75 | + COMMIT_SHA="${{ github.event.workflow_run.head_sha }}" |
| 76 | + SHORT_SHA="${COMMIT_SHA:0:7}" |
| 77 | +
|
| 78 | + BODY="## Build Failure Auto-Detected |
| 79 | +
|
| 80 | + **Run:** [#${{ steps.logs.outputs.run_id }}](${RUN_URL}) |
| 81 | + **Commit:** [\`${SHORT_SHA}\`](https://github.com/${{ github.repository }}/commit/${COMMIT_SHA}) |
| 82 | + **Branch:** \`${{ github.event.workflow_run.head_branch }}\` |
| 83 | +
|
| 84 | + ## Error Summary |
| 85 | +
|
| 86 | + $(cat /tmp/error_log.md) |
| 87 | +
|
| 88 | + --- |
| 89 | + _This issue was automatically created by the auto-fix workflow. |
| 90 | + Use Copilot Workspace or \`@github-copilot\` to suggest a fix._ |
| 91 | + " |
| 92 | +
|
| 93 | + gh issue create -R "${{ github.repository }}" \ |
| 94 | + --title "CI Build Failure on ${SHORT_SHA}" \ |
| 95 | + --body "$BODY" \ |
| 96 | + --label "auto-fix,bug" |
0 commit comments