Skip to content

Commit 3f6ad06

Browse files
authored
Merge pull request #939 from Adez017/my-changes
Added workflow for the PR
2 parents 36fd674 + de1b4be commit 3f6ad06

File tree

2 files changed

+220
-2
lines changed

2 files changed

+220
-2
lines changed
Lines changed: 218 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,218 @@
1+
name: Auto Label PR from Linked Issue
2+
3+
on:
4+
pull_request_target:
5+
types: [opened, edited, synchronize, reopened]
6+
7+
permissions:
8+
pull-requests: write
9+
issues: write
10+
contents: read
11+
12+
jobs:
13+
label-pr:
14+
runs-on: ubuntu-latest
15+
16+
steps:
17+
- name: Checkout code
18+
uses: actions/checkout@v4
19+
20+
- name: Extract Issue Numbers from PR Body
21+
id: extract-issues
22+
uses: actions/github-script@v7
23+
with:
24+
github-token: ${{ secrets.GITHUB_TOKEN }}
25+
result-encoding: string
26+
script: |
27+
let prNumber, prBody, prTitle;
28+
29+
// Check if triggered by issue event
30+
if (context.eventName === 'issues') {
31+
// Find all open PRs that link to this issue
32+
const issueNumber = context.payload.issue.number;
33+
console.log(`Issue #${issueNumber} labels were updated`);
34+
35+
// Search for PRs that mention this issue
36+
const { data: pullRequests } = await github.rest.pulls.list({
37+
owner: context.repo.owner,
38+
repo: context.repo.repo,
39+
state: 'open'
40+
});
41+
42+
const linkedPRs = [];
43+
for (const pr of pullRequests) {
44+
const prText = `${pr.title} ${pr.body || ''}`;
45+
const patterns = [
46+
new RegExp(`(?:close[sd]?|fix(?:e[sd])?|resolve[sd]?)\\s+#${issueNumber}\\b`, 'i'),
47+
new RegExp(`#${issueNumber}\\b`)
48+
];
49+
50+
if (patterns.some(p => p.test(prText))) {
51+
linkedPRs.push(pr.number);
52+
}
53+
}
54+
55+
if (linkedPRs.length === 0) {
56+
console.log('No linked PRs found for this issue');
57+
return JSON.stringify({ prs: [], issue: issueNumber });
58+
}
59+
60+
console.log(`Found linked PRs: ${linkedPRs.join(', ')}`);
61+
return JSON.stringify({ prs: linkedPRs, issue: issueNumber });
62+
} else {
63+
// Triggered by PR event - original logic
64+
prBody = context.payload.pull_request.body || '';
65+
prTitle = context.payload.pull_request.title || '';
66+
67+
const patterns = [
68+
/(?:close[sd]?|fix(?:e[sd])?|resolve[sd]?)\s+#(\d+)/gi,
69+
/#(\d+)/g
70+
];
71+
72+
const issueNumbers = new Set();
73+
const textToSearch = prBody + ' ' + prTitle;
74+
75+
patterns.forEach(pattern => {
76+
const matches = [...textToSearch.matchAll(pattern)];
77+
matches.forEach(match => {
78+
issueNumbers.add(match[1]);
79+
});
80+
});
81+
82+
const issues = Array.from(issueNumbers);
83+
console.log('Found linked issues:', issues);
84+
85+
return JSON.stringify({
86+
prs: [context.payload.pull_request.number],
87+
issues: issues
88+
});
89+
}
90+
91+
- name: Get Labels from Linked Issues
92+
id: get-labels
93+
uses: actions/github-script@v7
94+
with:
95+
github-token: ${{ secrets.GITHUB_TOKEN }}
96+
result-encoding: string
97+
script: |
98+
const extractData = JSON.parse('${{ steps.extract-issues.outputs.result }}');
99+
100+
// Labels to exclude from being applied to PRs
101+
const excludedLabels = ['recode', 'hacktoberfest-accepted'];
102+
103+
let issueNumbers = [];
104+
let prsToUpdate = [];
105+
106+
// Handle both PR and issue events
107+
if (extractData.issue) {
108+
// Issue event - update all linked PRs
109+
issueNumbers = [extractData.issue];
110+
prsToUpdate = extractData.prs || [];
111+
} else {
112+
// PR event - update the current PR
113+
issueNumbers = extractData.issues || [];
114+
prsToUpdate = extractData.prs || [];
115+
}
116+
117+
if (!issueNumbers || issueNumbers.length === 0) {
118+
console.log('No linked issues found');
119+
return JSON.stringify({ labels: [], prs: prsToUpdate });
120+
}
121+
122+
const allLabels = new Set();
123+
124+
for (const issueNumber of issueNumbers) {
125+
try {
126+
const issue = await github.rest.issues.get({
127+
owner: context.repo.owner,
128+
repo: context.repo.repo,
129+
issue_number: parseInt(issueNumber)
130+
});
131+
132+
console.log(`Issue #${issueNumber} labels:`, issue.data.labels.map(l => l.name));
133+
134+
issue.data.labels.forEach(label => {
135+
// Only add label if it's not in the excluded list
136+
if (!excludedLabels.includes(label.name.toLowerCase())) {
137+
allLabels.add(label.name);
138+
} else {
139+
console.log(`Excluding label: ${label.name}`);
140+
}
141+
});
142+
} catch (error) {
143+
console.log(`Could not fetch issue #${issueNumber}:`, error.message);
144+
}
145+
}
146+
147+
const labels = Array.from(allLabels);
148+
console.log('All labels to apply:', labels);
149+
150+
return JSON.stringify({ labels: labels, prs: prsToUpdate });
151+
152+
- name: Apply Labels to PR
153+
uses: actions/github-script@v7
154+
with:
155+
github-token: ${{ secrets.GITHUB_TOKEN }}
156+
script: |
157+
const data = JSON.parse('${{ steps.get-labels.outputs.result }}');
158+
const labels = data.labels || [];
159+
const prsToUpdate = data.prs || [];
160+
161+
if (!labels || labels.length === 0) {
162+
console.log('No labels to apply');
163+
return;
164+
}
165+
166+
if (!prsToUpdate || prsToUpdate.length === 0) {
167+
console.log('No PRs to update');
168+
return;
169+
}
170+
171+
// Update each PR
172+
for (const prNumber of prsToUpdate) {
173+
try {
174+
// First, get current PR labels
175+
const { data: pr } = await github.rest.pulls.get({
176+
owner: context.repo.owner,
177+
repo: context.repo.repo,
178+
pull_number: prNumber
179+
});
180+
181+
// Remove all existing labels first (to handle removed issue labels)
182+
const currentLabels = pr.labels.map(l => l.name);
183+
if (currentLabels.length > 0) {
184+
for (const label of currentLabels) {
185+
try {
186+
await github.rest.issues.removeLabel({
187+
owner: context.repo.owner,
188+
repo: context.repo.repo,
189+
issue_number: prNumber,
190+
name: label
191+
});
192+
} catch (e) {
193+
console.log(`Could not remove label ${label}: ${e.message}`);
194+
}
195+
}
196+
}
197+
198+
// Apply new labels
199+
await github.rest.issues.addLabels({
200+
owner: context.repo.owner,
201+
repo: context.repo.repo,
202+
issue_number: prNumber,
203+
labels: labels
204+
});
205+
206+
console.log(`Successfully applied ${labels.length} labels to PR #${prNumber}`);
207+
208+
// Add a comment to the PR
209+
await github.rest.issues.createComment({
210+
owner: context.repo.owner,
211+
repo: context.repo.repo,
212+
issue_number: prNumber,
213+
body: `🏷️ Labels automatically synced from linked issue(s): ${labels.map(l => `\`${l}\``).join(', ')}`
214+
});
215+
} catch (error) {
216+
console.error(`Error updating PR #${prNumber}:`, error.message);
217+
}
218+
}

.github/workflows/autolabler.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,10 @@ jobs:
2424
await github.rest.issues.addLabels({
2525
...context.repo,
2626
issue_number: prNumber,
27-
labels: ["recode", "level 1", "hacktoberfest-accepted"]
27+
labels: ["recode","hacktoberfest-accepted"]
2828
});
2929
30-
console.log(`Added labels [recode, level 1, hacktoberfest-accepted] to PR #${prNumber}`);
30+
console.log(`Added labels [recode, hacktoberfest-accepted] to PR #${prNumber}`);
3131
3232
- name: Add labels to Issue
3333
if: github.event_name == 'issues'

0 commit comments

Comments
 (0)