Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
104 changes: 104 additions & 0 deletions github/github-accessors.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

140 changes: 140 additions & 0 deletions github/github-accessors_test.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

83 changes: 83 additions & 0 deletions github/pulls.go
Original file line number Diff line number Diff line change
Expand Up @@ -514,6 +514,36 @@ type pullRequestMergeRequest struct {
SHA string `json:"sha,omitempty"`
}

// PullRequestMergeAsyncRequest represents a request to merge a pull request asynchronously.
type PullRequestMergeAsyncRequest struct {
// MergeMethod is the merge method: merge, squash, or rebase. Not supported on merge_queue actions.
MergeMethod *string `json:"merge_method,omitempty"`
// MergeAction is how to merge: default, direct_merge, or merge_queue.
MergeAction *string `json:"merge_action,omitempty"`
// CommitTitle is the title for the automatic commit message. Not supported on merge_queue actions.
CommitTitle *string `json:"commit_title,omitempty"`
// CommitMessage is extra detail to append to the automatic commit message. Not supported on merge_queue actions.
CommitMessage *string `json:"commit_message,omitempty"`
// SHA that the pull request head must match to allow the merge.
SHA *string `json:"sha,omitempty"`
}

// PullRequestMergeAsyncResult represents the current state of an asynchronous merge request.
type PullRequestMergeAsyncResult struct {
Status *string `json:"status,omitempty"`
Details *PullRequestMergeAsyncDetails `json:"details,omitempty"`
}

// PullRequestMergeAsyncDetails represents details for the current state of a PullRequestMergeAsyncResult.
type PullRequestMergeAsyncDetails struct {
Message *string `json:"message,omitempty"`
UUID *string `json:"uuid,omitempty"`
MergeMethod *string `json:"merge_method,omitempty"`
MergeAction *string `json:"merge_action,omitempty"`
ExpectedHeadSHA *string `json:"expected_head_sha,omitempty"`
SHA *string `json:"sha,omitempty"`
}

// Merge a pull request.
// commitMessage is an extra detail to append to automatic commit message.
//
Expand Down Expand Up @@ -548,3 +578,56 @@ func (s *PullRequestsService) Merge(ctx context.Context, owner, repo string, num

return mergeResult, resp, nil
}

// MergeAsync merges a pull request asynchronously. For stacked pull requests,
// this also merges everything below it in the stack. This is the required
// method for merging stacked pull requests; the legacy Merge method cannot be
// used for stacks.
//
// A pending response includes a UUID in PullRequestMergeAsyncResult.Details.UUID
// that must be passed to GetMergeAsyncResult to poll for the outcome.
//
// GitHub API docs: https://docs.github.com/rest/pulls/pulls?apiVersion=2022-11-28#merge-a-pull-request-asynchronously
//
//meta:operation PUT /repos/{owner}/{repo}/pulls/{pull_number}/merge-async
func (s *PullRequestsService) MergeAsync(ctx context.Context, owner, repo string, number int, body PullRequestMergeAsyncRequest) (*PullRequestMergeAsyncResult, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/pulls/%v/merge-async", owner, repo, number)

req, err := s.client.NewRequest(ctx, "PUT", u, body)
if err != nil {
return nil, nil, err
}

var result *PullRequestMergeAsyncResult
resp, err := s.client.Do(req, &result)
if err != nil {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This endpoint can return a 202 AcceptedError - other places where this happens is either handled in the function or documented in the function docs. Not sure what the maintainers prefer but we should do something here

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems like adding a comment in the function docs would be sufficient here - do you agree, @DP19?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah maybe it should be handled in the function just based on a previous bug #3036 / #3047 - the doc might be fine as long as people don't care about the response in that case. Up to you all!

@gmlewis

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this is an asynchronous call anyway, I think a comment should be just fine. In those other examples, users were waiting for the upload, but here, they are explicitly calling an async endpoint anyway and are planning on waiting. Thoughts?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup that works for me 👍🏻

return nil, resp, err
}

return result, resp, nil
}

// GetMergeAsyncResult fetches the current result of an asynchronous merge
// request, identified by the uuid returned when the merge was submitted via
// MergeAsync. Poll this method until the returned status is no longer
// "pending". Results are retained for 24 hours after their most recent update.
//
// GitHub API docs: https://docs.github.com/rest/pulls/pulls?apiVersion=2022-11-28#get-the-result-of-an-asynchronous-merge
//
//meta:operation GET /repos/{owner}/{repo}/pulls/{pull_number}/merge-async/{uuid}
func (s *PullRequestsService) GetMergeAsyncResult(ctx context.Context, owner, repo string, number int, uuid string) (*PullRequestMergeAsyncResult, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/pulls/%v/merge-async/%v", owner, repo, number, uuid)

req, err := s.client.NewRequest(ctx, "GET", u, nil)
if err != nil {
return nil, nil, err
}

var result *PullRequestMergeAsyncResult
resp, err := s.client.Do(req, &result)
if err != nil {
return nil, resp, err
}

return result, resp, nil
}
Loading
Loading