Skip to content

Commit 193b2d4

Browse files
Merge pull request #756 from Aditya8369/714
[GSSoC] [NSOC] Auto labelling opened PRs with gssoc:approved
2 parents 395eb3f + 5b373f4 commit 193b2d4

2 files changed

Lines changed: 101 additions & 0 deletions

File tree

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
name: Sync gssoc approved label
2+
3+
on:
4+
pull_request_review:
5+
types: [submitted, dismissed]
6+
pull_request:
7+
types: [opened, reopened, synchronize, ready_for_review]
8+
9+
permissions:
10+
contents: read
11+
issues: write
12+
pull-requests: read
13+
14+
jobs:
15+
sync-approved-label:
16+
runs-on: ubuntu-latest
17+
steps:
18+
- name: Sync gssoc:approved label
19+
uses: actions/github-script@v7
20+
with:
21+
github-token: ${{ secrets.GITHUB_TOKEN }}
22+
script: |
23+
const labelName = 'gssoc:approved';
24+
const pullRequest = context.payload.pull_request || context.payload.review?.pull_request;
25+
26+
if (!pullRequest?.number) {
27+
core.info('No pull request context found.');
28+
return;
29+
}
30+
31+
const owner = context.repo.owner;
32+
const repo = context.repo.repo;
33+
const pullNumber = pullRequest.number;
34+
35+
const { data: currentPullRequest } = await github.rest.pulls.get({
36+
owner,
37+
repo,
38+
pull_number: pullNumber,
39+
});
40+
41+
const headSha = currentPullRequest.head.sha;
42+
const reviews = await github.paginate(github.rest.pulls.listReviews, {
43+
owner,
44+
repo,
45+
pull_number: pullNumber,
46+
per_page: 100,
47+
});
48+
49+
const latestReviewsByUser = new Map();
50+
51+
for (const review of reviews) {
52+
if (!review.user || review.user.type === 'Bot' || !review.submitted_at) {
53+
continue;
54+
}
55+
56+
const existing = latestReviewsByUser.get(review.user.login);
57+
const reviewTime = Date.parse(review.submitted_at);
58+
const existingTime = existing ? Date.parse(existing.submitted_at) : -1;
59+
60+
if (!existing || reviewTime >= existingTime) {
61+
latestReviewsByUser.set(review.user.login, review);
62+
}
63+
}
64+
65+
const approvedOnCurrentHead = [...latestReviewsByUser.values()].some(
66+
(review) => review.state === 'APPROVED' && review.commit_id === headSha
67+
);
68+
69+
const { data: labels } = await github.rest.issues.listLabelsOnIssue({
70+
owner,
71+
repo,
72+
issue_number: pullNumber,
73+
});
74+
75+
const hasLabel = labels.some((label) => label.name === labelName);
76+
77+
if (approvedOnCurrentHead && !hasLabel) {
78+
await github.rest.issues.addLabels({
79+
owner,
80+
repo,
81+
issue_number: pullNumber,
82+
labels: [labelName],
83+
});
84+
core.info(`Added ${labelName} to PR #${pullNumber}.`);
85+
return;
86+
}
87+
88+
if (!approvedOnCurrentHead && hasLabel) {
89+
await github.rest.issues.removeLabel({
90+
owner,
91+
repo,
92+
issue_number: pullNumber,
93+
name: labelName,
94+
});
95+
core.info(`Removed ${labelName} from PR #${pullNumber}.`);
96+
return;
97+
}
98+
99+
core.info(`No label change needed for PR #${pullNumber}.`);

‎docs/contributing.md‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,8 @@ When proposing an enhancement, describe:
109109
4. Include screenshots for visible UI changes.
110110
5. Reference the related issue if one exists.
111111

112+
If label automation is enabled in the repository, `gssoc:approved` is added when the PR has an approval on its current head commit and is removed again if that approval becomes stale after new commits.
113+
112114
## Code Style
113115

114116
- Keep the frontend vanilla unless a change explicitly needs otherwise.

0 commit comments

Comments
 (0)