Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 96 additions & 0 deletions .github/workflows/cgo.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1684,3 +1684,99 @@ jobs:
name: safe-outputs-conformance-report
path: conformance-output.txt
retention-days: 7

notify-failure:
name: Notify on CGO Failure
runs-on: ubuntu-latest
timeout-minutes: 5
if: always() && github.ref == 'refs/heads/main'
needs:
- test
- canary-go
- build
- build-wasm
- validate-yaml
- bench
- check-validator-sizes
- lint-go
- actions-build
- fuzz
- security
- security-scan
- mcp-server-compile-test
- cross-platform-build
- alpine-container-test
- safe-outputs-conformance
permissions:
issues: write
steps:
- name: Check for job failures and create issue
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9
with:
script: |
const needs = ${{ toJSON(needs) }};
const failedJobs = Object.entries(needs)
.filter(([, job]) => job.result === 'failure')
.map(([name]) => name);

if (failedJobs.length === 0) {
core.info('No jobs failed. Nothing to do.');
return;
}

core.info(`Failed jobs: ${failedJobs.join(', ')}`);

// Check for an existing open CGO failure issue to avoid duplicates
const existingIssues = await github.rest.issues.listForRepo({
owner: context.repo.owner,
repo: context.repo.repo,
labels: 'cgo-failure',
state: 'open',
});

if (existingIssues.data.length > 0) {
core.info(`Existing CGO failure issue #${existingIssues.data[0].number} is still open. Skipping.`);
Comment on lines +1736 to +1738
Copy link

Copilot AI Apr 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

github.rest.issues.listForRepo returns both issues and pull requests. If a PR is ever labeled cgo-failure, this deduplication check will incorrectly suppress issue creation. Filter out items with the pull_request field (or use a search query that excludes PRs) before deciding to skip creating a new issue.

Suggested change
if (existingIssues.data.length > 0) {
core.info(`Existing CGO failure issue #${existingIssues.data[0].number} is still open. Skipping.`);
const existingOpenIssues = existingIssues.data.filter(item => !item.pull_request);
if (existingOpenIssues.length > 0) {
core.info(`Existing CGO failure issue #${existingOpenIssues[0].number} is still open. Skipping.`);

Copilot uses AI. Check for mistakes.
return;
}

// Ensure required labels exist, creating them if missing
for (const [label, color] of [['cookie', 'e4e669'], ['cgo-failure', 'b60205']]) {
try {
await github.rest.issues.getLabel({ owner: context.repo.owner, repo: context.repo.repo, name: label });
} catch (e) {
if (e.status === 404) {
await github.rest.issues.createLabel({ owner: context.repo.owner, repo: context.repo.repo, name: label, color });
Copy link

Copilot AI Apr 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The getLabel error handling only creates labels on 404, but silently ignores any other API error (rate limit, permissions, transient failures). This can hide the root cause and lead to a later, harder-to-diagnose failure when creating the issue with missing labels. Re-throw or core.setFailed for non-404 errors so the workflow fails with a clear reason.

Suggested change
await github.rest.issues.createLabel({ owner: context.repo.owner, repo: context.repo.repo, name: label, color });
await github.rest.issues.createLabel({ owner: context.repo.owner, repo: context.repo.repo, name: label, color });
} else {
throw new Error(`Failed to verify label "${label}": ${e.message}`);

Copilot uses AI. Check for mistakes.
}
}
}

const runUrl = `https://github.com/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`;
const expiresAt = new Date(Date.now() + 4 * 60 * 60 * 1000).toISOString();

const body = [
`## CGO Workflow Failure`,
``,
`Workflow run [#${context.runNumber}](${runUrl}) on the \`main\` branch completed with failed jobs.`,
``,
`| Field | Value |`,
`| --- | --- |`,
`| Run ID | ${context.runId} |`,
`| Commit | ${context.sha} |`,
`| Expires | ${expiresAt} |`,
``,
`## Failed Jobs`,
``,
...failedJobs.map(name => `- \`${name}\``),
``,
`> This issue expires at ${expiresAt}. Please investigate the failed jobs above and close once resolved.`,
].join('\n');

const issue = await github.rest.issues.create({
owner: context.repo.owner,
repo: context.repo.repo,
title: `[CGO] Workflow failure on main - Run #${context.runNumber}`,
body,
labels: ['cookie', 'cgo-failure'],
});

core.info(`Created issue #${issue.data.number}: ${issue.data.html_url}`);
Loading