MCPcopy Create free account
hub / github.com/SIMARSINGHRAYAT/Gitzo / mergePullRequest

Function mergePullRequest

src/utils/github.ts:516–569  ·  view source on GitHub ↗
(
  token: string,
  owner: string,
  repo: string,
  pullNumber: number,
  mergeMethod: MergeMethod = 'merge',
  maxRetries = 3
)

Source from the content-addressed store, hash-verified

514 * Merge a PR with retries.
515 */
516export async function mergePullRequest(
517 token: string,
518 owner: string,
519 repo: string,
520 pullNumber: number,
521 mergeMethod: MergeMethod = 'merge',
522 maxRetries = 3
523): Promise<{ merged: boolean; sha?: string; message?: string }> {
524 let lastError: Error | null = null;
525
526 for (let attempt = 0; attempt < maxRetries; attempt++) {
527 try {
528 const res = await ghFetch(`/repos/${owner}/${repo}/pulls/${pullNumber}/merge`, token, {
529 method: 'PUT',
530 body: JSON.stringify({ merge_method: mergeMethod }),
531 headers: { 'Content-Type': 'application/json' },
532 });
533
534 if (res.ok) {
535 const data = await res.json();
536 return { merged: true, sha: data.sha, message: data.message };
537 }
538
539 const err = await res.json().catch(() => ({ message: res.statusText }));
540
541 if (res.status === 405) {
542 if (attempt < maxRetries - 1) { await sleep(2000); continue; }
543 throw new Error(`Cannot merge PR #${pullNumber}: ${err.message || 'Method not allowed. Check branch protection rules.'}`);
544 }
545 if (res.status === 409) {
546 if (attempt < maxRetries - 1) { await sleep(1500); continue; }
547 throw new Error(`Merge conflict on PR #${pullNumber}: ${err.message}`);
548 }
549 if (res.status === 403) {
550 if (err.message?.includes('Resource not accessible'))
551 throw new Error(`PERMISSION_DENIED: ${err.message}`);
552 if (err.message?.includes('rate limit') || err.message?.includes('abuse'))
553 throw new Error(`RATE_LIMITED: ${err.message}`);
554 throw new Error(`Forbidden: ${err.message}`);
555 }
556 if (res.status === 401) {
557 throw new Error(`PERMISSION_DENIED: Token expired or invalid (401 Unauthorized)`);
558 }
559 throw new Error(`Merge failed (HTTP ${res.status}): ${err.message || res.statusText}`);
560 } catch (err) {
561 lastError = err instanceof Error ? err : new Error(String(err));
562 if (lastError.message.includes('PERMISSION_DENIED') || lastError.message.includes('RATE_LIMITED')) {
563 throw lastError;
564 }
565 if (attempt < maxRetries - 1) { await sleep(1500); }
566 }
567 }
568 throw lastError || new Error(`Failed to merge PR #${pullNumber} after ${maxRetries} attempts`);
569}
570
571/**
572 * Delete a branch after merge (cleanup).

Callers 3

startYOLOBadgeWorkflowFunction · 0.90
startCreatingPRsFunction · 0.90
startCreatingPairsFunction · 0.90

Calls 2

ghFetchFunction · 0.85
sleepFunction · 0.85

Tested by

no test coverage detected