Skip to content

Commit db02476

Browse files
authored
ci(line): add LINE PR review check workflow (#1304)
Replicates the Slack PR review workflow for LINE PRs: - Adds 'line' label to PRs with LINE in the title - Requests review from openab-line-reviewers team - Manages pending-community-review / pending-maintainer-review labels Refs: #1292 Co-authored-by: chaodu-agent <chaodu-agent@users.noreply.github.com>
1 parent a7c2433 commit db02476

1 file changed

Lines changed: 103 additions & 0 deletions

File tree

.github/workflows/line.yml

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
name: LINE PR Review Check
2+
3+
on:
4+
schedule:
5+
- cron: '0 */3 * * *'
6+
workflow_dispatch:
7+
8+
jobs:
9+
check:
10+
runs-on: ubuntu-latest
11+
permissions:
12+
pull-requests: write
13+
issues: write
14+
steps:
15+
- uses: actions/create-github-app-token@v3
16+
id: app-token
17+
with:
18+
client-id: ${{ secrets.APP_ID }}
19+
private-key: ${{ secrets.APP_PRIVATE_KEY }}
20+
- uses: actions/github-script@v7
21+
with:
22+
github-token: ${{ steps.app-token.outputs.token }}
23+
script: |
24+
const LINE_LABEL = 'line';
25+
const PENDING_COMMUNITY = 'pending-community-review';
26+
const PENDING_MAINTAINER = 'pending-maintainer-review';
27+
28+
// Get openab-line-reviewers team members (team must be associated with repo)
29+
const { data: members } = await github.rest.teams.listMembersInOrg({
30+
org: 'openabdev',
31+
team_slug: 'openab-line-reviewers',
32+
per_page: 100
33+
});
34+
const LINE_REVIEWERS = members.map(m => m.login);
35+
36+
const prs = await github.rest.pulls.list({
37+
...context.repo,
38+
state: 'open',
39+
per_page: 100
40+
});
41+
42+
for (const pr of prs.data) {
43+
// 1. Check if title contains "LINE" (exact case)
44+
if (!/LINE/.test(pr.title)) continue;
45+
46+
const labels = pr.labels.map(l => l.name);
47+
48+
// Apply line label if not present
49+
if (!labels.includes(LINE_LABEL)) {
50+
await github.rest.issues.addLabels({
51+
...context.repo,
52+
issue_number: pr.number,
53+
labels: [LINE_LABEL]
54+
});
55+
}
56+
57+
// 2. Check for approval from a line reviewer
58+
const { data: reviews } = await github.rest.pulls.listReviews({
59+
...context.repo,
60+
pull_number: pr.number,
61+
per_page: 100
62+
});
63+
64+
const hasReviewerApproval = reviews.some(
65+
r => r.state === 'APPROVED' && LINE_REVIEWERS.includes(r.user.login)
66+
);
67+
68+
if (hasReviewerApproval) {
69+
// Flip to pending-maintainer-review
70+
if (!labels.includes(PENDING_MAINTAINER)) {
71+
await github.rest.issues.addLabels({
72+
...context.repo,
73+
issue_number: pr.number,
74+
labels: [PENDING_MAINTAINER]
75+
});
76+
}
77+
if (labels.includes(PENDING_COMMUNITY)) {
78+
await github.rest.issues.removeLabel({
79+
...context.repo,
80+
issue_number: pr.number,
81+
name: PENDING_COMMUNITY
82+
}).catch(() => {});
83+
}
84+
console.log(`#${pr.number} — approved by line reviewer, set ${PENDING_MAINTAINER}`);
85+
} else {
86+
// Flip to pending-community-review
87+
if (!labels.includes(PENDING_COMMUNITY)) {
88+
await github.rest.issues.addLabels({
89+
...context.repo,
90+
issue_number: pr.number,
91+
labels: [PENDING_COMMUNITY]
92+
});
93+
}
94+
if (labels.includes(PENDING_MAINTAINER)) {
95+
await github.rest.issues.removeLabel({
96+
...context.repo,
97+
issue_number: pr.number,
98+
name: PENDING_MAINTAINER
99+
}).catch(() => {});
100+
}
101+
console.log(`#${pr.number} — no line reviewer approval, set ${PENDING_COMMUNITY}`);
102+
}
103+
}

0 commit comments

Comments
 (0)