Repository: google/go-github
Pull request #1186 (2019-06-08 14:00:29)

Add Support to preview endpoints to list branches or pull requests fo…
…r a commit

Helps https://github.com/google/go-github/issues/1151

codecov[bot]: # [Codecov](https://codecov.io/gh/google/go-github/pull/1186?src=pr&el=h1) Report
> Merging [#1186](https://codecov.io/gh/google/go-github/pull/1186?src=pr&el=desc) into [master](https://codecov.io/gh/google/go-github/commit/8354c0739a78b30158359e98fe14ca3bb823159c?src=pr&el=desc) will **decrease** coverage by `0.03%`.
> The diff coverage is `61.53%`.

[![Impacted file tree graph](https://codecov.io/gh/google/go-github/pull/1186/graphs/tree.svg?width=650&token=EgYjGjZlI0&height=150&src=pr)](https://codecov.io/gh/google/go-github/pull/1186?src=pr&el=tree)

```diff
@@            Coverage Diff             @@
##           master    #1186      +/-   ##
==========================================
- Coverage   70.25%   70.21%   -0.04%     
==========================================
  Files          84       84              
  Lines        5867     5893      +26     
==========================================
+ Hits         4122     4138      +16     
- Misses        956      961       +5     
- Partials      789      794       +5
```


| [Impacted Files](https://codecov.io/gh/google/go-github/pull/1186?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [github/github.go](https://codecov.io/gh/google/go-github/pull/1186/diff?src=pr&el=tree#diff-Z2l0aHViL2dpdGh1Yi5nbw==) | `87.53% <ø> (ø)` | :arrow_up: |
| [github/pulls.go](https://codecov.io/gh/google/go-github/pull/1186/diff?src=pr&el=tree#diff-Z2l0aHViL3B1bGxzLmdv) | `72.02% <60%> (-1.41%)` | :arrow_down: |
| [github/repos\_commits.go](https://codecov.io/gh/google/go-github/pull/1186/diff?src=pr&el=tree#diff-Z2l0aHViL3JlcG9zX2NvbW1pdHMuZ28=) | `70.73% <63.63%> (-1.1%)` | :arrow_down: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/google/go-github/pull/1186?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/google/go-github/pull/1186?src=pr&el=footer). Last update [8354c07...cd62ca4](https://codecov.io/gh/google/go-github/pull/1186?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).

sks444: Thanks for the review @gmlewis, I have updated the PR.
googlebot: So there's good news and bad news.

:thumbsup: The good news is that everyone that needs to sign a CLA (the pull request submitter and all commit authors) have done so.  Everything is all good there.

:confused: The bad news is that it appears that one or more commits were authored or co-authored by someone other than the pull request submitter.  We need to confirm that all authors are ok with their commits being contributed to this project.  Please have them confirm that here in the pull request.

*Note to project maintainer: This is a terminal state, meaning the `cla/google` commit status will not change from this state. It's up to you to confirm consent of all the commit author(s), set the `cla` label to `yes` (if enabled on your project), and then merge this pull request when appropriate.*

ℹ️ **Googlers: [Go here](https://goto.google.com/prinfo/https%3A%2F%2Fgithub.com%2Fgoogle%2Fgo-github%2Fpull%2F1186) for more info**.

<!-- need_author_consent -->
sks444: Thanks @vaibhavsingh97, I have updated the pr according to your review.

@gmlewis, There was some conflicts so I did the rebase and did the push without using `--force` and this happened. Should I squash my commits into a single commit and do a force push or it is okay?
gmlewis: @sks444 - sure, go ahead and do a force push since all the review feedback has already been addressed. That should hopefully clear it up.

googlebot: CLAs look good, thanks!

ℹ️ **Googlers: [Go here](https://goto.google.com/prinfo/https%3A%2F%2Fgithub.com%2Fgoogle%2Fgo-github%2Fpull%2F1186) for more info**.

<!-- ok -->
sks444: Thanks @gmlewis, it's done.
gmlewis: Thank you, @sks444!
And thank you for the review, @vaibhavsingh97!

Merging.

Patch:
diff --git a/github/github-accessors.go b/github/github-accessors.go
index 62fddd20..ba872be3 100644
--- a/github/github-accessors.go
+++ b/github/github-accessors.go
@@ -484,6 +484,30 @@ func (b *Branch) GetProtected() bool {
 	return *b.Protected
 }
 
+// GetCommit returns the Commit field.
+func (b *BranchCommit) GetCommit() *Commit {
+	if b == nil {
+		return nil
+	}
+	return b.Commit
+}
+
+// GetName returns the Name field if it's non-nil, zero value otherwise.
+func (b *BranchCommit) GetName() string {
+	if b == nil || b.Name == nil {
+		return ""
+	}
+	return *b.Name
+}
+
+// GetProtected returns the Protected field if it's non-nil, zero value otherwise.
+func (b *BranchCommit) GetProtected() string {
+	if b == nil || b.Protected == nil {
+		return ""
+	}
+	return *b.Protected
+}
+
 // GetApp returns the App field.
 func (c *CheckRun) GetApp() *App {
 	if c == nil {
diff --git a/github/github.go b/github/github.go
index bfe0453e..63f8a966 100644
--- a/github/github.go
+++ b/github/github.go
@@ -140,6 +140,9 @@ const (
 
 	// https://developer.github.com/changes/2019-05-29-update-branch-api/
 	mediaTypeUpdatePullRequestBranchPreview = "application/vnd.github.lydian-preview+json"
+
+	// https://developer.github.com/changes/2019-04-11-pulls-branches-for-commit/
+	mediaTypeListPullsOrBranchesForCommitPreview = "application/vnd.github.groot-preview+json"
 )
 
 // A Client manages communication with the GitHub API.
diff --git a/github/pulls.go b/github/pulls.go
index a8670f9b..a06f97bc 100644
--- a/github/pulls.go
+++ b/github/pulls.go
@@ -159,6 +159,35 @@ func (s *PullRequestsService) List(ctx context.Context, owner string, repo strin
 	return pulls, resp, nil
 }
 
+// ListPullRequestsWithCommit returns pull requests associated with a commit SHA.
+//
+// The results will include open and closed pull requests.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/commits/#list-pull-requests-associated-with-commit
+func (s *PullRequestsService) ListPullRequestsWithCommit(ctx context.Context, owner, repo, sha string, opt *PullRequestListOptions) ([]*PullRequest, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/commits/%v/pulls", owner, repo, sha)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	acceptHeaders := []string{mediaTypeListPullsOrBranchesForCommitPreview, mediaTypeDraftPreview, mediaTypeLabelDescriptionSearchPreview, mediaTypeLockReasonPreview}
+	req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
+	var pulls []*PullRequest
+	resp, err := s.client.Do(ctx, req, &pulls)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return pulls, resp, nil
+}
+
 // Get a single pull request.
 //
 // GitHub API docs: https://developer.github.com/v3/pulls/#get-a-single-pull-request
diff --git a/github/repos_commits.go b/github/repos_commits.go
index 83cdf5b3..95096923 100644
--- a/github/repos_commits.go
+++ b/github/repos_commits.go
@@ -115,6 +115,13 @@ type CommitsListOptions struct {
 	ListOptions
 }
 
+// BranchCommit is the result of listing branches with commit SHA.
+type BranchCommit struct {
+	Name      *string `json:"name,omitempty"`
+	Commit    *Commit `json:"commit,omitempty"`
+	Protected *string `json:"protected,omitempty"`
+}
+
 // ListCommits lists the commits of a repository.
 //
 // GitHub API docs: https://developer.github.com/v3/repos/commits/#list
@@ -232,3 +239,26 @@ func (s *RepositoriesService) CompareCommits(ctx context.Context, owner, repo st
 
 	return comp, resp, nil
 }
+
+// ListBranchesHeadCommit gets all branches where the given commit SHA is the HEAD,
+// or latest commit for the branch.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/commits/#list-branches-for-head-commit
+func (s *RepositoriesService) ListBranchesHeadCommit(ctx context.Context, owner, repo, sha string) ([]*BranchCommit, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/commits/%v/branches-where-head", owner, repo, sha)
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeListPullsOrBranchesForCommitPreview)
+	var branchCommits []*BranchCommit
+	resp, err := s.client.Do(ctx, req, &branchCommits)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return branchCommits, resp, nil
+}


Test patch:
diff --git a/github/pulls_test.go b/github/pulls_test.go
index ba45b6fd..09d60e3a 100644
--- a/github/pulls_test.go
+++ b/github/pulls_test.go
@@ -47,6 +47,37 @@ func TestPullRequestsService_List(t *testing.T) {
 	}
 }
 
+func TestPullRequestsService_ListPullRequestsWithCommit(t *testing.T) {
+	client, mux, _, teardown := setup()
+	defer teardown()
+
+	wantAcceptHeaders := []string{mediaTypeListPullsOrBranchesForCommitPreview, mediaTypeDraftPreview, mediaTypeLabelDescriptionSearchPreview, mediaTypeLockReasonPreview}
+	mux.HandleFunc("/repos/o/r/commits/sha/pulls", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, "GET")
+		testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", "))
+		testFormValues(t, r, values{
+			"state":     "closed",
+			"head":      "h",
+			"base":      "b",
+			"sort":      "created",
+			"direction": "desc",
+			"page":      "2",
+		})
+		fmt.Fprint(w, `[{"number":1}]`)
+	})
+
+	opt := &PullRequestListOptions{"closed", "h", "b", "created", "desc", ListOptions{Page: 2}}
+	pulls, _, err := client.PullRequests.ListPullRequestsWithCommit(context.Background(), "o", "r", "sha", opt)
+	if err != nil {
+		t.Errorf("PullRequests.ListPullRequestsWithCommit returned error: %v", err)
+	}
+
+	want := []*PullRequest{{Number: Int(1)}}
+	if !reflect.DeepEqual(pulls, want) {
+		t.Errorf("PullRequests.ListPullRequestsWithCommit returned %+v, want %+v", pulls, want)
+	}
+}
+
 func TestPullRequestsService_List_invalidOwner(t *testing.T) {
 	client, _, _, teardown := setup()
 	defer teardown()
diff --git a/github/repos_commits_test.go b/github/repos_commits_test.go
index e076febb..feed2b95 100644
--- a/github/repos_commits_test.go
+++ b/github/repos_commits_test.go
@@ -360,3 +360,23 @@ func TestRepositoriesService_CompareCommits(t *testing.T) {
 		t.Errorf("Repositories.CompareCommits returned \n%+v, want \n%+v", got, want)
 	}
 }
+
+func TestRepositoriesService_ListBranchesHeadCommit(t *testing.T) {
+	client, mux, _, teardown := setup()
+	defer teardown()
+
+	mux.HandleFunc("/repos/o/r/commits/s/branches-where-head", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, "GET")
+		fmt.Fprintf(w, `[{"name": "b"}]`)
+	})
+
+	branches, _, err := client.Repositories.ListBranchesHeadCommit(context.Background(), "o", "r", "s")
+	if err != nil {
+		t.Errorf("Repositories.ListBranchesHeadCommit returned error: %v", err)
+	}
+
+	want := []*BranchCommit{{Name: String("b")}}
+	if !reflect.DeepEqual(branches, want) {
+		t.Errorf("Repositories.ListBranchesHeadCommit returned %+v, want %+v", branches, want)
+	}
+}