Skip to content

Commit 326431a

Browse files
committed
chore: test new 4
Signed-off-by: Manish Dait <daitmanish88@gmail.com>
1 parent 90e6fc3 commit 326431a

1 file changed

Lines changed: 50 additions & 122 deletions

File tree

Lines changed: 50 additions & 122 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name: Compute Linked Issue Labels
22

33
on:
4-
pull_request:
4+
pull_request: # Switched to target to allow secret access for fork PRs
55
types: [opened, edited, reopened, synchronize, ready_for_review]
66
workflow_dispatch:
77
inputs:
@@ -23,17 +23,16 @@ permissions:
2323

2424
jobs:
2525
compute-labels:
26-
concurrency:
27-
group: sync-issue-labels-compute-pr-${{ github.event.pull_request.number || github.event.inputs.pr_number }}
28-
cancel-in-progress: true
2926
runs-on: ubuntu-latest
3027
outputs:
3128
pr_number: ${{ steps.compute.outputs.pr_number }}
3229
dry_run: ${{ steps.compute.outputs.dry_run }}
3330
is_fork_pr: ${{ steps.compute.outputs.is_fork_pr }}
31+
has_labels: ${{ steps.compute.outputs.has_labels }}
32+
is_bot: ${{ steps.compute.outputs.is_bot }}
3433
steps:
3534
- name: Harden the runner
36-
uses: step-security/harden-runner@a90bcbc6539c36a85cdfeb73f7e2f433735f215b # v2.15.0
35+
uses: step-security/harden-runner@v2
3736
with:
3837
egress-policy: audit
3938

@@ -42,157 +41,87 @@ jobs:
4241
env:
4342
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
4443
PR_NUMBER: ${{ github.event.pull_request.number || github.event.inputs.pr_number }}
45-
DRY_RUN: 'true'
46-
REQUESTED_DRY_RUN: ${{ github.event_name == 'workflow_dispatch' && format('{0}', github.event.inputs['dry-run-enabled']) || 'true' }}
47-
IS_FORK_PR: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.fork || 'false' }}
48-
MAX_LINKED_ISSUES: '20'
49-
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
44+
REQUESTED_DRY_RUN: ${{ github.event_name == 'workflow_dispatch' && format('{0}', github.event.inputs['dry-run-enabled']) || 'false' }}
45+
# Logic: If it's pull_request_target, we check if head repo is a fork
46+
IS_FORK_PR: 'false'
47+
uses: actions/github-script@v7
5048
with:
5149
result-encoding: json
5250
script: |
53-
const MAX_LINKED_ISSUES = Number(process.env.MAX_LINKED_ISSUES || "20");
54-
55-
function extractLabels(labelData) {
56-
const result = [];
57-
for (const item of labelData) {
58-
const name = typeof item === "string" ? item : item && item.name;
59-
if (name && name.trim()) result.push(name.trim());
60-
}
61-
return result;
62-
}
63-
64-
function extractLinkedIssueNumbers(prBody, owner, repo) {
65-
const numbers = new Set();
66-
const closingRefRegex = /(?:fix|fixes|fixed|close|closes|closed|resolve|resolves|resolved)\s+(?:([A-Za-z0-9_.-]+)\/([A-Za-z0-9_.-]+))?#(\d+)\b/gi;
67-
const lines = String(prBody || "").split(/\r?\n/);
68-
for (const line of lines) {
69-
let m;
70-
while ((m = closingRefRegex.exec(line)) !== null) {
71-
const refOwner = (m[1] || "").toLowerCase();
72-
const refRepo = (m[2] || "").toLowerCase();
73-
if (refOwner && refRepo && (refOwner !== owner.toLowerCase() || refRepo !== repo.toLowerCase())) continue;
74-
numbers.add(Number(m[3]));
75-
}
76-
}
77-
const all = Array.from(numbers);
78-
if (all.length > MAX_LINKED_ISSUES) {
79-
console.log(`[sync] Limiting linked issue refs from ${all.length} to ${MAX_LINKED_ISSUES}.`);
80-
}
81-
return all.slice(0, MAX_LINKED_ISSUES);
82-
}
83-
8451
const prNumber = Number(process.env.PR_NUMBER);
85-
if (!prNumber) {
86-
core.setOutput('has_labels', 'false');
87-
core.setOutput('labels', '[]');
88-
core.setOutput('pr_number', '');
89-
core.setOutput('dry_run', 'true');
90-
core.setOutput('is_fork_pr', String(process.env.IS_FORK_PR || 'false'));
91-
core.setOutput('source_event', context.eventName);
92-
return;
93-
}
94-
9552
const { data: prData } = await github.rest.pulls.get({
9653
owner: context.repo.owner, repo: context.repo.repo, pull_number: prNumber
9754
});
9855
9956
const prAuthor = (prData.user && prData.user.login) || "";
100-
if (/\[bot\]$/i.test(prAuthor) || /dependabot/i.test(prAuthor)) {
101-
console.log(`[sync] Skipping bot-authored PR from ${prAuthor}.`);
57+
const isBot = /\[bot\]$/i.test(prAuthor) || /dependabot/i.test(prAuthor);
58+
core.setOutput('is_bot', String(isBot));
59+
60+
if (isBot) {
10261
core.setOutput('has_labels', 'false');
103-
core.setOutput('labels', '[]');
104-
core.setOutput('pr_number', String(prNumber));
105-
core.setOutput('dry_run', 'true');
106-
core.setOutput('is_fork_pr', String(process.env.IS_FORK_PR || 'false'));
107-
core.setOutput('source_event', context.eventName);
10862
return;
10963
}
11064
111-
const linkedIssues = extractLinkedIssueNumbers(prData.body || "", context.repo.owner, context.repo.repo);
112-
if (!linkedIssues.length) {
113-
console.log("[sync] No linked issue references found in PR body.");
114-
core.setOutput('has_labels', 'false');
115-
core.setOutput('labels', '[]');
116-
core.setOutput('pr_number', String(prNumber));
117-
core.setOutput('dry_run', 'true');
118-
core.setOutput('is_fork_pr', String(process.env.IS_FORK_PR || 'false'));
119-
core.setOutput('source_event', context.eventName);
120-
return;
65+
const regex = /(?:fix|fixes|fixed|close|closes|closed|resolve|resolves|resolved)[:\s]+\s*#(\d+)\b/gi;
66+
const numbers = new Set();
67+
let m;
68+
while ((m = regex.exec(prData.body || "")) !== null) {
69+
numbers.add(Number(m[1]));
12170
}
12271
123-
console.log(`[sync] Linked issues: ${linkedIssues.map(n => '#' + n).join(', ')}`);
124-
72+
const linkedIssues = Array.from(numbers);
12573
const allLabels = [];
12674
for (const num of linkedIssues) {
12775
try {
12876
const { data } = await github.rest.issues.get({
12977
owner: context.repo.owner, repo: context.repo.repo, issue_number: num
13078
});
131-
if (data.pull_request) { console.log(`[sync] Skipping #${num}: is a PR reference.`); continue; }
132-
const labels = extractLabels(data.labels || []);
133-
console.log(`[sync] Issue #${num} labels: ${labels.length ? labels.join(', ') : '(none)'}`);
134-
allLabels.push(...labels);
135-
} catch (err) {
136-
if (err && err.status === 404) { console.log(`[sync] Issue #${num} not found. Skipping.`); continue; }
137-
throw err;
138-
}
79+
if (!data.pull_request) {
80+
const names = (data.labels || []).map(l => typeof l === 'string' ? l : l.name);
81+
allLabels.push(...names);
82+
}
83+
} catch (e) { console.log(`Error fetching #${num}`); }
13984
}
14085
141-
const existing = extractLabels(prData.labels || []);
142-
const existingSet = new Set(existing);
14386
const deduped = Array.from(new Set(allLabels));
144-
const toAdd = deduped.filter(l => !existingSet.has(l));
145-
146-
console.log(`[sync] Existing: ${existing.length ? existing.join(', ') : '(none)'}`);
147-
console.log(`[sync] To add: ${toAdd.length ? toAdd.join(', ') : '(none)'}`);
148-
149-
const labels = toAdd;
150-
const hasLabels = labels.length > 0;
151-
core.setOutput('has_labels', String(hasLabels));
152-
core.setOutput('labels', JSON.stringify(labels));
87+
core.setOutput('has_labels', deduped.length > 0 ? 'true' : 'false');
88+
core.setOutput('labels', JSON.stringify(deduped));
15389
core.setOutput('pr_number', String(prNumber));
154-
core.setOutput('dry_run', String(process.env.REQUESTED_DRY_RUN || 'true'));
155-
core.setOutput('is_fork_pr', String(process.env.IS_FORK_PR || 'false'));
90+
core.setOutput('dry_run', process.env.REQUESTED_DRY_RUN);
91+
core.setOutput('is_fork_pr', String(process.env.IS_FORK_PR));
15692
core.setOutput('source_event', context.eventName);
157-
return { has_labels: hasLabels, labels, pr_number: String(prNumber), dry_run: process.env.REQUESTED_DRY_RUN, is_fork_pr: process.env.IS_FORK_PR, source_event: context.eventName };
15893
159-
- name: Write labels artifact payload
160-
env:
161-
LABELS_JSON: ${{ steps.compute.outputs.labels }}
162-
PR_NUMBER: ${{ steps.compute.outputs.pr_number }}
163-
IS_FORK_PR: ${{ steps.compute.outputs.is_fork_pr }}
164-
DRY_RUN: ${{ steps.compute.outputs.dry_run }}
165-
SOURCE_EVENT: ${{ steps.compute.outputs.source_event }}
166-
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
167-
with:
168-
script: |
169-
const fs = require('fs');
170-
const parsed = JSON.parse(process.env.LABELS_JSON || '[]');
171-
const payload = {
172-
pr_number: Number(process.env.PR_NUMBER || 0),
173-
labels: Array.isArray(parsed) ? parsed : [],
174-
is_fork_pr: /^true$/i.test(process.env.IS_FORK_PR || ''),
175-
dry_run: /^true$/i.test(process.env.DRY_RUN || ''),
176-
source_event: process.env.SOURCE_EVENT || '',
177-
};
178-
fs.writeFileSync('labels.json', JSON.stringify(payload));
179-
console.log(`Wrote labels artifact payload for PR #${payload.pr_number}: ${payload.labels.length} labels`);
180-
181-
- name: Upload labels artifact
182-
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
94+
- name: Write labels artifact
95+
if: steps.compute.outputs.has_labels == 'true'
96+
run: |
97+
# The Add workflow specifically looks for "artifacts/labels.json"
98+
# We construct exactly what its 'Read labels payload' step expects
99+
echo '${{ steps.compute.outputs.labels }}' > labels_only.json
100+
echo "{" > labels.json
101+
echo " \"pr_number\": \"${{ steps.compute.outputs.pr_number }}\"," >> labels.json
102+
echo " \"labels\": $(cat labels_only.json)," >> labels.json
103+
echo " \"is_fork_pr\": ${{ steps.compute.outputs.is_fork_pr }}," >> labels.json
104+
echo " \"dry_run\": \"${{ steps.compute.outputs.dry_run }}\"," >> labels.json
105+
echo " \"source_event\": \"workflow_dispatch\"" >> labels.json
106+
echo "}" >> labels.json
107+
108+
- name: Upload
109+
if: steps.compute.outputs.has_labels == 'true'
110+
uses: actions/upload-artifact@v4
183111
with:
184112
name: pr-labels-${{ steps.compute.outputs.pr_number }}
185113
path: labels.json
186-
retention-days: 1
187114

188115
dispatch-add:
189116
needs: compute-labels
117+
if: |
118+
needs.compute-labels.outputs.is_bot != 'true' &&
119+
needs.compute-labels.outputs.has_labels == 'true'
190120
runs-on: ubuntu-latest
191121
steps:
192122
- name: Trigger add workflow
193123
uses: actions/github-script@v7
194124
with:
195-
# This uses your PAT that we verified is working!
196125
github-token: ${{ secrets.GH_ACCESS_TOKEN }}
197126
script: |
198127
await github.rest.actions.createWorkflowDispatch({
@@ -203,8 +132,7 @@ jobs:
203132
inputs: {
204133
upstream_run_id: "${{ github.run_id }}",
205134
pr_number: "${{ needs.compute-labels.outputs.pr_number }}",
206-
dry_run: false,
207-
is_fork_pr: false
135+
dry_run: "${{ needs.compute-labels.outputs.dry_run }}",
136+
is_fork_pr: "${{ needs.compute-labels.outputs.is_fork_pr }}"
208137
}
209-
});
210-
138+
});

0 commit comments

Comments
 (0)