Skip to content

Commit d927617

Browse files
authored
Added Workflow for Sync in issue and PR
This workflow synchronizes metadata from linked issues into the pull request body, including labels, assignees, and milestones.
1 parent 2232ae0 commit d927617

File tree

1 file changed

+84
-0
lines changed

1 file changed

+84
-0
lines changed
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
name: Sync PR Metadata from Linked Issues
2+
3+
on:
4+
pull_request:
5+
types: [opened, edited, synchronize]
6+
7+
jobs:
8+
sync-metadata:
9+
runs-on: ubuntu-latest
10+
11+
permissions:
12+
pull-requests: write
13+
issues: read
14+
contents: read
15+
16+
steps:
17+
- name: Extract Linked Issues
18+
id: extract
19+
uses: actions/github-script@v7
20+
with:
21+
script: |
22+
const body = context.payload.pull_request.body || "";
23+
const issuePattern = /#(\d+)/g;
24+
const matches = [...body.matchAll(issuePattern)];
25+
const issueNumbers = matches.map(m => parseInt(m[1]));
26+
core.setOutput("issues", JSON.stringify(issueNumbers));
27+
28+
- name: Sync Metadata into PR Body
29+
if: steps.extract.outputs.issues != '[]'
30+
uses: actions/github-script@v7
31+
with:
32+
script: |
33+
const issues = JSON.parse(core.getInput("issues"));
34+
const pr = context.payload.pull_request;
35+
36+
let combinedLabels = [];
37+
let combinedAssignees = [];
38+
let combinedMilestones = [];
39+
40+
for (const number of issues) {
41+
try {
42+
const issue = await github.rest.issues.get({
43+
...context.repo,
44+
issue_number: number
45+
});
46+
47+
const labels = issue.data.labels.map(l => l.name);
48+
const assignees = issue.data.assignees.map(a => a.login);
49+
const milestone = issue.data.milestone ? issue.data.milestone.title : null;
50+
51+
combinedLabels.push(...labels);
52+
combinedAssignees.push(...assignees);
53+
if (milestone) combinedMilestones.push(milestone);
54+
55+
} catch (err) {
56+
console.log(`Could not sync from issue #${number}:`, err.message);
57+
}
58+
}
59+
60+
// Deduplicate
61+
combinedLabels = [...new Set(combinedLabels)];
62+
combinedAssignees = [...new Set(combinedAssignees)];
63+
combinedMilestones = [...new Set(combinedMilestones)];
64+
65+
const metadataBlock =
66+
`\n---\n` +
67+
`### Synced data from Linked Issues\n\n` +
68+
`**Labels:**\n${combinedLabels.length ? combinedLabels.map(l => `- ${l}`).join("\n") : "- None"}\n\n` +
69+
`**Assignees:**\n${combinedAssignees.length ? combinedAssignees.map(a => `- ${a}`).join("\n") : "- None"}\n\n` +
70+
`**Milestones:**\n${combinedMilestones.length ? combinedMilestones.map(m => `- ${m}`).join("\n") : "- None"}\n`;
71+
72+
let newBody = pr.body || "";
73+
74+
// Remove old metadata block if exists
75+
newBody = newBody.replace(/---\n### Synced Metadata[\s\S]*$/, "");
76+
77+
// Append fresh metadata block
78+
newBody += metadataBlock;
79+
80+
await github.rest.pulls.update({
81+
...context.repo,
82+
pull_number: pr.number,
83+
body: newBody
84+
});

0 commit comments

Comments
 (0)