Skip to content

Added support for preview Lock Reason (#828) #910

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Aug 10, 2018
Merged
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
24 changes: 24 additions & 0 deletions github/github-accessors.go

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

3 changes: 3 additions & 0 deletions github/github.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,9 @@ const (
// https://developer.github.com/changes/2018-02-07-team-discussions-api/
mediaTypeTeamDiscussionsPreview = "application/vnd.github.echo-preview+json"

// https://developer.github.com/changes/2018-01-10-lock-reason-api-preview/
mediaTypeLockReasonPreview = "application/vnd.github.sailor-v-preview+json"

// https://developer.github.com/changes/2018-05-07-new-checks-api-public-beta/
mediaTypeCheckRunsPreview = "application/vnd.github.antiope-preview+json"

Expand Down
27 changes: 22 additions & 5 deletions github/issues.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ type Issue struct {
// TextMatches is only populated from search results that request text matches
// See: search.go and https://developer.github.com/v3/search/#text-match-metadata
TextMatches []TextMatch `json:"text_matches,omitempty"`

// ActiveLockReason is populated only when LockReason is provided while locking the issue.
// Possible values are: "off-topic", "too heated", "resolved", and "spam".
ActiveLockReason *string `json:"active_lock_reason,omitempty"`
}

func (i Issue) String() string {
Expand Down Expand Up @@ -156,7 +160,7 @@ func (s *IssuesService) listIssues(ctx context.Context, u string, opt *IssueList
}

// TODO: remove custom Accept headers when APIs fully launch.
acceptHeaders := []string{mediaTypeReactionsPreview, mediaTypeLabelDescriptionSearchPreview}
acceptHeaders := []string{mediaTypeReactionsPreview, mediaTypeLabelDescriptionSearchPreview, mediaTypeLockReasonPreview}
req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))

var issues []*Issue
Expand Down Expand Up @@ -224,7 +228,7 @@ func (s *IssuesService) ListByRepo(ctx context.Context, owner string, repo strin
}

// TODO: remove custom Accept headers when APIs fully launch.
acceptHeaders := []string{mediaTypeReactionsPreview, mediaTypeLabelDescriptionSearchPreview}
acceptHeaders := []string{mediaTypeReactionsPreview, mediaTypeLabelDescriptionSearchPreview, mediaTypeLockReasonPreview}
req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))

var issues []*Issue
Expand All @@ -247,7 +251,7 @@ func (s *IssuesService) Get(ctx context.Context, owner string, repo string, numb
}

// TODO: remove custom Accept headers when APIs fully launch.
acceptHeaders := []string{mediaTypeReactionsPreview, mediaTypeLabelDescriptionSearchPreview}
acceptHeaders := []string{mediaTypeReactionsPreview, mediaTypeLabelDescriptionSearchPreview, mediaTypeLockReasonPreview}
req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))

issue := new(Issue)
Expand Down Expand Up @@ -303,16 +307,29 @@ func (s *IssuesService) Edit(ctx context.Context, owner string, repo string, num
return i, resp, nil
}

// LockIssueOptions specifies the optional parameters to the
// IssuesService.Lock method.
type LockIssueOptions struct {
// LockReason specifies the reason to lock this issue.
// Providing a lock reason can help make it clearer to contributors why an issue
// was locked. Possible values are: "off-topic", "too heated", "resolved", and "spam".
LockReason string `json:"lock_reason,omitempty"`
}

// Lock an issue's conversation.
//
// GitHub API docs: https://developer.github.com/v3/issues/#lock-an-issue
func (s *IssuesService) Lock(ctx context.Context, owner string, repo string, number int) (*Response, error) {
func (s *IssuesService) Lock(ctx context.Context, owner string, repo string, number int, opt *LockIssueOptions) (*Response, error) {
u := fmt.Sprintf("repos/%v/%v/issues/%d/lock", owner, repo, number)
req, err := s.client.NewRequest("PUT", u, nil)
req, err := s.client.NewRequest("PUT", u, opt)
if err != nil {
return nil, err
}

if opt != nil {
req.Header.Set("Accept", mediaTypeLockReasonPreview)
}

return s.client.Do(ctx, req, nil)
}

Expand Down
21 changes: 14 additions & 7 deletions github/issues_events.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,13 @@ type IssueEvent struct {
// The Actor committed to master a commit mentioning the issue in its commit message.
// CommitID holds the SHA1 of the commit.
//
// reopened, locked, unlocked
// reopened, unlocked
// The Actor did that to the issue.
//
// locked
// The Actor locked the issue.
// LockReason holds the reason of locking the issue (if provided while locking).
//
// renamed
// The Actor changed the issue title from Rename.From to Rename.To.
//
Expand Down Expand Up @@ -64,12 +68,13 @@ type IssueEvent struct {
Issue *Issue `json:"issue,omitempty"`

// Only present on certain events; see above.
Assignee *User `json:"assignee,omitempty"`
Assigner *User `json:"assigner,omitempty"`
CommitID *string `json:"commit_id,omitempty"`
Milestone *Milestone `json:"milestone,omitempty"`
Label *Label `json:"label,omitempty"`
Rename *Rename `json:"rename,omitempty"`
Assignee *User `json:"assignee,omitempty"`
Assigner *User `json:"assigner,omitempty"`
CommitID *string `json:"commit_id,omitempty"`
Milestone *Milestone `json:"milestone,omitempty"`
Label *Label `json:"label,omitempty"`
Rename *Rename `json:"rename,omitempty"`
LockReason *string `json:"lock_reason,omitempty"`
}

// ListIssueEvents lists events for the specified issue.
Expand All @@ -87,6 +92,8 @@ func (s *IssuesService) ListIssueEvents(ctx context.Context, owner, repo string,
return nil, nil, err
}

req.Header.Set("Accept", mediaTypeLockReasonPreview)

var events []*IssueEvent
resp, err := s.client.Do(ctx, req, &events)
if err != nil {
Expand Down
29 changes: 23 additions & 6 deletions github/issues_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ func TestIssuesService_List_all(t *testing.T) {
client, mux, _, teardown := setup()
defer teardown()

acceptHeaders := []string{mediaTypeReactionsPreview, mediaTypeLabelDescriptionSearchPreview}
acceptHeaders := []string{mediaTypeReactionsPreview, mediaTypeLabelDescriptionSearchPreview, mediaTypeLockReasonPreview}
mux.HandleFunc("/issues", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testHeader(t, r, "Accept", strings.Join(acceptHeaders, ", "))
Expand Down Expand Up @@ -57,7 +57,7 @@ func TestIssuesService_List_owned(t *testing.T) {
client, mux, _, teardown := setup()
defer teardown()

acceptHeaders := []string{mediaTypeReactionsPreview, mediaTypeLabelDescriptionSearchPreview}
acceptHeaders := []string{mediaTypeReactionsPreview, mediaTypeLabelDescriptionSearchPreview, mediaTypeLockReasonPreview}
mux.HandleFunc("/user/issues", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testHeader(t, r, "Accept", strings.Join(acceptHeaders, ", "))
Expand All @@ -79,7 +79,7 @@ func TestIssuesService_ListByOrg(t *testing.T) {
client, mux, _, teardown := setup()
defer teardown()

acceptHeaders := []string{mediaTypeReactionsPreview, mediaTypeLabelDescriptionSearchPreview}
acceptHeaders := []string{mediaTypeReactionsPreview, mediaTypeLabelDescriptionSearchPreview, mediaTypeLockReasonPreview}
mux.HandleFunc("/orgs/o/issues", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testHeader(t, r, "Accept", strings.Join(acceptHeaders, ", "))
Expand Down Expand Up @@ -109,7 +109,7 @@ func TestIssuesService_ListByRepo(t *testing.T) {
client, mux, _, teardown := setup()
defer teardown()

acceptHeaders := []string{mediaTypeReactionsPreview, mediaTypeLabelDescriptionSearchPreview}
acceptHeaders := []string{mediaTypeReactionsPreview, mediaTypeLabelDescriptionSearchPreview, mediaTypeLockReasonPreview}
mux.HandleFunc("/repos/o/r/issues", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testHeader(t, r, "Accept", strings.Join(acceptHeaders, ", "))
Expand Down Expand Up @@ -155,7 +155,7 @@ func TestIssuesService_Get(t *testing.T) {
client, mux, _, teardown := setup()
defer teardown()

acceptHeaders := []string{mediaTypeReactionsPreview, mediaTypeLabelDescriptionSearchPreview}
acceptHeaders := []string{mediaTypeReactionsPreview, mediaTypeLabelDescriptionSearchPreview, mediaTypeLockReasonPreview}
mux.HandleFunc("/repos/o/r/issues/1", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testHeader(t, r, "Accept", strings.Join(acceptHeaders, ", "))
Expand Down Expand Up @@ -279,7 +279,24 @@ func TestIssuesService_Lock(t *testing.T) {
w.WriteHeader(http.StatusNoContent)
})

if _, err := client.Issues.Lock(context.Background(), "o", "r", 1); err != nil {
if _, err := client.Issues.Lock(context.Background(), "o", "r", 1, nil); err != nil {
t.Errorf("Issues.Lock returned error: %v", err)
}
}

func TestIssuesService_LockWithReason(t *testing.T) {
client, mux, _, teardown := setup()
defer teardown()

mux.HandleFunc("/repos/o/r/issues/1/lock", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "PUT")
testHeader(t, r, "Accept", mediaTypeLockReasonPreview)
w.WriteHeader(http.StatusNoContent)
})

opt := &LockIssueOptions{LockReason: "off-topic"}

if _, err := client.Issues.Lock(context.Background(), "o", "r", 1, opt); err != nil {
t.Errorf("Issues.Lock returned error: %v", err)
}
}
Expand Down
14 changes: 11 additions & 3 deletions github/pulls.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"bytes"
"context"
"fmt"
"strings"
"time"
)

Expand Down Expand Up @@ -61,6 +62,10 @@ type PullRequest struct {

Head *PullRequestBranch `json:"head,omitempty"`
Base *PullRequestBranch `json:"base,omitempty"`

// ActiveLockReason is populated only when LockReason is provided while locking the pull request.
// Possible values are: "off-topic", "too heated", "resolved", and "spam".
ActiveLockReason *string `json:"active_lock_reason,omitempty"`
}

func (p PullRequest) String() string {
Expand Down Expand Up @@ -118,7 +123,8 @@ func (s *PullRequestsService) List(ctx context.Context, owner string, repo strin
}

// TODO: remove custom Accept header when this API fully launches.
req.Header.Set("Accept", mediaTypeLabelDescriptionSearchPreview)
acceptHeaders := []string{mediaTypeLabelDescriptionSearchPreview, mediaTypeLockReasonPreview}
req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))

var pulls []*PullRequest
resp, err := s.client.Do(ctx, req, &pulls)
Expand All @@ -140,7 +146,8 @@ func (s *PullRequestsService) Get(ctx context.Context, owner string, repo string
}

// TODO: remove custom Accept header when this API fully launches.
req.Header.Set("Accept", mediaTypeLabelDescriptionSearchPreview)
acceptHeaders := []string{mediaTypeLabelDescriptionSearchPreview, mediaTypeLockReasonPreview}
req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))

pull := new(PullRequest)
resp, err := s.client.Do(ctx, req, pull)
Expand Down Expand Up @@ -247,7 +254,8 @@ func (s *PullRequestsService) Edit(ctx context.Context, owner string, repo strin
}

// TODO: remove custom Accept header when this API fully launches.
req.Header.Set("Accept", mediaTypeLabelDescriptionSearchPreview)
acceptHeaders := []string{mediaTypeLabelDescriptionSearchPreview, mediaTypeLockReasonPreview}
req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))

p := new(PullRequest)
resp, err := s.client.Do(ctx, req, p)
Expand Down
9 changes: 6 additions & 3 deletions github/pulls_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,10 @@ func TestPullRequestsService_List(t *testing.T) {
client, mux, _, teardown := setup()
defer teardown()

acceptHeaders := []string{mediaTypeLabelDescriptionSearchPreview, mediaTypeLockReasonPreview}
mux.HandleFunc("/repos/o/r/pulls", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testHeader(t, r, "Accept", mediaTypeLabelDescriptionSearchPreview)
testHeader(t, r, "Accept", strings.Join(acceptHeaders, ", "))
testFormValues(t, r, values{
"state": "closed",
"head": "h",
Expand Down Expand Up @@ -58,9 +59,10 @@ func TestPullRequestsService_Get(t *testing.T) {
client, mux, _, teardown := setup()
defer teardown()

acceptHeaders := []string{mediaTypeLabelDescriptionSearchPreview, mediaTypeLockReasonPreview}
mux.HandleFunc("/repos/o/r/pulls/1", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testHeader(t, r, "Accept", mediaTypeLabelDescriptionSearchPreview)
testHeader(t, r, "Accept", strings.Join(acceptHeaders, ", "))
fmt.Fprint(w, `{"number":1}`)
})

Expand Down Expand Up @@ -278,9 +280,10 @@ func TestPullRequestsService_Edit(t *testing.T) {

for i, tt := range tests {
madeRequest := false
acceptHeaders := []string{mediaTypeLabelDescriptionSearchPreview, mediaTypeLockReasonPreview}
mux.HandleFunc(fmt.Sprintf("/repos/o/r/pulls/%v", i), func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "PATCH")
testHeader(t, r, "Accept", mediaTypeLabelDescriptionSearchPreview)
testHeader(t, r, "Accept", strings.Join(acceptHeaders, ", "))
testBody(t, r, tt.wantUpdate+"\n")
io.WriteString(w, tt.sendResponse)
madeRequest = true
Expand Down