Skip to content

Commit e9776f2

Browse files
authored
Merge pull request #260 from boostcampwm-2024/develop
develop 브랜치를 main 브랜치로 병합
2 parents 75a436d + b187192 commit e9776f2

File tree

214 files changed

+15996
-10844
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

214 files changed

+15996
-10844
lines changed
Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
name: Auto Assign, Review, and Merge
2+
3+
on:
4+
pull_request:
5+
types:
6+
- opened
7+
- labeled
8+
- unlabeled
9+
- review_requested
10+
- review_request_removed
11+
pull_request_review:
12+
types:
13+
- submitted
14+
15+
jobs:
16+
auto-assign:
17+
if: github.event_name == 'pull_request'
18+
runs-on: ubuntu-latest
19+
steps:
20+
- name: Checkout repository
21+
uses: actions/checkout@v2
22+
23+
- name: Set up Node.js
24+
uses: actions/setup-node@v2
25+
with:
26+
node-version: "16"
27+
28+
- name: Assign PR creator as Assignee
29+
uses: actions/github-script@v6
30+
with:
31+
script: |
32+
const prNumber = context.payload.pull_request.number;
33+
const currentAssignees = context.payload.pull_request.assignees.map(a => a.login);
34+
35+
// PR 작성자가 이미 담당자로 지정되어 있지 않은 경우에만 할당
36+
if (!currentAssignees.includes(context.actor)) {
37+
await github.rest.issues.addAssignees({
38+
owner: context.repo.owner,
39+
repo: context.repo.repo,
40+
issue_number: prNumber,
41+
assignees: [context.actor]
42+
});
43+
}
44+
45+
auto-reviewers:
46+
if: github.event_name == 'pull_request'
47+
runs-on: ubuntu-latest
48+
needs: auto-assign
49+
steps:
50+
- name: Checkout repository
51+
uses: actions/checkout@v2
52+
53+
- name: Set up Node.js
54+
uses: actions/setup-node@v2
55+
with:
56+
node-version: "16"
57+
58+
- name: Add reviewers based on labels
59+
uses: actions/github-script@v6
60+
with:
61+
script: |
62+
const prNumber = context.payload.pull_request.number;
63+
const prAuthor = context.payload.pull_request.user.login;
64+
const assignees = context.payload.pull_request.assignees.map(a => a.login);
65+
66+
// 현재 리뷰어 목록 가져오기
67+
const currentReviewers = context.payload.pull_request.requested_reviewers
68+
? context.payload.pull_request.requested_reviewers.map(r => r.login)
69+
: [];
70+
71+
const BE_reviewers = ['summersummerwhy', 'ezcolin2', 'Tolerblanc'];
72+
const FE_reviewers = ['yewonJin', 'djk01281'];
73+
const doc_reviewers = ['summersummerwhy', 'ezcolin2', 'Tolerblanc', 'yewonJin', 'djk01281'];
74+
75+
// Function to filter out assignees, PR author, and current reviewers
76+
const filterReviewers = (reviewers) => {
77+
return reviewers.filter(r =>
78+
!assignees.includes(r) &&
79+
r !== prAuthor &&
80+
!currentReviewers.includes(r)
81+
);
82+
};
83+
84+
// Check the labels on the PR and assign appropriate reviewers
85+
const labels = context.payload.pull_request.labels.map(label => label.name);
86+
let reviewersToAdd = [];
87+
88+
if (labels.includes('🐧🚀😶‍🌫️ BE')) {
89+
reviewersToAdd.push(...filterReviewers(BE_reviewers));
90+
}
91+
if (labels.includes('🐳🐣 FE')) {
92+
reviewersToAdd.push(...filterReviewers(FE_reviewers));
93+
}
94+
if (labels.includes('📚 Documentation')) {
95+
reviewersToAdd.push(...filterReviewers(doc_reviewers));
96+
}
97+
98+
// Remove duplicates and limit the number of reviewers
99+
reviewersToAdd = [...new Set(reviewersToAdd)];
100+
const maxReviewers = 4; // 최대 리뷰어 수 제한
101+
reviewersToAdd = reviewersToAdd.slice(0, maxReviewers);
102+
103+
// Request reviewers only if there are new reviewers to add
104+
if (reviewersToAdd.length > 0) {
105+
try {
106+
await github.rest.pulls.requestReviewers({
107+
owner: context.repo.owner,
108+
repo: context.repo.repo,
109+
pull_number: prNumber,
110+
reviewers: reviewersToAdd
111+
});
112+
console.log(`Added reviewers: ${reviewersToAdd.join(', ')}`);
113+
} catch (error) {
114+
console.error('Failed to add reviewers:', error);
115+
// 실패해도 워크플로우는 계속 진행
116+
}
117+
} else {
118+
console.log('No new reviewers to add');
119+
}
120+
121+
auto-merge:
122+
if: github.event_name == 'pull_request_review' && github.event.review.state == 'approved'
123+
runs-on: ubuntu-latest
124+
permissions:
125+
pull-requests: write
126+
contents: write
127+
steps:
128+
- name: Merge and Close PR if Approved
129+
uses: actions/github-script@v6
130+
with:
131+
script: |
132+
const prNumber = context.payload.pull_request.number || context.payload.review.pull_request_number;
133+
134+
try {
135+
// PR 정보 가져오기
136+
const pr = await github.rest.pulls.get({
137+
owner: context.repo.owner,
138+
repo: context.repo.repo,
139+
pull_number: prNumber
140+
});
141+
142+
if (pr.data.merged) {
143+
console.log('PR이 이미 머지되었습니다.');
144+
return;
145+
}
146+
147+
// 머지 가능 상태 확인
148+
if (!pr.data.mergeable) {
149+
console.log('PR에 충돌이 있습니다. 수동 확인이 필요합니다.');
150+
core.setFailed('PR에 충돌이 있어 자동 머지를 진행할 수 없습니다.');
151+
return;
152+
}
153+
154+
// 모든 리뷰 확인
155+
const reviews = await github.rest.pulls.listReviews({
156+
owner: context.repo.owner,
157+
repo: context.repo.repo,
158+
pull_number: prNumber
159+
});
160+
161+
// 각 리뷰어의 최신 리뷰 상태만 확인
162+
const latestReviews = new Map();
163+
reviews.data.forEach(review => {
164+
latestReviews.set(review.user.login, review.state);
165+
});
166+
167+
const hasRejection = Array.from(latestReviews.values()).includes('CHANGES_REQUESTED');
168+
const approvalCount = Array.from(latestReviews.values()).filter(state => state === 'APPROVED').length;
169+
170+
if (!hasRejection && approvalCount >= 1) {
171+
console.log('PR 머지를 시도합니다...');
172+
await github.rest.pulls.merge({
173+
owner: context.repo.owner,
174+
repo: context.repo.repo,
175+
pull_number: prNumber
176+
});
177+
178+
// 브랜치 삭제
179+
const branchName = pr.data.head.ref;
180+
if (branchName !== 'main' && branchName !== 'master') {
181+
await github.rest.git.deleteRef({
182+
owner: context.repo.owner,
183+
repo: context.repo.repo,
184+
ref: `heads/${branchName}`
185+
});
186+
}
187+
} else {
188+
console.log('머지 조건이 충족되지 않았습니다.');
189+
}
190+
} catch (error) {
191+
console.error('Error:', error);
192+
core.setFailed(error.message);
193+
}

.github/workflows/ci-pipeline.yml

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
name: OctoDocs CI Pipeline
2+
3+
on:
4+
pull_request:
5+
branches:
6+
- develop
7+
push:
8+
branches:
9+
- develop
10+
11+
jobs:
12+
setup:
13+
runs-on: ubuntu-latest
14+
outputs:
15+
cache-key: ${{ steps.cache-backend-deps.outputs.cache-hit }}
16+
steps:
17+
- name: Checkout repository
18+
uses: actions/checkout@v3
19+
20+
- name: Set up Node.js
21+
uses: actions/setup-node@v3
22+
with:
23+
node-version: "23"
24+
25+
# turbo 의존성 캐시 설정
26+
- name: Cache Yarn dependencies for backend
27+
id: cache-deps
28+
uses: actions/cache@v3
29+
with:
30+
path: node_modules
31+
key: ${{ runner.os }}-yarn-${{ hashFiles('yarn.lock') }}
32+
33+
# turbo 의존성 설치
34+
- name: Install backend dependencies
35+
if: steps.cache-deps.outputs.cache-hit != 'true'
36+
run: yarn install
37+
38+
lint:
39+
runs-on: ubuntu-latest
40+
needs: setup
41+
steps:
42+
- name: Checkout repository
43+
uses: actions/checkout@v3
44+
45+
- name: Set up Node.js
46+
uses: actions/setup-node@v3
47+
with:
48+
node-version: "23"
49+
50+
# 의존성 캐시 복원
51+
- name: Restore Yarn dependencies for backend
52+
uses: actions/cache@v3
53+
with:
54+
path: node_modules
55+
key: ${{ runner.os }}-yarn-${{ hashFiles('yarn.lock') }}
56+
57+
# 백엔드 린트 실행
58+
- name: Run lint
59+
run: yarn lint
60+
continue-on-error: true
61+
62+
# 백엔드 린트 경고 포스트
63+
- name: Post backend lint warning if any
64+
if: failure()
65+
run: echo "⚠️ lint 실행 도중 경고가 발생했습니다. 확인해주세요."
66+
67+
build:
68+
runs-on: ubuntu-latest
69+
needs: setup
70+
steps:
71+
- name: Checkout repository
72+
uses: actions/checkout@v3
73+
74+
- name: Set up Node.js
75+
uses: actions/setup-node@v3
76+
with:
77+
node-version: "23"
78+
# 루트 의존성 캐시 설정
79+
- name: Cache Yarn dependencies for root
80+
id: cache-deps
81+
uses: actions/cache@v3
82+
with:
83+
path: node_modules
84+
key: ${{ runner.os }}-yarn-${{ hashFiles('yarn.lock') }}
85+
86+
# 빌드 실행
87+
- name: Run build
88+
run: yarn build
89+
test:
90+
runs-on: ubuntu-latest
91+
needs: [setup, build]
92+
steps:
93+
- name: Checkout repository
94+
uses: actions/checkout@v3
95+
96+
- name: Set up Node.js
97+
uses: actions/setup-node@v3
98+
with:
99+
node-version: "23"
100+
101+
# 의존성 캐시 복원
102+
- name: Restore Yarn dependencies
103+
uses: actions/cache@v3
104+
with:
105+
path: node_modules
106+
key: ${{ runner.os }}-yarn-${{ hashFiles('yarn.lock') }}
107+
108+
# 테스트 실행
109+
- name: Run tests
110+
run: yarn test

0 commit comments

Comments
 (0)