Skip to content

Agent CI Feedback #2296

Agent CI Feedback

Agent CI Feedback #2296

name: Agent CI Feedback
on:
workflow_run:
workflows: ["CI", "PR Validation"]
types: [completed]
permissions:
pull-requests: write
issues: write
actions: read
jobs:
notify-agent:
name: Notify Agent of CI Failure
if: >-
vars.AGENT_ENABLED == 'true' &&
github.event.workflow_run.conclusion == 'failure' &&
github.event.workflow_run.event == 'pull_request'
runs-on: ubuntu-latest
steps:
- name: Generate App token
id: app-token
uses: actions/create-github-app-token@v3
with:
app-id: ${{ secrets.AGENT_APP_ID }}
private-key: ${{ secrets.AGENT_APP_PRIVATE_KEY }}
- name: Post CI failure feedback to agent PR
uses: actions/github-script@v9
with:
github-token: ${{ steps.app-token.outputs.token }}
script: |
const runId = context.payload.workflow_run.id;
const workflowName = context.payload.workflow_run.name;
// Get the PR associated with this workflow run
const { data: { pull_requests: prs } } = await github.rest.actions.getWorkflowRun({
owner: context.repo.owner,
repo: context.repo.repo,
run_id: runId
});
if (!prs || prs.length === 0) {
core.info('No PR associated with this workflow run');
return;
}
const prNumber = prs[0].number;
// Get the PR to check if it's an agent PR
const { data: pr } = await github.rest.pulls.get({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: prNumber
});
if (!pr.head.ref.startsWith('agent/')) {
core.info(`PR #${prNumber} is not an agent PR (branch: ${pr.head.ref})`);
return;
}
// Count existing CI feedback rounds to prevent infinite loops
const { data: comments } = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: prNumber
});
const ciFixRounds = comments.filter(c =>
c.body.includes('<!-- agent-ci-fix-round')
).length;
if (ciFixRounds >= 2) {
core.info(`PR #${prNumber} already has ${ciFixRounds} CI fix rounds, leaving for human review`);
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: prNumber,
body: `<!-- agent-ci-fix-round: ${ciFixRounds + 1} -->\n\nThe **${workflowName}** workflow has failed ${ciFixRounds + 1} times on this agent PR. Remaining CI issues require human review.\n\n[View failed run](${context.payload.workflow_run.html_url})`
});
return;
}
// Get failed jobs for context
const { data: { jobs } } = await github.rest.actions.listJobsForWorkflowRun({
owner: context.repo.owner,
repo: context.repo.repo,
run_id: runId,
filter: 'latest'
});
const failedJobs = jobs
.filter(j => j.conclusion === 'failure')
.map(j => `- **${j.name}**: [view logs](${j.html_url})`)
.join('\n');
const round = ciFixRounds + 1;
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: prNumber,
body: `<!-- agent-ci-fix-round: ${round} -->\n\n@goudengine-agent The **${workflowName}** workflow failed on this PR (round ${round}/2). Please investigate and fix the failures.\n\n### Failed jobs\n${failedJobs || '_No individual job failures found — check the workflow run._'}\n\n[View full run](${context.payload.workflow_run.html_url})`
});
core.info(`Posted CI failure feedback for PR #${prNumber} (round ${round})`);