Pin Bump CI Handler #126
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Pin Bump CI Handler | |
| on: | |
| workflow_run: | |
| workflows: ["trunk"] | |
| types: [completed] | |
| jobs: | |
| handle-ci-result: | |
| if: github.repository_owner == 'pytorch' | |
| runs-on: ubuntu-latest | |
| environment: update-commit-hash | |
| permissions: | |
| pull-requests: write | |
| issues: write | |
| steps: | |
| - uses: actions/github-script@v7 | |
| with: | |
| github-token: ${{ secrets.UPDATEBOT_TOKEN }} | |
| script: | | |
| const { owner, repo } = context.repo; | |
| const workflowRun = context.payload.workflow_run; | |
| const conclusion = workflowRun.conclusion; | |
| const runUrl = workflowRun.html_url; | |
| const prs = workflowRun.pull_requests; | |
| if (!prs || prs.length === 0) { | |
| console.log('No PRs associated with this workflow run. Skipping.'); | |
| return; | |
| } | |
| const prNumber = prs[0].number; | |
| const pr = await github.rest.pulls.get({ owner, repo, pull_number: prNumber }); | |
| const isPinBump = pr.data.labels.some(l => l.name === 'ci/pytorch-pin-bump'); | |
| if (!isPinBump) { | |
| console.log(`PR #${prNumber} is not a pin bump PR. Skipping.`); | |
| return; | |
| } | |
| const allowedAuthors = new Set(['pytorchbot', 'pytorchupdatebot', 'facebook-github-bot']); | |
| if (!allowedAuthors.has(pr.data.user.login)) { | |
| console.log(`PR #${prNumber} was created by ${pr.data.user.login}, not an allowed automation account. Skipping.`); | |
| return; | |
| } | |
| console.log(`Pin bump PR #${prNumber}, trunk concluded: ${conclusion}`); | |
| const comments = await github.rest.issues.listComments({ | |
| owner, repo, issue_number: prNumber, per_page: 100 | |
| }); | |
| const fixAttempts = comments.data.filter( | |
| c => c.body && c.body.startsWith('@claude [ci-fix-attempt') | |
| ).length; | |
| if (conclusion === 'success') { | |
| const note = fixAttempts > 0 | |
| ? `Claude fixed CI failures in ${fixAttempts} attempt(s).` | |
| : 'CI passed on the first try.'; | |
| await github.rest.issues.createComment({ | |
| owner, repo, issue_number: prNumber, | |
| body: `## CI Passed\n\nAll trunk CI checks have passed on this pin bump PR. ${note}\n\n**This PR is ready for human review and merge.**\n\ncc @jakeszwe` | |
| }); | |
| return; | |
| } | |
| if (conclusion !== 'failure') { | |
| console.log(`Trunk concluded with "${conclusion}" (not failure). Skipping.`); | |
| return; | |
| } | |
| if (fixAttempts >= 3) { | |
| await github.rest.issues.createComment({ | |
| owner, repo, issue_number: prNumber, | |
| body: [ | |
| '## Automated Fix Attempts Exhausted', | |
| '', | |
| `CI is still failing after ${fixAttempts} automated fix attempt(s).`, | |
| `Failed trunk run: ${runUrl}`, | |
| '', | |
| 'This pin bump likely requires human intervention. Common causes:', | |
| '- BC-breaking API changes in PyTorch that need design discussion', | |
| '- New dependencies or build system changes', | |
| '- Test infrastructure issues unrelated to the pin bump', | |
| '', | |
| 'cc @jakeszwe' | |
| ].join('\n') | |
| }); | |
| return; | |
| } | |
| const attemptNum = fixAttempts + 1; | |
| await github.rest.issues.createComment({ | |
| owner, repo, issue_number: prNumber, | |
| body: [ | |
| `@claude [ci-fix-attempt ${attemptNum}/3]`, | |
| '', | |
| `The \`trunk\` CI workflow has failed on this automated PyTorch pin bump PR.`, | |
| `Failed run: ${runUrl}`, | |
| '', | |
| 'Please:', | |
| '1. Read the Dr. CI comment on this PR for a summary of which jobs failed and whether they are flaky. Ignore failures marked as FLAKY.', | |
| '2. Use your CI tools to download the failure logs for the non-flaky failing jobs', | |
| '3. Identify the root cause of the failure', | |
| '4. If this is a build or test failure caused by PyTorch API changes, fix the ExecuTorch code to be compatible with the new PyTorch version', | |
| '5. If this is a c10 header sync issue, the headers have already been synced by the pin bump script — the issue is likely in ExecuTorch code that uses those headers', | |
| '6. Run `lintrunner -a` on any files you change', | |
| '7. Push your fix as a new commit to this PR branch', | |
| '', | |
| 'Important constraints:', | |
| '- Do NOT modify torch_pin.py or .ci/docker/ci_commit_pins/pytorch.txt — the pin itself is correct', | |
| '- Do NOT modify files under runtime/core/portable_type/c10/ unless the sync introduced a new API that ExecuTorch code needs to adapt to', | |
| '- Focus on fixing ExecuTorch code to be compatible with the new PyTorch APIs', | |
| '- If this is a major BC-breaking change that requires architectural discussion, say so clearly and stop — do not attempt a fix' | |
| ].join('\n') | |
| }); |