Skip to content

Commit 15b8db8

Browse files
Copilotpelikhan
andauthored
Create issues with agentic instructions when workflows need recompilation (#9277)
* Initial plan * Add check_workflow_recompile_needed.cjs and update maintenance workflow - Created JavaScript script to check for outdated workflows and create issues - Updated maintenance_workflow.go to use the new JavaScript script - Added comprehensive tests for the new functionality - Script searches for existing issues to avoid duplicates - Creates issues with agentic instructions for GitHub Copilot Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> * Format JavaScript files with prettier Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> * Use sparse checkout of .github folder with persist-credentials: false Updated the compile-workflows job checkout step to use sparse-checkout for .github folder instead of full repository checkout, and added persist-credentials: false for security. Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> * Update checkout strategy: full repo in dev mode, sparse .github in release mode In dev mode, checkout the entire repository (needed for building). In release mode, use sparse checkout of only .github folder. Both modes use persist-credentials: false for security. Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> Co-authored-by: Peli de Halleux <pelikhan@users.noreply.github.com>
1 parent 800e166 commit 15b8db8

File tree

4 files changed

+421
-23
lines changed

4 files changed

+421
-23
lines changed

.github/workflows/agentics-maintenance.yml

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -95,9 +95,13 @@ jobs:
9595
runs-on: ubuntu-latest
9696
permissions:
9797
contents: read
98+
issues: write
9899
steps:
99100
- name: Checkout repository
100101
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
102+
with:
103+
persist-credentials: false
104+
101105

102106
- name: Setup Go
103107
uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0
@@ -113,17 +117,19 @@ jobs:
113117
./gh-aw compile --validate --verbose
114118
echo "✓ All workflows compiled successfully"
115119
116-
- name: Check for out-of-sync workflows
117-
run: |
118-
if git diff --exit-code .github/workflows/*.lock.yml; then
119-
echo "✓ All workflow lock files are up to date"
120-
else
121-
echo "::error::Some workflow lock files are out of sync. Run 'make recompile' locally."
122-
echo "::group::Diff of out-of-sync files"
123-
git diff .github/workflows/*.lock.yml
124-
echo "::endgroup::"
125-
exit 1
126-
fi
120+
- name: Setup Scripts
121+
uses: ./actions/setup
122+
with:
123+
destination: /tmp/gh-aw/actions
124+
125+
- name: Check for out-of-sync workflows and create issue if needed
126+
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
127+
with:
128+
script: |
129+
const { setupGlobals } = require('/tmp/gh-aw/actions/setup_globals.cjs');
130+
setupGlobals(core, github, context, exec, io);
131+
const { main } = require('/tmp/gh-aw/actions/check_workflow_recompile_needed.cjs');
132+
await main();
127133
128134
zizmor-scan:
129135
runs-on: ubuntu-latest
Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
// @ts-check
2+
/// <reference types="@actions/github-script" />
3+
4+
const { getErrorMessage } = require("./error_helpers.cjs");
5+
6+
/**
7+
* Check if workflows need recompilation and create an issue if needed.
8+
* This script:
9+
* 1. Checks if there are out-of-sync workflow lock files
10+
* 2. Searches for existing open issues about recompiling workflows
11+
* 3. If workflows are out of sync and no issue exists, creates a new issue with agentic instructions
12+
*
13+
* @returns {Promise<void>}
14+
*/
15+
async function main() {
16+
const owner = context.repo.owner;
17+
const repo = context.repo.repo;
18+
19+
core.info("Checking for out-of-sync workflow lock files");
20+
21+
// Execute git diff to check for changes in lock files
22+
let diffOutput = "";
23+
let hasChanges = false;
24+
25+
try {
26+
// Run git diff to check if there are any changes in lock files
27+
await exec.exec("git", ["diff", "--exit-code", ".github/workflows/*.lock.yml"], {
28+
ignoreReturnCode: true,
29+
listeners: {
30+
stdout: data => {
31+
diffOutput += data.toString();
32+
},
33+
stderr: data => {
34+
diffOutput += data.toString();
35+
},
36+
},
37+
});
38+
39+
// If git diff exits with code 0, there are no changes
40+
// If it exits with code 1, there are changes
41+
// We need to check if there's actual diff output
42+
hasChanges = diffOutput.trim().length > 0;
43+
} catch (error) {
44+
core.error(`Failed to check for workflow changes: ${getErrorMessage(error)}`);
45+
throw error;
46+
}
47+
48+
if (!hasChanges) {
49+
core.info("✓ All workflow lock files are up to date");
50+
return;
51+
}
52+
53+
core.info("⚠ Detected out-of-sync workflow lock files");
54+
55+
// Capture the actual diff for the issue body
56+
let detailedDiff = "";
57+
try {
58+
await exec.exec("git", ["diff", ".github/workflows/*.lock.yml"], {
59+
listeners: {
60+
stdout: data => {
61+
detailedDiff += data.toString();
62+
},
63+
},
64+
});
65+
} catch (error) {
66+
core.warning(`Could not capture detailed diff: ${getErrorMessage(error)}`);
67+
}
68+
69+
// Search for existing open issue about workflow recompilation
70+
const issueTitle = "Workflows need recompilation";
71+
const searchQuery = `repo:${owner}/${repo} is:issue is:open in:title "${issueTitle}"`;
72+
73+
core.info(`Searching for existing issue with title: "${issueTitle}"`);
74+
75+
try {
76+
const searchResult = await github.rest.search.issuesAndPullRequests({
77+
q: searchQuery,
78+
per_page: 1,
79+
});
80+
81+
if (searchResult.data.total_count > 0) {
82+
const existingIssue = searchResult.data.items[0];
83+
core.info(`Found existing issue #${existingIssue.number}: ${existingIssue.html_url}`);
84+
core.info("Skipping issue creation (avoiding duplicate)");
85+
86+
// Add a comment to the existing issue with the new workflow run info
87+
const githubServer = process.env.GITHUB_SERVER_URL || "https://github.com";
88+
const runUrl = context.payload.repository ? `${context.payload.repository.html_url}/actions/runs/${context.runId}` : `${githubServer}/${owner}/${repo}/actions/runs/${context.runId}`;
89+
const commentBody = `Workflows are still out of sync as of ${new Date().toISOString()}.\n\nSee [workflow run](${runUrl}) for details.`;
90+
91+
await github.rest.issues.createComment({
92+
owner,
93+
repo,
94+
issue_number: existingIssue.number,
95+
body: commentBody,
96+
});
97+
98+
core.info(`✓ Added comment to existing issue #${existingIssue.number}`);
99+
return;
100+
}
101+
} catch (error) {
102+
core.error(`Failed to search for existing issues: ${getErrorMessage(error)}`);
103+
throw error;
104+
}
105+
106+
// No existing issue found, create a new one
107+
core.info("No existing issue found, creating a new issue with agentic instructions");
108+
109+
const githubServer = process.env.GITHUB_SERVER_URL || "https://github.com";
110+
const runUrl = context.payload.repository ? `${context.payload.repository.html_url}/actions/runs/${context.runId}` : `${githubServer}/${owner}/${repo}/actions/runs/${context.runId}`;
111+
112+
// Build the issue body with agentic instructions
113+
const issueBody = `## Problem
114+
115+
The workflow lock files (\`.lock.yml\`) are out of sync with their source markdown files (\`.md\`). This means the workflows that run in GitHub Actions are not using the latest configuration.
116+
117+
## What needs to be done
118+
119+
The workflows need to be recompiled to regenerate the lock files from the markdown sources.
120+
121+
## Instructions for GitHub Copilot
122+
123+
Please recompile all workflows by running the following command:
124+
125+
\`\`\`bash
126+
make recompile
127+
\`\`\`
128+
129+
This will:
130+
1. Build the latest version of \`gh-aw\`
131+
2. Compile all workflow markdown files to YAML lock files
132+
3. Ensure all workflows are up to date
133+
134+
After recompiling, commit the changes with a message like:
135+
\`\`\`
136+
Recompile workflows to update lock files
137+
\`\`\`
138+
139+
## Detected Changes
140+
141+
The following workflow lock files have changes:
142+
143+
<details>
144+
<summary>View diff</summary>
145+
146+
\`\`\`diff
147+
${detailedDiff.substring(0, 50000)}${detailedDiff.length > 50000 ? "\n\n... (diff truncated)" : ""}
148+
\`\`\`
149+
150+
</details>
151+
152+
## References
153+
154+
- **Failed Check:** [Workflow Run](${runUrl})
155+
- **Repository:** ${owner}/${repo}
156+
157+
---
158+
159+
> This issue was automatically created by the agentics maintenance workflow.
160+
`;
161+
162+
try {
163+
const newIssue = await github.rest.issues.create({
164+
owner,
165+
repo,
166+
title: issueTitle,
167+
body: issueBody,
168+
labels: ["maintenance", "workflows"],
169+
});
170+
171+
core.info(`✓ Created issue #${newIssue.data.number}: ${newIssue.data.html_url}`);
172+
173+
// Write to job summary
174+
await core.summary.addHeading("Workflow Recompilation Needed", 2).addRaw(`Created issue [#${newIssue.data.number}](${newIssue.data.html_url}) to track workflow recompilation.`).write();
175+
} catch (error) {
176+
core.error(`Failed to create issue: ${getErrorMessage(error)}`);
177+
throw error;
178+
}
179+
}
180+
181+
module.exports = { main };

0 commit comments

Comments
 (0)