Skip to content

Commit e21f244

Browse files
authored
feat: Add MergeAsync and GetMergeAsyncResult support (#4491)
1 parent 0fb1d5e commit e21f244

4 files changed

Lines changed: 441 additions & 0 deletions

File tree

github/github-accessors.go

Lines changed: 104 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

github/github-accessors_test.go

Lines changed: 140 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

github/pulls.go

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -514,6 +514,36 @@ type pullRequestMergeRequest struct {
514514
SHA string `json:"sha,omitempty"`
515515
}
516516

517+
// PullRequestMergeAsyncRequest represents a request to merge a pull request asynchronously.
518+
type PullRequestMergeAsyncRequest struct {
519+
// MergeMethod is the merge method: merge, squash, or rebase. Not supported on merge_queue actions.
520+
MergeMethod *string `json:"merge_method,omitempty"`
521+
// MergeAction is how to merge: default, direct_merge, or merge_queue.
522+
MergeAction *string `json:"merge_action,omitempty"`
523+
// CommitTitle is the title for the automatic commit message. Not supported on merge_queue actions.
524+
CommitTitle *string `json:"commit_title,omitempty"`
525+
// CommitMessage is extra detail to append to the automatic commit message. Not supported on merge_queue actions.
526+
CommitMessage *string `json:"commit_message,omitempty"`
527+
// SHA that the pull request head must match to allow the merge.
528+
SHA *string `json:"sha,omitempty"`
529+
}
530+
531+
// PullRequestMergeAsyncResult represents the current state of an asynchronous merge request.
532+
type PullRequestMergeAsyncResult struct {
533+
Status *string `json:"status,omitempty"`
534+
Details *PullRequestMergeAsyncDetails `json:"details,omitempty"`
535+
}
536+
537+
// PullRequestMergeAsyncDetails represents details for the current state of a PullRequestMergeAsyncResult.
538+
type PullRequestMergeAsyncDetails struct {
539+
Message *string `json:"message,omitempty"`
540+
UUID *string `json:"uuid,omitempty"`
541+
MergeMethod *string `json:"merge_method,omitempty"`
542+
MergeAction *string `json:"merge_action,omitempty"`
543+
ExpectedHeadSHA *string `json:"expected_head_sha,omitempty"`
544+
SHA *string `json:"sha,omitempty"`
545+
}
546+
517547
// Merge a pull request.
518548
// commitMessage is an extra detail to append to automatic commit message.
519549
//
@@ -548,3 +578,61 @@ func (s *PullRequestsService) Merge(ctx context.Context, owner, repo string, num
548578

549579
return mergeResult, resp, nil
550580
}
581+
582+
// MergeAsync merges a pull request asynchronously. For stacked pull requests,
583+
// this also merges everything below it in the stack. This is the required
584+
// method for merging stacked pull requests; the legacy Merge method cannot be
585+
// used for stacks.
586+
//
587+
// This endpoint typically returns a 202 Accepted status along with the initial
588+
// AsyncMergeResult, since the merge is processed asynchronously. Because this
589+
// is an explicitly asynchronous call, the returned status code is not treated
590+
// as an error here.
591+
//
592+
// A pending response includes a UUID in PullRequestMergeAsyncResult.Details.UUID
593+
// that must be passed to GetMergeAsyncResult to poll for the outcome.
594+
//
595+
// GitHub API docs: https://docs.github.com/rest/pulls/pulls?apiVersion=2022-11-28#merge-a-pull-request-asynchronously
596+
//
597+
//meta:operation PUT /repos/{owner}/{repo}/pulls/{pull_number}/merge-async
598+
func (s *PullRequestsService) MergeAsync(ctx context.Context, owner, repo string, number int, body PullRequestMergeAsyncRequest) (*PullRequestMergeAsyncResult, *Response, error) {
599+
u := fmt.Sprintf("repos/%v/%v/pulls/%v/merge-async", owner, repo, number)
600+
601+
req, err := s.client.NewRequest(ctx, "PUT", u, body)
602+
if err != nil {
603+
return nil, nil, err
604+
}
605+
606+
var result *PullRequestMergeAsyncResult
607+
resp, err := s.client.Do(req, &result)
608+
if err != nil {
609+
return nil, resp, err
610+
}
611+
612+
return result, resp, nil
613+
}
614+
615+
// GetMergeAsyncResult fetches the current result of an asynchronous merge
616+
// request, identified by the uuid returned when the merge was submitted via
617+
// MergeAsync. Poll this method until the returned status is no longer
618+
// "pending". Results are retained for 24 hours after their most recent update.
619+
//
620+
// GitHub API docs: https://docs.github.com/rest/pulls/pulls?apiVersion=2022-11-28#get-the-result-of-an-asynchronous-merge
621+
//
622+
//meta:operation GET /repos/{owner}/{repo}/pulls/{pull_number}/merge-async/{uuid}
623+
func (s *PullRequestsService) GetMergeAsyncResult(ctx context.Context, owner, repo string, number int, uuid string) (*PullRequestMergeAsyncResult, *Response, error) {
624+
u := fmt.Sprintf("repos/%v/%v/pulls/%v/merge-async/%v", owner, repo, number, uuid)
625+
626+
req, err := s.client.NewRequest(ctx, "GET", u, nil)
627+
if err != nil {
628+
return nil, nil, err
629+
}
630+
631+
var result *PullRequestMergeAsyncResult
632+
resp, err := s.client.Do(req, &result)
633+
if err != nil {
634+
return nil, resp, err
635+
}
636+
637+
return result, resp, nil
638+
}

0 commit comments

Comments
 (0)