Skip to content

Commit 3c3b05e

Browse files
committed
with double-parse
1 parent 51acfaf commit 3c3b05e

1 file changed

Lines changed: 74 additions & 79 deletions

File tree

Lines changed: 74 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -1,93 +1,88 @@
1-
name: Sync PR data from Linked Issues
1+
- name: Sync Issue Metadata to PR
2+
uses: actions/github-script@v7
3+
env:
4+
RESULT_JSON: ${{ steps.extract-issues.outputs.result }}
5+
with:
6+
github-token: ${{ secrets.GITHUB_TOKEN }}
7+
script: |
8+
const core = require('@actions/core');
29
3-
on:
4-
pull_request_target:
5-
types: [opened, edited, synchronize]
10+
// Safely parse JSON from previous step
11+
const raw = process.env.RESULT_JSON;
12+
console.log("Raw JSON output:", raw);
613
7-
jobs:
8-
sync-metadata:
9-
runs-on: ubuntu-latest
14+
let data;
15+
try {
16+
data = JSON.parse(raw);
1017
11-
permissions:
12-
issues: write
13-
pull-requests: write
18+
// Handle case where the JSON is double-stringified
19+
if (typeof data === "string") {
20+
data = JSON.parse(data);
21+
}
22+
} catch (err) {
23+
core.setFailed(`Invalid JSON from extract-issues: ${err.message}\nRaw: ${raw}`);
24+
return;
25+
}
1426
15-
steps:
16-
- name: Extract Linked Issues
17-
id: extract
18-
uses: actions/github-script@v7
19-
with:
20-
github-token: ${{ secrets.GITHUB_TOKEN }}
21-
script: |
22-
const body = context.payload.pull_request.body || "";
23-
const issuePattern = /#(\d+)/g;
24-
let matches = [];
25-
let m;
26-
while ((m = issuePattern.exec(body)) !== null) {
27-
matches.push(parseInt(m[1]));
28-
}
29-
core.setOutput("issues", JSON.stringify(matches));
27+
console.log("Parsed data:", data);
3028
31-
- name: Post or Update data Comment
32-
if: steps.extract.outputs.issues && steps.extract.outputs.issues != '[]'
33-
uses: actions/github-script@v7
34-
with:
35-
github-token: ${{ secrets.GITHUB_TOKEN }}
36-
script: |
37-
const issues = JSON.parse(`${{ steps.extract.outputs.issues }}`);
38-
const prNumber = context.payload.pull_request.number;
29+
const prNumber = data.pr;
30+
const issueNumbers = data.issues || [];
3931
40-
let combinedLabels = [];
41-
let combinedAssignees = [];
42-
let combinedMilestones = [];
32+
if (!issueNumbers.length) {
33+
console.log("No linked issues found.");
34+
return;
35+
}
4336
44-
for (const number of issues) {
45-
try {
46-
const issue = await github.rest.issues.get({
47-
...context.repo,
48-
issue_number: number
49-
});
37+
for (const issueNumber of issueNumbers) {
38+
try {
39+
// Fetch issue
40+
const { data: issue } = await github.rest.issues.get({
41+
owner: context.repo.owner,
42+
repo: context.repo.repo,
43+
issue_number: parseInt(issueNumber)
44+
});
5045
51-
combinedLabels.push(...issue.data.labels.map(l => l.name));
52-
combinedAssignees.push(...issue.data.assignees.map(a => a.login));
53-
if (issue.data.milestone) combinedMilestones.push(issue.data.milestone.title);
46+
console.log(`Syncing metadata from Issue #${issueNumber} to PR #${prNumber}`);
5447
55-
} catch (err) {
56-
console.log(`Could not fetch issue #${number}: ${err.message}`);
57-
}
58-
}
48+
// --- Sync Labels ---
49+
const issueLabels = issue.labels.map(l => l.name);
50+
const { data: pr } = await github.rest.pulls.get({
51+
owner: context.repo.owner,
52+
repo: context.repo.repo,
53+
pull_number: prNumber
54+
});
55+
const currentPRLabels = pr.labels.map(l => l.name);
56+
const combinedLabels = Array.from(new Set([...currentPRLabels, ...issueLabels]));
5957
60-
// Deduplicate
61-
combinedLabels = [...new Set(combinedLabels)];
62-
combinedAssignees = [...new Set(combinedAssignees)];
63-
combinedMilestones = [...new Set(combinedMilestones)];
58+
await github.rest.issues.addLabels({
59+
owner: context.repo.owner,
60+
repo: context.repo.repo,
61+
issue_number: prNumber,
62+
labels: combinedLabels
63+
});
64+
console.log(`Labels applied: ${combinedLabels.join(', ')}`);
6465
65-
const commentBody =
66-
`### Synced data from Linked Issues\n\n` +
67-
`**Labels:**\n${combinedLabels.length ? combinedLabels.map(l => `- ${l}`).join("\n") : "- None"}\n\n` +
68-
`**Assignees:**\n${combinedAssignees.length ? combinedAssignees.map(a => `- ${a}`).join("\n") : "- None"}\n\n` +
69-
`**Milestones:**\n${combinedMilestones.length ? combinedMilestones.map(m => `- ${m}`).join("\n") : "- None"}\n`;
70-
71-
// Get existing comments
72-
const comments = await github.rest.issues.listComments({
73-
...context.repo,
74-
issue_number: prNumber
66+
// --- Sync Milestone ---
67+
if (issue.milestone) {
68+
await github.rest.issues.update({
69+
owner: context.repo.owner,
70+
repo: context.repo.repo,
71+
issue_number: prNumber,
72+
milestone: issue.milestone.number
7573
});
74+
console.log(`Milestone synced: ${issue.milestone.title}`);
75+
}
7676
77-
// Find existing workflow comment
78-
const existingComment = comments.data.find(c => c.body.includes("### Synced data from Linked Issues"));
77+
// --- Optional: Add a comment on PR ---
78+
await github.rest.issues.createComment({
79+
owner: context.repo.owner,
80+
repo: context.repo.repo,
81+
issue_number: prNumber,
82+
body: `✅ Synchronized metadata from Issue #${issueNumber}:\nLabels: ${issueLabels.join(', ')}\nMilestone: ${issue.milestone ? issue.milestone.title : 'None'}`
83+
});
7984
80-
if (existingComment) {
81-
await github.rest.issues.updateComment({
82-
...context.repo,
83-
comment_id: existingComment.id,
84-
body: commentBody
85-
});
86-
} else {
87-
// Create new comment
88-
await github.rest.issues.createComment({
89-
...context.repo,
90-
issue_number: prNumber,
91-
body: commentBody
92-
});
93-
}
85+
} catch (error) {
86+
console.error(`Error syncing issue #${issueNumber} to PR #${prNumber}:`, error.message);
87+
}
88+
}

0 commit comments

Comments
 (0)