github.com/cli/cli@v1.14.1-0.20210902173923-1af6a669e342/pkg/cmd/pr/merge/http.go (about)

     1  package merge
     2  
     3  import (
     4  	"context"
     5  	"net/http"
     6  	"strings"
     7  
     8  	"github.com/cli/cli/internal/ghinstance"
     9  	"github.com/cli/cli/internal/ghrepo"
    10  	"github.com/shurcooL/githubv4"
    11  	"github.com/shurcooL/graphql"
    12  )
    13  
    14  type PullRequestMergeMethod int
    15  
    16  const (
    17  	PullRequestMergeMethodMerge PullRequestMergeMethod = iota
    18  	PullRequestMergeMethodRebase
    19  	PullRequestMergeMethodSquash
    20  )
    21  
    22  type mergePayload struct {
    23  	repo             ghrepo.Interface
    24  	pullRequestID    string
    25  	method           PullRequestMergeMethod
    26  	auto             bool
    27  	commitSubject    string
    28  	setCommitSubject bool
    29  	commitBody       string
    30  	setCommitBody    bool
    31  }
    32  
    33  // TODO: drop after githubv4 gets updated
    34  type EnablePullRequestAutoMergeInput struct {
    35  	githubv4.MergePullRequestInput
    36  }
    37  
    38  func mergePullRequest(client *http.Client, payload mergePayload) error {
    39  	input := githubv4.MergePullRequestInput{
    40  		PullRequestID: githubv4.ID(payload.pullRequestID),
    41  	}
    42  
    43  	switch payload.method {
    44  	case PullRequestMergeMethodMerge:
    45  		m := githubv4.PullRequestMergeMethodMerge
    46  		input.MergeMethod = &m
    47  	case PullRequestMergeMethodRebase:
    48  		m := githubv4.PullRequestMergeMethodRebase
    49  		input.MergeMethod = &m
    50  	case PullRequestMergeMethodSquash:
    51  		m := githubv4.PullRequestMergeMethodSquash
    52  		input.MergeMethod = &m
    53  	}
    54  
    55  	if payload.setCommitSubject {
    56  		commitHeadline := githubv4.String(payload.commitSubject)
    57  		input.CommitHeadline = &commitHeadline
    58  	}
    59  	if payload.setCommitBody {
    60  		commitBody := githubv4.String(payload.commitBody)
    61  		input.CommitBody = &commitBody
    62  	}
    63  
    64  	variables := map[string]interface{}{
    65  		"input": input,
    66  	}
    67  
    68  	gql := graphql.NewClient(ghinstance.GraphQLEndpoint(payload.repo.RepoHost()), client)
    69  
    70  	if payload.auto {
    71  		var mutation struct {
    72  			EnablePullRequestAutoMerge struct {
    73  				ClientMutationId string
    74  			} `graphql:"enablePullRequestAutoMerge(input: $input)"`
    75  		}
    76  		variables["input"] = EnablePullRequestAutoMergeInput{input}
    77  		return gql.MutateNamed(context.Background(), "PullRequestAutoMerge", &mutation, variables)
    78  	}
    79  
    80  	var mutation struct {
    81  		MergePullRequest struct {
    82  			ClientMutationId string
    83  		} `graphql:"mergePullRequest(input: $input)"`
    84  	}
    85  	return gql.MutateNamed(context.Background(), "PullRequestMerge", &mutation, variables)
    86  }
    87  
    88  func disableAutoMerge(client *http.Client, repo ghrepo.Interface, prID string) error {
    89  	var mutation struct {
    90  		DisablePullRequestAutoMerge struct {
    91  			ClientMutationId string
    92  		} `graphql:"disablePullRequestAutoMerge(input: {pullRequestId: $prID})"`
    93  	}
    94  
    95  	variables := map[string]interface{}{
    96  		"prID": githubv4.ID(prID),
    97  	}
    98  
    99  	gql := graphql.NewClient(ghinstance.GraphQLEndpoint(repo.RepoHost()), client)
   100  	return gql.MutateNamed(context.Background(), "PullRequestAutoMergeDisable", &mutation, variables)
   101  }
   102  
   103  func getMergeText(client *http.Client, repo ghrepo.Interface, prID string, mergeMethod PullRequestMergeMethod) (string, error) {
   104  	var method githubv4.PullRequestMergeMethod
   105  	switch mergeMethod {
   106  	case PullRequestMergeMethodMerge:
   107  		method = githubv4.PullRequestMergeMethodMerge
   108  	case PullRequestMergeMethodRebase:
   109  		method = githubv4.PullRequestMergeMethodRebase
   110  	case PullRequestMergeMethodSquash:
   111  		method = githubv4.PullRequestMergeMethodSquash
   112  	}
   113  
   114  	var query struct {
   115  		Node struct {
   116  			PullRequest struct {
   117  				ViewerMergeBodyText string `graphql:"viewerMergeBodyText(mergeType: $method)"`
   118  			} `graphql:"...on PullRequest"`
   119  		} `graphql:"node(id: $prID)"`
   120  	}
   121  
   122  	variables := map[string]interface{}{
   123  		"prID":   githubv4.ID(prID),
   124  		"method": method,
   125  	}
   126  
   127  	gql := graphql.NewClient(ghinstance.GraphQLEndpoint(repo.RepoHost()), client)
   128  	err := gql.QueryNamed(context.Background(), "PullRequestMergeText", &query, variables)
   129  	if err != nil {
   130  		// Tolerate this API missing in older GitHub Enterprise
   131  		if strings.Contains(err.Error(), "Field 'viewerMergeBodyText' doesn't exist") {
   132  			return "", nil
   133  		}
   134  		return "", err
   135  	}
   136  
   137  	return query.Node.PullRequest.ViewerMergeBodyText, nil
   138  }