Skip to content

Commit 26bb550

Browse files
committed
Refactor mergePullRequest to use GraphQL for auto-merge functionality
1 parent 77569ec commit 26bb550

1 file changed

Lines changed: 75 additions & 17 deletions

File tree

handlers/merge_prs.js

Lines changed: 75 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -150,32 +150,90 @@ export async function mergePrs(request, env) {
150150
}
151151

152152
async function mergePullRequest(owner, repo, prNumber, mergeMethod, token, sha) {
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({
162-
merge_method: mergeMethod,
163-
sha,
164-
}),
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+
}
165185
}
166-
);
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+
});
196+
197+
const result = await safeJson(response);
167198

168-
const payload = await safeJson(response);
169-
if (response.ok && payload?.merged) {
170-
return { merged: true, sha: payload.sha };
199+
if (response.ok && result.data?.enablePullRequestAutoMerge?.pullRequest) {
200+
return {
201+
merged: true,
202+
autoMergeEnabled: true,
203+
sha: sha,
204+
};
171205
}
172206

173207
return {
174208
merged: false,
175-
error: payload?.message || "Merge failed",
209+
error: result.errors?.[0]?.message || "Auto-merge failed",
176210
};
177211
}
178212

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+
179237
async function getMergeableState(owner, repo, prNumber, token) {
180238
const prDetails = await getPullRequestDetails(owner, repo, prNumber, token);
181239

0 commit comments

Comments
 (0)