Skip to content

Commit bbed4dd

Browse files
committed
fix: 병합을 squash 기본값으로 바꾸고 auto-merge 대신 즉시 병합
1 parent ae1c441 commit bbed4dd

3 files changed

Lines changed: 16 additions & 73 deletions

File tree

AGENTS.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ GitHub Organization webhook 수신용 엔드포인트
208208

209209
#### `POST /merge-prs`
210210

211-
열려있는 PR을 일괄 병합합니다. 기본 병합 방식은 `merge`이며 `merge_method` 값으로 `merge | squash | rebase` 중 선택할 수 있습니다. `excludes`로 특정 PR을 제외할 수 있습니다. 승인 리뷰가 없거나 `maintenance` 라벨이 붙은 PR, Draft PR, GitHub `mergeable_state !== "clean"` PR은 스킵되며 `unknown`/`behind` 상태는 최대 1초 후 한 번 더 확인합니다.
211+
열려있는 PR을 일괄 병합합니다. 기본 병합 방식은 `squash`이며 `merge_method` 값으로 `merge | squash | rebase` 중 선택할 수 있습니다. `excludes`로 특정 PR을 제외할 수 있습니다. 승인 리뷰가 없거나 `maintenance` 라벨이 붙은 PR, Draft PR, GitHub `mergeable_state !== "clean"` PR은 스킵되며 `unknown`/`behind` 상태는 최대 1초 후 한 번 더 확인합니다.
212212

213213
**Request:**
214214

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ https://github.dalestudy.com
129129

130130
### `POST /merge-prs`
131131

132-
열려있는 PR을 일괄 병합합니다. 기본 병합 방식은 `merge`이며, `merge_method``merge | squash | rebase` 중 선택할 수 있습니다. `excludes` 배열로 특정 PR을 제외할 수 있습니다. 최소 1개의 승인 리뷰가 없거나 Draft/`maintenance` 라벨이 붙은 PR은 스킵되며, GitHub에서 `mergeable_state === "clean"`인 PR만 병합됩니다(`behind`, `dirty`, `unknown` 등은 스킵). `unknown`/`behind` 상태는 최대 1초 후 한 차례 재확인합니다.
132+
열려있는 PR을 일괄 병합합니다. 기본 병합 방식은 `squash`이며, `merge_method``merge | squash | rebase` 중 선택할 수 있습니다. `excludes` 배열로 특정 PR을 제외할 수 있습니다. 최소 1개의 승인 리뷰가 없거나 Draft/`maintenance` 라벨이 붙은 PR은 스킵되며, GitHub에서 `mergeable_state === "clean"`인 PR만 병합됩니다(`behind`, `dirty`, `unknown` 등은 스킵). `unknown`/`behind` 상태는 최대 1초 후 한 차례 재확인합니다.
133133

134134
**Request:**
135135

handlers/merge_prs.js

Lines changed: 14 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ export async function mergePrs(request, env) {
2828
}
2929

3030
const { repoOwner, repoName, week, excludes, rawPayload } = payload.data;
31-
const mergeMethod = (rawPayload.merge_method || "merge").toLowerCase();
31+
const mergeMethod = (rawPayload.merge_method || "squash").toLowerCase();
3232

3333
if (!ALLOWED_MERGE_METHODS.has(mergeMethod)) {
3434
return errorResponse(
@@ -150,90 +150,33 @@ export async function mergePrs(request, env) {
150150
}
151151

152152
async function mergePullRequest(owner, repo, prNumber, mergeMethod, token, sha) {
153-
// 1. PR의 GraphQL node ID 조회
154-
const nodeId = await getPullRequestNodeId(owner, repo, prNumber, token);
155-
if (!nodeId) {
156-
return {
157-
merged: false,
158-
error: "Failed to get PR node ID",
159-
};
160-
}
161-
162-
// 2. Merge method 매핑 (REST → GraphQL)
163-
const graphqlMergeMethod = {
164-
merge: "MERGE",
165-
squash: "SQUASH",
166-
rebase: "REBASE",
167-
}[mergeMethod] || "MERGE";
168-
169-
// 3. Auto-merge 활성화 (Merge Queue 사용)
170-
const mutation = `
171-
mutation {
172-
enablePullRequestAutoMerge(input: {
173-
pullRequestId: "${nodeId}"
174-
mergeMethod: ${graphqlMergeMethod}
175-
}) {
176-
pullRequest {
177-
id
178-
number
179-
autoMergeRequest {
180-
enabledAt
181-
mergeMethod
182-
}
183-
}
184-
}
153+
const response = await fetch(
154+
`https://api.github.com/repos/${owner}/${repo}/pulls/${prNumber}/merge`,
155+
{
156+
method: "PUT",
157+
headers: {
158+
...getGitHubHeaders(token),
159+
"Content-Type": "application/json",
160+
},
161+
body: JSON.stringify({ merge_method: mergeMethod, sha }),
185162
}
186-
`;
187-
188-
const response = await fetch("https://api.github.com/graphql", {
189-
method: "POST",
190-
headers: {
191-
...getGitHubHeaders(token),
192-
"Content-Type": "application/json",
193-
},
194-
body: JSON.stringify({ query: mutation }),
195-
});
163+
);
196164

197165
const result = await safeJson(response);
198166

199-
if (response.ok && result.data?.enablePullRequestAutoMerge?.pullRequest) {
167+
if (response.ok && result.merged) {
200168
return {
201169
merged: true,
202-
autoMergeEnabled: true,
203-
sha: sha,
170+
sha: result.sha,
204171
};
205172
}
206173

207174
return {
208175
merged: false,
209-
error: result.errors?.[0]?.message || "Auto-merge failed",
176+
error: result.message || "Merge failed",
210177
};
211178
}
212179

213-
async function getPullRequestNodeId(owner, repo, prNumber, token) {
214-
const query = `
215-
query {
216-
repository(owner: "${owner}", name: "${repo}") {
217-
pullRequest(number: ${prNumber}) {
218-
id
219-
}
220-
}
221-
}
222-
`;
223-
224-
const response = await fetch("https://api.github.com/graphql", {
225-
method: "POST",
226-
headers: {
227-
...getGitHubHeaders(token),
228-
"Content-Type": "application/json",
229-
},
230-
body: JSON.stringify({ query }),
231-
});
232-
233-
const result = await safeJson(response);
234-
return result.data?.repository?.pullRequest?.id || null;
235-
}
236-
237180
async function getMergeableState(owner, repo, prNumber, token) {
238181
const prDetails = await getPullRequestDetails(owner, repo, prNumber, token);
239182

0 commit comments

Comments
 (0)