44 issues :
55 types : [opened]
66
7+ concurrency :
8+ group : update-certification-matrix
9+ cancel-in-progress : false
10+
711jobs :
812 update-matrix :
913 if : contains(github.event.issue.labels.*.name, 'certificate') && github.event.issue.milestone != null
1014 runs-on : ubuntu-latest
1115 permissions :
1216 contents : write
17+ pull-requests : write
1318 steps :
1419 - uses : actions/checkout@v4
1520
@@ -20,13 +25,10 @@ jobs:
2025 const fs = require('fs');
2126 const path = require('path');
2227
23- // Read the README content
24- const readmePath = 'README.md';
25- const content = fs.readFileSync(readmePath, 'utf8');
26-
2728 // Get issue details
2829 const issue = context.payload.issue;
2930 const milestone = issue.milestone.title;
31+ const readmePath = 'README.md';
3032
3133 /// Find distribution label (format: "os-<string>", "os-<string>-<number>", or "os-<string>-<string>")
3234 const distroLabel = issue.labels.find(label =>
5254 const osName = version ? `${capitalize(os)} ${capitalize(version)}` : capitalize(os);
5355 const osPattern = version ? new RegExp(`^\\|\\s*${os}\\s+${version}\\s*\\|`, 'i') : new RegExp(`^\\|\\s*${os}\\s*\\|`, 'i');
5456
57+ // Use a single branch for all certification matrix updates
58+ const branchName = `update-certification-matrix`;
59+ const commitMessage = `Update certification matrix for ${osName}`;
60+
61+ // Get the default branch
62+ const { data: repo } = await github.rest.repos.get({
63+ owner: context.repo.owner,
64+ repo: context.repo.repo
65+ });
66+ const defaultBranch = repo.default_branch;
67+
68+ // Get the SHA of the default branch
69+ const { data: refData } = await github.rest.git.getRef({
70+ owner: context.repo.owner,
71+ repo: context.repo.repo,
72+ ref: `heads/${defaultBranch}`
73+ });
74+ const baseSha = refData.object.sha;
75+
76+ // Check if branch already exists
77+ let branchExists = false;
78+ try {
79+ await github.rest.git.getRef({
80+ owner: context.repo.owner,
81+ repo: context.repo.repo,
82+ ref: `heads/${branchName}`
83+ });
84+ branchExists = true;
85+ console.log(`Branch ${branchName} already exists, will fast-forward to main`);
86+ } catch (error) {
87+ if (error.status !== 404) throw error;
88+ console.log(`Creating new branch ${branchName}`);
89+ }
90+
91+ // Create or update branch to point to latest main
92+ if (!branchExists) {
93+ await github.rest.git.createRef({
94+ owner: context.repo.owner,
95+ repo: context.repo.repo,
96+ ref: `refs/heads/${branchName}`,
97+ sha: baseSha
98+ });
99+ console.log(`Created branch ${branchName} from main`);
100+ } else {
101+ // Try to rebase the branch onto main
102+ try {
103+ await github.rest.git.updateRef({
104+ owner: context.repo.owner,
105+ repo: context.repo.repo,
106+ ref: `heads/${branchName}`,
107+ sha: baseSha,
108+ force: false
109+ });
110+ console.log(`Rebased ${branchName} onto main`);
111+ } catch (error) {
112+ // If update fails, it means branch is ahead or diverged - this is fine
113+ console.log(`Branch ${branchName} is already up to date or ahead of main`);
114+ }
115+ }
116+
117+ // Get current file content from the branch (after fast-forward)
118+ const { data: fileData } = await github.rest.repos.getContent({
119+ owner: context.repo.owner,
120+ repo: context.repo.repo,
121+ path: readmePath,
122+ ref: branchName
123+ });
124+ const content = Buffer.from(fileData.content, 'base64').toString('utf8');
125+
55126 // Create new table row content
56127 const newStatus = '✅'; // Assuming new certification issues indicate passing
57128 const certificationCell = `[${milestone}](${issue.html_url})`;
@@ -96,22 +167,46 @@ jobs:
96167 lines.splice(tableEnd, 0, newRow);
97168 }
98169
99- // Write back to README
100- fs.writeFileSync(readmePath, lines.join('\n'));
101-
102- // Create commit
170+ // Commit changes to the branch
103171 await github.rest.repos.createOrUpdateFileContents({
104172 owner: context.repo.owner,
105173 repo: context.repo.repo,
106174 path: readmePath,
107- message: `Update certification matrix for ${osName}` ,
175+ message: commitMessage ,
108176 content: Buffer.from(lines.join('\n')).toString('base64'),
109- sha: (await github.rest.repos.getContent({
177+ sha: fileData.sha,
178+ branch: branchName
179+ });
180+
181+ // Check if PR already exists for this branch
182+ const { data: existingPRs } = await github.rest.pulls.list({
183+ owner: context.repo.owner,
184+ repo: context.repo.repo,
185+ state: 'open',
186+ head: `${context.repo.owner}:${branchName}`
187+ });
188+
189+ if (existingPRs.length > 0) {
190+ console.log(`PR already exists: #${existingPRs[0].number}`);
191+ // Add a comment to the existing PR
192+ await github.rest.issues.createComment({
110193 owner: context.repo.owner,
111194 repo: context.repo.repo,
112- path: readmePath
113- })).data.sha
114- });
195+ issue_number: existingPRs[0].number,
196+ body: `Updated certification matrix for **${osName}** (${milestone}) - refs #${issue.number}`
197+ });
198+ } else {
199+ // Create new PR
200+ const { data: pr } = await github.rest.pulls.create({
201+ owner: context.repo.owner,
202+ repo: context.repo.repo,
203+ title: `Update certification matrix`,
204+ head: branchName,
205+ base: defaultBranch,
206+ body: `This PR automatically updates the certification matrix based on certification issues.\n\nStarted with: **${osName}** (${milestone}) - refs #${issue.number}`
207+ });
208+ console.log(`Created PR #${pr.number}`);
209+ }
115210 close-duplicates :
116211 if : contains(github.event.issue.labels.*.name, 'certificate') && github.event.issue.milestone != null
117212 runs-on : ubuntu-latest
0 commit comments