Skip to content

Commit 3f6db92

Browse files
authored
Merge pull request #19 from nettee-space/feature/auto-status-label
PR 병합 시 status 라벨 변경 자동화
2 parents 0eb7b5f + ba05fa7 commit 3f6db92

File tree

1 file changed

+108
-0
lines changed

1 file changed

+108
-0
lines changed
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
name: Update Status Labels on PR Merge
2+
on:
3+
pull_request:
4+
types: [closed]
5+
6+
jobs:
7+
update_status_labels:
8+
if: github.event.pull_request.merged == true
9+
runs-on: ubuntu-latest
10+
permissions:
11+
issues: write
12+
pull-requests: write
13+
14+
steps:
15+
- name: Check Repository Labels
16+
uses: actions/github-script@v6
17+
with:
18+
github-token: ${{ secrets.GITHUB_TOKEN }}
19+
script: |
20+
try {
21+
await github.rest.issues.getLabel({
22+
owner: context.repo.owner,
23+
repo: context.repo.repo,
24+
name: 'status:done'
25+
});
26+
} catch (error) {
27+
if (error.status === 404) {
28+
console.error(`'status:done' 라벨이 저장소에 존재하지 않습니다.`);
29+
return;
30+
}
31+
console.error('라벨 확인 중 오류:', error);
32+
}
33+
34+
- name: Update PR and Issue Labels
35+
if: success()
36+
uses: actions/github-script@v6
37+
with:
38+
github-token: ${{ secrets.GITHUB_TOKEN }}
39+
script: |
40+
async function updateStatusLabels(issueNumber, currentLabels) {
41+
const statusLabels = currentLabels.filter(label => label.name.startsWith('status:'));
42+
43+
// status:done이 아닌 status: 라벨 제거
44+
await Promise.all(statusLabels
45+
.filter(label => label.name !== 'status:done')
46+
.map(label => github.rest.issues.removeLabel({
47+
owner: context.repo.owner,
48+
repo: context.repo.repo,
49+
issue_number: issueNumber,
50+
name: label.name
51+
}).catch(error => {
52+
if (error.status !== 404) console.error(`라벨 ${label.name} 제거 중 오류:`, error);
53+
}))
54+
);
55+
56+
// status:done 라벨 추가
57+
if (!statusLabels.some(label => label.name === 'status:done')) {
58+
await github.rest.issues.addLabels({
59+
owner: context.repo.owner,
60+
repo: context.repo.repo,
61+
issue_number: issueNumber,
62+
labels: ['status:done']
63+
});
64+
}
65+
66+
const { data: finalLabels } = await github.rest.issues.listLabelsOnIssue({
67+
owner: context.repo.owner,
68+
repo: context.repo.repo,
69+
issue_number: issueNumber
70+
});
71+
return finalLabels.map(label => label.name);
72+
}
73+
74+
try {
75+
// PR 라벨 업데이트
76+
const prNumber = context.payload.pull_request.number;
77+
const prFinalLabels = await updateStatusLabels(prNumber, context.payload.pull_request.labels);
78+
console.log(`PR #${prNumber} 최종 라벨:`, prFinalLabels);
79+
80+
// 연결된 이슈 찾기
81+
const prBody = context.payload.pull_request.body;
82+
if (!prBody) return;
83+
84+
const issueRegex = /(close|closes|closed|fix|fixes|fixed|resolve|resolves|resolved)\s+#(\d+)/gi;
85+
const uniqueIssueNumbers = new Set([...prBody.matchAll(issueRegex)].map(match => match[2]));
86+
87+
if (uniqueIssueNumbers.size === 0) return;
88+
89+
// 이슈 라벨 업데이트
90+
await Promise.all(Array.from(uniqueIssueNumbers).map(async issueNumber => {
91+
try {
92+
const { data: issue } = await github.rest.issues.get({
93+
owner: context.repo.owner,
94+
repo: context.repo.repo,
95+
issue_number: issueNumber
96+
});
97+
98+
const finalLabels = await updateStatusLabels(issueNumber, issue.labels);
99+
console.log(`이슈 #${issueNumber} 최종 라벨:`, finalLabels);
100+
} catch (error) {
101+
if (error.status !== 404) {
102+
console.error(`이슈 #${issueNumber} 처리 중 오류:`, error);
103+
}
104+
}
105+
}));
106+
} catch (error) {
107+
console.error('라벨 업데이트 중 오류:', error);
108+
}

0 commit comments

Comments
 (0)