From d695b5b0d4106500bc3e32271fecb26a8fc2ffa4 Mon Sep 17 00:00:00 2001 From: Aidan Steele Date: Tue, 11 Jun 2019 21:53:35 +1000 Subject: [PATCH 0001/1468] github.App: Use *Timestamp instead of *time.Time (#1179) --- github/apps.go | 4 ++-- github/github-accessors.go | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/github/apps.go b/github/apps.go index 1ad9a9818fb..80dfb3c8451 100644 --- a/github/apps.go +++ b/github/apps.go @@ -26,8 +26,8 @@ type App struct { Description *string `json:"description,omitempty"` ExternalURL *string `json:"external_url,omitempty"` HTMLURL *string `json:"html_url,omitempty"` - CreatedAt *time.Time `json:"created_at,omitempty"` - UpdatedAt *time.Time `json:"updated_at,omitempty"` + CreatedAt *Timestamp `json:"created_at,omitempty"` + UpdatedAt *Timestamp `json:"updated_at,omitempty"` } // InstallationToken represents an installation token. diff --git a/github/github-accessors.go b/github/github-accessors.go index ba872be39cb..9cd331038e5 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -117,9 +117,9 @@ func (a *APIMeta) GetVerifiablePasswordAuthentication() bool { } // GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise. -func (a *App) GetCreatedAt() time.Time { +func (a *App) GetCreatedAt() Timestamp { if a == nil || a.CreatedAt == nil { - return time.Time{} + return Timestamp{} } return *a.CreatedAt } @@ -181,9 +181,9 @@ func (a *App) GetOwner() *User { } // GetUpdatedAt returns the UpdatedAt field if it's non-nil, zero value otherwise. -func (a *App) GetUpdatedAt() time.Time { +func (a *App) GetUpdatedAt() Timestamp { if a == nil || a.UpdatedAt == nil { - return time.Time{} + return Timestamp{} } return *a.UpdatedAt } From ae920610bb8700b8cfdcf7bb313eef1fe1177886 Mon Sep 17 00:00:00 2001 From: Carlos Tadeu Panato Junior Date: Tue, 11 Jun 2019 14:00:20 +0200 Subject: [PATCH 0002/1468] Add Automated Security Fixes API preview endpoint (#1188) Fixes #1184. --- github/github.go | 3 +++ github/repos.go | 34 ++++++++++++++++++++++++++++++++++ github/repos_test.go | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 69 insertions(+) diff --git a/github/github.go b/github/github.go index 63f8a966439..45a72d7acbe 100644 --- a/github/github.go +++ b/github/github.go @@ -138,6 +138,9 @@ const ( // https://developer.github.com/changes/2019-04-24-vulnerability-alerts/ mediaTypeRequiredVulnerabilityAlertsPreview = "application/vnd.github.dorian-preview+json" + // https://developer.github.com/changes/2019-06-04-automated-security-fixes/ + mediaTypeRequiredAutomatedSecurityFixesPreview = "application/vnd.github.london-preview+json" + // https://developer.github.com/changes/2019-05-29-update-branch-api/ mediaTypeUpdatePullRequestBranchPreview = "application/vnd.github.lydian-preview+json" diff --git a/github/repos.go b/github/repos.go index 154d28bb56a..5f44c6d86fc 100644 --- a/github/repos.go +++ b/github/repos.go @@ -496,6 +496,40 @@ func (s *RepositoriesService) DisableVulnerabilityAlerts(ctx context.Context, ow return s.client.Do(ctx, req, nil) } +// EnableAutomatedSecurityFixes enables the automated security fixes for a repository. +// +// GitHub API docs: https://developer.github.com/v3/repos/#enable-automated-security-fixes +func (s *RepositoriesService) EnableAutomatedSecurityFixes(ctx context.Context, owner, repository string) (*Response, error) { + u := fmt.Sprintf("repos/%v/%v/automated-security-fixes", owner, repository) + + req, err := s.client.NewRequest("PUT", u, nil) + if err != nil { + return nil, err + } + + // TODO: remove custom Accept header when this API fully launches + req.Header.Set("Accept", mediaTypeRequiredAutomatedSecurityFixesPreview) + + return s.client.Do(ctx, req, nil) +} + +// DisableAutomatedSecurityFixes disables vulnerability alerts and the dependency graph for a repository. +// +// GitHub API docs: https://developer.github.com/v3/repos/#disable-automated-security-fixes +func (s *RepositoriesService) DisableAutomatedSecurityFixes(ctx context.Context, owner, repository string) (*Response, error) { + u := fmt.Sprintf("repos/%v/%v/automated-security-fixes", owner, repository) + + req, err := s.client.NewRequest("DELETE", u, nil) + if err != nil { + return nil, err + } + + // TODO: remove custom Accept header when this API fully launches + req.Header.Set("Accept", mediaTypeRequiredAutomatedSecurityFixesPreview) + + return s.client.Do(ctx, req, nil) +} + // ListContributors lists contributors for a repository. // // GitHub API docs: https://developer.github.com/v3/repos/#list-contributors diff --git a/github/repos_test.go b/github/repos_test.go index cb91a38671e..6dd9973cd59 100644 --- a/github/repos_test.go +++ b/github/repos_test.go @@ -399,6 +399,38 @@ func TestRepositoriesService_DisableVulnerabilityAlerts(t *testing.T) { } } +func TestRepositoriesService_EnableAutomatedSecurityFixes(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/repos/o/r/automated-security-fixes", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "PUT") + testHeader(t, r, "Accept", mediaTypeRequiredAutomatedSecurityFixesPreview) + + w.WriteHeader(http.StatusNoContent) + }) + + if _, err := client.Repositories.EnableAutomatedSecurityFixes(context.Background(), "o", "r"); err != nil { + t.Errorf("Repositories.EnableAutomatedSecurityFixes returned error: %v", err) + } +} + +func TestRepositoriesService_DisableAutomatedSecurityFixes(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/repos/o/r/automated-security-fixes", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "DELETE") + testHeader(t, r, "Accept", mediaTypeRequiredAutomatedSecurityFixesPreview) + + w.WriteHeader(http.StatusNoContent) + }) + + if _, err := client.Repositories.DisableAutomatedSecurityFixes(context.Background(), "o", "r"); err != nil { + t.Errorf("Repositories.DisableAutomatedSecurityFixes returned error: %v", err) + } +} + func TestRepositoriesService_ListContributors(t *testing.T) { client, mux, _, teardown := setup() defer teardown() From 3c0a06186fba843ee65689877b7def4685d91d0a Mon Sep 17 00:00:00 2001 From: Glenn Lewis <6598971+gmlewis@users.noreply.github.com> Date: Tue, 11 Jun 2019 08:03:22 -0400 Subject: [PATCH 0003/1468] Bump version from v25 to v26 --- README.md | 2 +- example/appengine/app.go | 2 +- example/basicauth/main.go | 2 +- example/commitpr/main.go | 2 +- example/migrations/main.go | 2 +- example/newrepo/main.go | 2 +- example/simple/main.go | 2 +- github/doc.go | 2 +- github/examples_test.go | 2 +- go.mod | 2 +- test/fields/fields.go | 2 +- test/integration/activity_test.go | 2 +- test/integration/authorizations_test.go | 2 +- test/integration/github_test.go | 2 +- test/integration/repos_test.go | 2 +- test/integration/users_test.go | 2 +- 16 files changed, 16 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 18dd5fda82d..2f2e89ab1fe 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ If you're interested in using the [GraphQL API v4][], the recommended library is ## Usage ## ```go -import "github.com/google/go-github/v25/github" // with go modules enabled (GO111MODULE=on or outside GOPATH) +import "github.com/google/go-github/v26/github" // with go modules enabled (GO111MODULE=on or outside GOPATH) import "github.com/google/go-github/github" // with go modules disabled ``` diff --git a/example/appengine/app.go b/example/appengine/app.go index 4d5c2cbbb00..5ed7573a3d1 100644 --- a/example/appengine/app.go +++ b/example/appengine/app.go @@ -12,7 +12,7 @@ import ( "net/http" "os" - "github.com/google/go-github/v25/github" + "github.com/google/go-github/v26/github" "golang.org/x/oauth2" "google.golang.org/appengine" "google.golang.org/appengine/log" diff --git a/example/basicauth/main.go b/example/basicauth/main.go index 4eac0df8908..cc3b0ccc9ae 100644 --- a/example/basicauth/main.go +++ b/example/basicauth/main.go @@ -16,7 +16,7 @@ import ( "strings" "syscall" - "github.com/google/go-github/v25/github" + "github.com/google/go-github/v26/github" "golang.org/x/crypto/ssh/terminal" ) diff --git a/example/commitpr/main.go b/example/commitpr/main.go index 3ce5fcb0717..33324ce1ff0 100644 --- a/example/commitpr/main.go +++ b/example/commitpr/main.go @@ -31,7 +31,7 @@ import ( "strings" "time" - "github.com/google/go-github/v25/github" + "github.com/google/go-github/v26/github" "golang.org/x/oauth2" ) diff --git a/example/migrations/main.go b/example/migrations/main.go index 26c8352d75f..9c6ae4d98c7 100644 --- a/example/migrations/main.go +++ b/example/migrations/main.go @@ -12,7 +12,7 @@ import ( "context" "fmt" - "github.com/google/go-github/v25/github" + "github.com/google/go-github/v26/github" "golang.org/x/oauth2" ) diff --git a/example/newrepo/main.go b/example/newrepo/main.go index 3898d9ffdc5..65736d7afbf 100644 --- a/example/newrepo/main.go +++ b/example/newrepo/main.go @@ -16,7 +16,7 @@ import ( "log" "os" - "github.com/google/go-github/v25/github" + "github.com/google/go-github/v26/github" "golang.org/x/oauth2" ) diff --git a/example/simple/main.go b/example/simple/main.go index b80886e0142..8c291b76d39 100644 --- a/example/simple/main.go +++ b/example/simple/main.go @@ -12,7 +12,7 @@ import ( "context" "fmt" - "github.com/google/go-github/v25/github" + "github.com/google/go-github/v26/github" ) // Fetch all the public organizations' membership of a user. diff --git a/github/doc.go b/github/doc.go index b82440c3410..1d3151edbaf 100644 --- a/github/doc.go +++ b/github/doc.go @@ -8,7 +8,7 @@ Package github provides a client for using the GitHub API. Usage: - import "github.com/google/go-github/v25/github" // with go modules enabled (GO111MODULE=on or outside GOPATH) + import "github.com/google/go-github/v26/github" // with go modules enabled (GO111MODULE=on or outside GOPATH) import "github.com/google/go-github/github" // with go modules disabled Construct a new GitHub client, then use the various services on the client to diff --git a/github/examples_test.go b/github/examples_test.go index 9fdae43b310..3d385edb915 100644 --- a/github/examples_test.go +++ b/github/examples_test.go @@ -12,7 +12,7 @@ import ( "fmt" "log" - "github.com/google/go-github/v25/github" + "github.com/google/go-github/v26/github" ) func ExampleClient_Markdown() { diff --git a/go.mod b/go.mod index 3d4f0834667..ac4c2dab09c 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module github.com/google/go-github/v25 +module github.com/google/go-github/v26 require ( github.com/golang/protobuf v1.2.0 // indirect diff --git a/test/fields/fields.go b/test/fields/fields.go index 875089f8ab2..a858fdcf92e 100644 --- a/test/fields/fields.go +++ b/test/fields/fields.go @@ -25,7 +25,7 @@ import ( "reflect" "strings" - "github.com/google/go-github/v25/github" + "github.com/google/go-github/v26/github" "golang.org/x/oauth2" ) diff --git a/test/integration/activity_test.go b/test/integration/activity_test.go index 4b3beaca799..082380074e5 100644 --- a/test/integration/activity_test.go +++ b/test/integration/activity_test.go @@ -11,7 +11,7 @@ import ( "context" "testing" - "github.com/google/go-github/v25/github" + "github.com/google/go-github/v26/github" ) const ( diff --git a/test/integration/authorizations_test.go b/test/integration/authorizations_test.go index b058b99d479..b87ec240854 100644 --- a/test/integration/authorizations_test.go +++ b/test/integration/authorizations_test.go @@ -16,7 +16,7 @@ import ( "testing" "time" - "github.com/google/go-github/v25/github" + "github.com/google/go-github/v26/github" ) const msgEnvMissing = "Skipping test because the required environment variable (%v) is not present." diff --git a/test/integration/github_test.go b/test/integration/github_test.go index 3d9328a9308..d1449b30ab1 100644 --- a/test/integration/github_test.go +++ b/test/integration/github_test.go @@ -14,7 +14,7 @@ import ( "net/http" "os" - "github.com/google/go-github/v25/github" + "github.com/google/go-github/v26/github" "golang.org/x/oauth2" ) diff --git a/test/integration/repos_test.go b/test/integration/repos_test.go index ddb1fa5937a..fb938020b6b 100644 --- a/test/integration/repos_test.go +++ b/test/integration/repos_test.go @@ -13,7 +13,7 @@ import ( "reflect" "testing" - "github.com/google/go-github/v25/github" + "github.com/google/go-github/v26/github" ) func TestRepositories_CRUD(t *testing.T) { diff --git a/test/integration/users_test.go b/test/integration/users_test.go index 0ab940eb604..b1bfaf64933 100644 --- a/test/integration/users_test.go +++ b/test/integration/users_test.go @@ -13,7 +13,7 @@ import ( "math/rand" "testing" - "github.com/google/go-github/v25/github" + "github.com/google/go-github/v26/github" ) func TestUsers_Get(t *testing.T) { From 8bcc0479b1703906d4203dbffbb59d656783db5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricco=20F=C3=B8rgaard?= Date: Tue, 11 Jun 2019 14:05:50 +0200 Subject: [PATCH 0004/1468] Add tests for resource JSON marshaling and unmarshaling (#1189) Helps #55. --- github/checks_test.go | 317 ++++++++++++++++++++++++++++++++++++++++++ github/github_test.go | 2 +- 2 files changed, 318 insertions(+), 1 deletion(-) diff --git a/github/checks_test.go b/github/checks_test.go index 9e5bc1fcbd9..214c9f0272d 100644 --- a/github/checks_test.go +++ b/github/checks_test.go @@ -479,3 +479,320 @@ func TestChecksService_ReRequestCheckSuite(t *testing.T) { t.Errorf("Checks.ReRequestCheckSuite = %v, want %v", got, want) } } + +func Test_CheckRunMarshal(t *testing.T) { + testJSONMarshal(t, &CheckRun{}, "{}") + + now := time.Now() + ts := now.Format(time.RFC3339Nano) + + c := CheckRun{ + ID: Int64(1), + NodeID: String("n"), + HeadSHA: String("h"), + ExternalID: String("1"), + URL: String("u"), + HTMLURL: String("u"), + DetailsURL: String("u"), + Status: String("s"), + Conclusion: String("c"), + StartedAt: &Timestamp{Time: now}, + CompletedAt: &Timestamp{Time: now}, + Output: &CheckRunOutput{ + Annotations: []*CheckRunAnnotation{ + { + AnnotationLevel: String("a"), + BlobHRef: String("b"), + EndLine: Int(1), + Message: String("m"), + Path: String("p"), + RawDetails: String("r"), + StartLine: Int(1), + Title: String("t"), + }, + }, + AnnotationsCount: Int(1), + AnnotationsURL: String("a"), + Images: []*CheckRunImage{ + { + Alt: String("a"), + ImageURL: String("i"), + Caption: String("c"), + }, + }, + Title: String("t"), + Summary: String("s"), + Text: String("t"), + }, + Name: String("n"), + CheckSuite: &CheckSuite{ + ID: Int64(1), + }, + App: &App{ + ID: Int64(1), + NodeID: String("n"), + Owner: &User{ + Login: String("l"), + ID: Int64(1), + NodeID: String("n"), + URL: String("u"), + ReposURL: String("r"), + EventsURL: String("e"), + AvatarURL: String("a"), + }, + Name: String("n"), + Description: String("d"), + HTMLURL: String("h"), + ExternalURL: String("u"), + CreatedAt: &now, + UpdatedAt: &now, + }, + PullRequests: []*PullRequest{ + { + URL: String("u"), + ID: Int64(1), + Number: Int(1), + Head: &PullRequestBranch{ + Ref: String("r"), + SHA: String("s"), + Repo: &Repository{ + ID: Int64(1), + URL: String("s"), + Name: String("n"), + }, + }, + Base: &PullRequestBranch{ + Ref: String("r"), + SHA: String("s"), + Repo: &Repository{ + ID: Int64(1), + URL: String("u"), + Name: String("n"), + }, + }, + }, + }, + } + w := fmt.Sprintf(`{ + "id": 1, + "node_id": "n", + "head_sha": "h", + "external_id": "1", + "url": "u", + "html_url": "u", + "details_url": "u", + "status": "s", + "conclusion": "c", + "started_at": "%s", + "completed_at": "%s", + "output": { + "title": "t", + "summary": "s", + "text": "t", + "annotations_count": 1, + "annotations_url": "a", + "annotations": [ + { + "path": "p", + "blob_href": "b", + "start_line": 1, + "end_line": 1, + "annotation_level": "a", + "message": "m", + "title": "t", + "raw_details": "r" + } + ], + "images": [ + { + "alt": "a", + "image_url": "i", + "caption": "c" + } + ] + }, + "name": "n", + "check_suite": { + "id": 1 + }, + "app": { + "id": 1, + "node_id": "n", + "owner": { + "login": "l", + "id": 1, + "node_id": "n", + "avatar_url": "a", + "url": "u", + "events_url": "e", + "repos_url": "r" + }, + "name": "n", + "description": "d", + "external_url": "u", + "html_url": "h", + "created_at": "%s", + "updated_at": "%s" + }, + "pull_requests": [ + { + "id": 1, + "number": 1, + "url": "u", + "head": { + "ref": "r", + "sha": "s", + "repo": { + "id": 1, + "name": "n", + "url": "s" + } + }, + "base": { + "ref": "r", + "sha": "s", + "repo": { + "id": 1, + "name": "n", + "url": "u" + } + } + } + ] + }`, ts, ts, ts, ts) + + testJSONMarshal(t, &c, w) +} + +func Test_CheckSuiteMarshal(t *testing.T) { + testJSONMarshal(t, &CheckSuite{}, "{}") + + now := time.Now() + ts := now.Format(time.RFC3339Nano) + + c := CheckSuite{ + ID: Int64(1), + NodeID: String("n"), + HeadBranch: String("h"), + HeadSHA: String("h"), + URL: String("u"), + BeforeSHA: String("b"), + AfterSHA: String("a"), + Status: String("s"), + Conclusion: String("c"), + App: &App{ + ID: Int64(1), + NodeID: String("n"), + Owner: &User{ + Login: String("l"), + ID: Int64(1), + NodeID: String("n"), + URL: String("u"), + ReposURL: String("r"), + EventsURL: String("e"), + AvatarURL: String("a"), + }, + Name: String("n"), + Description: String("d"), + HTMLURL: String("h"), + ExternalURL: String("u"), + CreatedAt: &now, + UpdatedAt: &now, + }, + Repository: &Repository{ + ID: Int64(1), + }, + PullRequests: []*PullRequest{ + { + URL: String("u"), + ID: Int64(1), + Number: Int(1), + Head: &PullRequestBranch{ + Ref: String("r"), + SHA: String("s"), + Repo: &Repository{ + ID: Int64(1), + URL: String("s"), + Name: String("n"), + }, + }, + Base: &PullRequestBranch{ + Ref: String("r"), + SHA: String("s"), + Repo: &Repository{ + ID: Int64(1), + URL: String("u"), + Name: String("n"), + }, + }, + }, + }, + HeadCommit: &Commit{ + SHA: String("s"), + }, + } + + w := fmt.Sprintf(`{ + "id": 1, + "node_id": "n", + "head_branch": "h", + "head_sha": "h", + "url": "u", + "before": "b", + "after": "a", + "status": "s", + "conclusion": "c", + "app": { + "id": 1, + "node_id": "n", + "owner": { + "login": "l", + "id": 1, + "node_id": "n", + "avatar_url": "a", + "url": "u", + "events_url": "e", + "repos_url": "r" + }, + "name": "n", + "description": "d", + "external_url": "u", + "html_url": "h", + "created_at": "%s", + "updated_at": "%s" + }, + "repository": { + "id": 1 + }, + "pull_requests": [ + { + "id": 1, + "number": 1, + "url": "u", + "head": { + "ref": "r", + "sha": "s", + "repo": { + "id": 1, + "name": "n", + "url": "s" + } + }, + "base": { + "ref": "r", + "sha": "s", + "repo": { + "id": 1, + "name": "n", + "url": "u" + } + } + } + ], + "head_commit": { + "sha": "s" + } + }`, ts, ts) + + testJSONMarshal(t, &c, w) +} diff --git a/github/github_test.go b/github/github_test.go index 4a2581b0194..47f009cf50a 100644 --- a/github/github_test.go +++ b/github/github_test.go @@ -155,7 +155,7 @@ func testJSONMarshal(t *testing.T, v interface{}, want string) { // now go the other direction and make sure things unmarshal as expected u := reflect.ValueOf(v).Interface() if err := json.Unmarshal([]byte(want), u); err != nil { - t.Errorf("Unable to unmarshal JSON for %v", want) + t.Errorf("Unable to unmarshal JSON for %v: %v", want, err) } if !reflect.DeepEqual(v, u) { From 7da2d477e4275d041bc841dd4e1dc90fe9b10a7b Mon Sep 17 00:00:00 2001 From: Glenn Lewis <6598971+gmlewis@users.noreply.github.com> Date: Thu, 13 Jun 2019 20:16:12 -0400 Subject: [PATCH 0005/1468] Fix unit test (#1193) --- github/checks_test.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/github/checks_test.go b/github/checks_test.go index 214c9f0272d..0bdc09651d2 100644 --- a/github/checks_test.go +++ b/github/checks_test.go @@ -544,8 +544,8 @@ func Test_CheckRunMarshal(t *testing.T) { Description: String("d"), HTMLURL: String("h"), ExternalURL: String("u"), - CreatedAt: &now, - UpdatedAt: &now, + CreatedAt: &Timestamp{now}, + UpdatedAt: &Timestamp{now}, }, PullRequests: []*PullRequest{ { @@ -696,8 +696,8 @@ func Test_CheckSuiteMarshal(t *testing.T) { Description: String("d"), HTMLURL: String("h"), ExternalURL: String("u"), - CreatedAt: &now, - UpdatedAt: &now, + CreatedAt: &Timestamp{now}, + UpdatedAt: &Timestamp{now}, }, Repository: &Repository{ ID: Int64(1), From e7f4f741a7add36b17385b4377322d29048029df Mon Sep 17 00:00:00 2001 From: Glenn Lewis <6598971+gmlewis@users.noreply.github.com> Date: Thu, 13 Jun 2019 20:19:44 -0400 Subject: [PATCH 0006/1468] Update AUTHORS with recent contributors --- AUTHORS | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/AUTHORS b/AUTHORS index 5789fed1466..afb59217078 100644 --- a/AUTHORS +++ b/AUTHORS @@ -10,7 +10,9 @@ 178inaba Abhinav Gupta +adrienzieba Ahmed Hagy +Aidan Steele Ainsley Chong Akeda Bagus Akhil Mohan @@ -82,6 +84,7 @@ Emerson Wood eperm Erick Fejta erwinvaneyk +Evan Elias Fabrice Felix Geisendörfer Filippo Valsorda @@ -190,6 +193,7 @@ Ranbir Singh RaviTeja Pothana rc1140 Red Hat, Inc. +Ricco Førgaard Rob Figueiredo Rohit Upadhyay Ronak Jain @@ -212,6 +216,7 @@ Shagun Khemka shakeelrao Shawn Catanzarite Shawn Smith +Shrikrishna Singh sona-tar SoundCloud, Ltd. Sridhar Mocherla From d30c9b8f37c585de76cc730509818ec5a8593bde Mon Sep 17 00:00:00 2001 From: Glenn Lewis <6598971+gmlewis@users.noreply.github.com> Date: Thu, 13 Jun 2019 21:05:06 -0400 Subject: [PATCH 0007/1468] Coverage: admin_stats.go (#1194) --- github/admin_stats_test.go | 203 ++++++++++++++++++++++++++----------- 1 file changed, 145 insertions(+), 58 deletions(-) diff --git a/github/admin_stats_test.go b/github/admin_stats_test.go index 9433adc37b0..745cd606439 100644 --- a/github/admin_stats_test.go +++ b/github/admin_stats_test.go @@ -6,6 +6,7 @@ import ( "net/http" "reflect" "testing" + "time" ) func TestAdminService_GetAdminStats(t *testing.T) { @@ -75,68 +76,154 @@ func TestAdminService_GetAdminStats(t *testing.T) { `) }) - stats, _, err := client.Admin.GetAdminStats(context.Background()) + ctx := context.Background() + stats, _, err := client.Admin.GetAdminStats(ctx) if err != nil { t.Errorf("AdminService.GetAdminStats returned error: %v", err) } - want := &AdminStats{ - Repos: &RepoStats{ - TotalRepos: Int(212), - RootRepos: Int(194), - ForkRepos: Int(18), - OrgRepos: Int(51), - TotalPushes: Int(3082), - TotalWikis: Int(15), - }, - Hooks: &HookStats{ - TotalHooks: Int(27), - ActiveHooks: Int(23), - InactiveHooks: Int(4), - }, - Pages: &PageStats{ - TotalPages: Int(36), - }, - Orgs: &OrgStats{ - TotalOrgs: Int(33), - DisabledOrgs: Int(0), - TotalTeams: Int(60), - TotalTeamMembers: Int(314), - }, - Users: &UserStats{ - TotalUsers: Int(254), - AdminUsers: Int(45), - SuspendedUsers: Int(21), - }, - Pulls: &PullStats{ - TotalPulls: Int(86), - MergedPulls: Int(60), - MergablePulls: Int(21), - UnmergablePulls: Int(3), - }, - Issues: &IssueStats{ - TotalIssues: Int(179), - OpenIssues: Int(83), - ClosedIssues: Int(96), - }, - Milestones: &MilestoneStats{ - TotalMilestones: Int(7), - OpenMilestones: Int(6), - ClosedMilestones: Int(1), - }, - Gists: &GistStats{ - TotalGists: Int(178), - PrivateGists: Int(151), - PublicGists: Int(25), - }, - Comments: &CommentStats{ - TotalCommitComments: Int(6), - TotalGistComments: Int(28), - TotalIssueComments: Int(366), - TotalPullRequestComments: Int(30), - }, - } - if !reflect.DeepEqual(stats, want) { + if want := testAdminStats; !reflect.DeepEqual(stats, want) { t.Errorf("AdminService.GetAdminStats returned %+v, want %+v", stats, want) } + + // Test s.client.NewRequest failure + client.BaseURL.Path = "" + got, resp, err := client.Admin.GetAdminStats(ctx) + if got != nil { + t.Errorf("client.BaseURL.Path='' GetAdminStats = %#v, want nil", got) + } + if resp != nil { + t.Errorf("client.BaseURL.Path='' GetAdminStats resp = %#v, want nil", resp) + } + if err == nil { + t.Error("client.BaseURL.Path='' GetAdminStats err = nil, want error") + } + + // Test s.client.Do failure + client.BaseURL.Path = "/api-v3/" + client.rateLimits[0].Reset.Time = time.Now().Add(10 * time.Minute) + got, resp, err = client.Admin.GetAdminStats(ctx) + if got != nil { + t.Errorf("rate.Reset.Time > now GetAdminStats = %#v, want nil", got) + } + if want := http.StatusForbidden; resp == nil || resp.Response.StatusCode != want { + t.Errorf("rate.Reset.Time > now GetAdminStats resp = %#v, want StatusCode=%v", resp.Response, want) + } + if err == nil { + t.Error("rate.Reset.Time > now GetAdminStats err = nil, want error") + } +} + +func TestAdminService_Stringify(t *testing.T) { + want := "github.AdminStats{Issues:github.IssueStats{TotalIssues:179, OpenIssues:83, ClosedIssues:96}, Hooks:github.HookStats{TotalHooks:27, ActiveHooks:23, InactiveHooks:4}, Milestones:github.MilestoneStats{TotalMilestones:7, OpenMilestones:6, ClosedMilestones:1}, Orgs:github.OrgStats{TotalOrgs:33, DisabledOrgs:0, TotalTeams:60, TotalTeamMembers:314}, Comments:github.CommentStats{TotalCommitComments:6, TotalGistComments:28, TotalIssueComments:366, TotalPullRequestComments:30}, Pages:github.PageStats{TotalPages:36}, Users:github.UserStats{TotalUsers:254, AdminUsers:45, SuspendedUsers:21}, Gists:github.GistStats{TotalGists:178, PrivateGists:151, PublicGists:25}, Pulls:github.PullStats{TotalPulls:86, MergedPulls:60, MergablePulls:21, UnmergablePulls:3}, Repos:github.RepoStats{TotalRepos:212, RootRepos:194, ForkRepos:18, OrgRepos:51, TotalPushes:3082, TotalWikis:15}}" + if got := testAdminStats.String(); got != want { + t.Errorf("testAdminStats.String = %q, want %q", got, want) + } + + want = "github.IssueStats{TotalIssues:179, OpenIssues:83, ClosedIssues:96}" + if got := testAdminStats.Issues.String(); got != want { + t.Errorf("testAdminStats.Issues.String = %q, want %q", got, want) + } + + want = "github.HookStats{TotalHooks:27, ActiveHooks:23, InactiveHooks:4}" + if got := testAdminStats.Hooks.String(); got != want { + t.Errorf("testAdminStats.Hooks.String = %q, want %q", got, want) + } + + want = "github.MilestoneStats{TotalMilestones:7, OpenMilestones:6, ClosedMilestones:1}" + if got := testAdminStats.Milestones.String(); got != want { + t.Errorf("testAdminStats.Milestones.String = %q, want %q", got, want) + } + + want = "github.OrgStats{TotalOrgs:33, DisabledOrgs:0, TotalTeams:60, TotalTeamMembers:314}" + if got := testAdminStats.Orgs.String(); got != want { + t.Errorf("testAdminStats.Orgs.String = %q, want %q", got, want) + } + + want = "github.CommentStats{TotalCommitComments:6, TotalGistComments:28, TotalIssueComments:366, TotalPullRequestComments:30}" + if got := testAdminStats.Comments.String(); got != want { + t.Errorf("testAdminStats.Comments.String = %q, want %q", got, want) + } + + want = "github.PageStats{TotalPages:36}" + if got := testAdminStats.Pages.String(); got != want { + t.Errorf("testAdminStats.Pages.String = %q, want %q", got, want) + } + + want = "github.UserStats{TotalUsers:254, AdminUsers:45, SuspendedUsers:21}" + if got := testAdminStats.Users.String(); got != want { + t.Errorf("testAdminStats.Users.String = %q, want %q", got, want) + } + + want = "github.GistStats{TotalGists:178, PrivateGists:151, PublicGists:25}" + if got := testAdminStats.Gists.String(); got != want { + t.Errorf("testAdminStats.Gists.String = %q, want %q", got, want) + } + + want = "github.PullStats{TotalPulls:86, MergedPulls:60, MergablePulls:21, UnmergablePulls:3}" + if got := testAdminStats.Pulls.String(); got != want { + t.Errorf("testAdminStats.Pulls.String = %q, want %q", got, want) + } + + want = "github.RepoStats{TotalRepos:212, RootRepos:194, ForkRepos:18, OrgRepos:51, TotalPushes:3082, TotalWikis:15}" + if got := testAdminStats.Repos.String(); got != want { + t.Errorf("testAdminStats.Repos.String = %q, want %q", got, want) + } +} + +var testAdminStats = &AdminStats{ + Repos: &RepoStats{ + TotalRepos: Int(212), + RootRepos: Int(194), + ForkRepos: Int(18), + OrgRepos: Int(51), + TotalPushes: Int(3082), + TotalWikis: Int(15), + }, + Hooks: &HookStats{ + TotalHooks: Int(27), + ActiveHooks: Int(23), + InactiveHooks: Int(4), + }, + Pages: &PageStats{ + TotalPages: Int(36), + }, + Orgs: &OrgStats{ + TotalOrgs: Int(33), + DisabledOrgs: Int(0), + TotalTeams: Int(60), + TotalTeamMembers: Int(314), + }, + Users: &UserStats{ + TotalUsers: Int(254), + AdminUsers: Int(45), + SuspendedUsers: Int(21), + }, + Pulls: &PullStats{ + TotalPulls: Int(86), + MergedPulls: Int(60), + MergablePulls: Int(21), + UnmergablePulls: Int(3), + }, + Issues: &IssueStats{ + TotalIssues: Int(179), + OpenIssues: Int(83), + ClosedIssues: Int(96), + }, + Milestones: &MilestoneStats{ + TotalMilestones: Int(7), + OpenMilestones: Int(6), + ClosedMilestones: Int(1), + }, + Gists: &GistStats{ + TotalGists: Int(178), + PrivateGists: Int(151), + PublicGists: Int(25), + }, + Comments: &CommentStats{ + TotalCommitComments: Int(6), + TotalGistComments: Int(28), + TotalIssueComments: Int(366), + TotalPullRequestComments: Int(30), + }, } From 14fcc093bb3e553a69d7783e38049c83dd0cea0f Mon Sep 17 00:00:00 2001 From: Glenn Lewis <6598971+gmlewis@users.noreply.github.com> Date: Thu, 13 Jun 2019 21:40:01 -0400 Subject: [PATCH 0008/1468] Coverage: admin.go (#1195) --- github/admin_test.go | 108 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 106 insertions(+), 2 deletions(-) diff --git a/github/admin_test.go b/github/admin_test.go index 8979686f124..9d2943332c0 100644 --- a/github/admin_test.go +++ b/github/admin_test.go @@ -12,6 +12,7 @@ import ( "net/http" "reflect" "testing" + "time" ) func TestAdminService_UpdateUserLDAPMapping(t *testing.T) { @@ -33,7 +34,8 @@ func TestAdminService_UpdateUserLDAPMapping(t *testing.T) { fmt.Fprint(w, `{"id":1,"ldap_dn":"uid=asdf,ou=users,dc=github,dc=com"}`) }) - mapping, _, err := client.Admin.UpdateUserLDAPMapping(context.Background(), "u", input) + ctx := context.Background() + mapping, _, err := client.Admin.UpdateUserLDAPMapping(ctx, "u", input) if err != nil { t.Errorf("Admin.UpdateUserLDAPMapping returned error: %v", err) } @@ -45,6 +47,33 @@ func TestAdminService_UpdateUserLDAPMapping(t *testing.T) { if !reflect.DeepEqual(mapping, want) { t.Errorf("Admin.UpdateUserLDAPMapping returned %+v, want %+v", mapping, want) } + + // Test s.client.NewRequest failure + client.BaseURL.Path = "" + got, resp, err := client.Admin.UpdateUserLDAPMapping(ctx, "u", input) + if got != nil { + t.Errorf("client.BaseURL.Path='' UpdateUserLDAPMapping = %#v, want nil", got) + } + if resp != nil { + t.Errorf("client.BaseURL.Path='' UpdateUserLDAPMapping resp = %#v, want nil", resp) + } + if err == nil { + t.Error("client.BaseURL.Path='' UpdateUserLDAPMapping err = nil, want error") + } + + // Test s.client.Do failure + client.BaseURL.Path = "/api-v3/" + client.rateLimits[0].Reset.Time = time.Now().Add(10 * time.Minute) + got, resp, err = client.Admin.UpdateUserLDAPMapping(ctx, "u", input) + if got != nil { + t.Errorf("rate.Reset.Time > now UpdateUserLDAPMapping = %#v, want nil", got) + } + if want := http.StatusForbidden; resp == nil || resp.Response.StatusCode != want { + t.Errorf("rate.Reset.Time > now UpdateUserLDAPMapping resp = %#v, want StatusCode=%v", resp.Response, want) + } + if err == nil { + t.Error("rate.Reset.Time > now UpdateUserLDAPMapping err = nil, want error") + } } func TestAdminService_UpdateTeamLDAPMapping(t *testing.T) { @@ -66,7 +95,8 @@ func TestAdminService_UpdateTeamLDAPMapping(t *testing.T) { fmt.Fprint(w, `{"id":1,"ldap_dn":"cn=Enterprise Ops,ou=teams,dc=github,dc=com"}`) }) - mapping, _, err := client.Admin.UpdateTeamLDAPMapping(context.Background(), 1, input) + ctx := context.Background() + mapping, _, err := client.Admin.UpdateTeamLDAPMapping(ctx, 1, input) if err != nil { t.Errorf("Admin.UpdateTeamLDAPMapping returned error: %v", err) } @@ -78,4 +108,78 @@ func TestAdminService_UpdateTeamLDAPMapping(t *testing.T) { if !reflect.DeepEqual(mapping, want) { t.Errorf("Admin.UpdateTeamLDAPMapping returned %+v, want %+v", mapping, want) } + + // Test s.client.NewRequest failure + client.BaseURL.Path = "" + got, resp, err := client.Admin.UpdateTeamLDAPMapping(ctx, 1, input) + if got != nil { + t.Errorf("client.BaseURL.Path='' UpdateTeamLDAPMapping = %#v, want nil", got) + } + if resp != nil { + t.Errorf("client.BaseURL.Path='' UpdateTeamLDAPMapping resp = %#v, want nil", resp) + } + if err == nil { + t.Error("client.BaseURL.Path='' UpdateTeamLDAPMapping err = nil, want error") + } + + // Test s.client.Do failure + client.BaseURL.Path = "/api-v3/" + client.rateLimits[0].Reset.Time = time.Now().Add(10 * time.Minute) + got, resp, err = client.Admin.UpdateTeamLDAPMapping(ctx, 1, input) + if got != nil { + t.Errorf("rate.Reset.Time > now UpdateTeamLDAPMapping = %#v, want nil", got) + } + if want := http.StatusForbidden; resp == nil || resp.Response.StatusCode != want { + t.Errorf("rate.Reset.Time > now UpdateTeamLDAPMapping resp = %#v, want StatusCode=%v", resp.Response, want) + } + if err == nil { + t.Error("rate.Reset.Time > now UpdateTeamLDAPMapping err = nil, want error") + } +} + +func TestAdminService_TeamLDAPMapping_String(t *testing.T) { + v := &TeamLDAPMapping{ + ID: Int64(1), + LDAPDN: String("a"), + URL: String("b"), + Name: String("c"), + Slug: String("d"), + Description: String("e"), + Privacy: String("f"), + Permission: String("g"), + MembersURL: String("h"), + RepositoriesURL: String("i"), + } + + want := `github.TeamLDAPMapping{ID:1, LDAPDN:"a", URL:"b", Name:"c", Slug:"d", Description:"e", Privacy:"f", Permission:"g", MembersURL:"h", RepositoriesURL:"i"}` + if got := v.String(); got != want { + t.Errorf("TeamLDAPMapping.String = `%v`, want `%v`", got, want) + } +} + +func TestAdminService_UserLDAPMapping_String(t *testing.T) { + v := &UserLDAPMapping{ + ID: Int64(1), + LDAPDN: String("a"), + Login: String("b"), + AvatarURL: String("c"), + GravatarID: String("d"), + Type: String("e"), + SiteAdmin: Bool(true), + URL: String("f"), + EventsURL: String("g"), + FollowingURL: String("h"), + FollowersURL: String("i"), + GistsURL: String("j"), + OrganizationsURL: String("k"), + ReceivedEventsURL: String("l"), + ReposURL: String("m"), + StarredURL: String("n"), + SubscriptionsURL: String("o"), + } + + want := `github.UserLDAPMapping{ID:1, LDAPDN:"a", Login:"b", AvatarURL:"c", GravatarID:"d", Type:"e", SiteAdmin:true, URL:"f", EventsURL:"g", FollowingURL:"h", FollowersURL:"i", GistsURL:"j", OrganizationsURL:"k", ReceivedEventsURL:"l", ReposURL:"m", StarredURL:"n", SubscriptionsURL:"o"}` + if got := v.String(); got != want { + t.Errorf("UserLDAPMapping.String = `%v`, want `%v`", got, want) + } } From ac1f352733b7749aac32bcc0dcee16970659b468 Mon Sep 17 00:00:00 2001 From: Eddy Reyes Date: Fri, 14 Jun 2019 08:16:26 -0500 Subject: [PATCH 0009/1468] Adds Type and Issue fields to timeline Source (#511) Helps #510. --- github/issues_timeline.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/github/issues_timeline.go b/github/issues_timeline.go index d0e4a3a9428..8d76e27be17 100644 --- a/github/issues_timeline.go +++ b/github/issues_timeline.go @@ -124,6 +124,8 @@ type Timeline struct { type Source struct { ID *int64 `json:"id,omitempty"` URL *string `json:"url,omitempty"` + Type *string `json:"type,omitempty"` + Issue *Issue `json:"issue,omitempty"` Actor *User `json:"actor,omitempty"` Type *string `json:"type,omitempty"` Issue *Issue `json:"issue,omitempty"` From 6c7910aba3541e857ee0e9ad7a8fa6e5a9353e30 Mon Sep 17 00:00:00 2001 From: Glenn Lewis <6598971+gmlewis@users.noreply.github.com> Date: Fri, 14 Jun 2019 09:24:55 -0400 Subject: [PATCH 0010/1468] Revert "Adds Type and Issue fields to timeline Source (#511)" (#1197) This reverts commit ac1f352733b7749aac32bcc0dcee16970659b468. --- github/issues_timeline.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/github/issues_timeline.go b/github/issues_timeline.go index 8d76e27be17..d0e4a3a9428 100644 --- a/github/issues_timeline.go +++ b/github/issues_timeline.go @@ -124,8 +124,6 @@ type Timeline struct { type Source struct { ID *int64 `json:"id,omitempty"` URL *string `json:"url,omitempty"` - Type *string `json:"type,omitempty"` - Issue *Issue `json:"issue,omitempty"` Actor *User `json:"actor,omitempty"` Type *string `json:"type,omitempty"` Issue *Issue `json:"issue,omitempty"` From 7a8ff7a9b90963cdf49e959a5e8009ea03138ff1 Mon Sep 17 00:00:00 2001 From: Mark Tareshawty Date: Wed, 19 Jun 2019 06:25:48 -0700 Subject: [PATCH 0011/1468] Add missing permissions to InstallationPermissions (#1180) --- github/apps.go | 34 ++++++-- github/apps_test.go | 52 ++++++++++-- github/github-accessors.go | 160 +++++++++++++++++++++++++++++++++++++ 3 files changed, 235 insertions(+), 11 deletions(-) diff --git a/github/apps.go b/github/apps.go index 80dfb3c8451..f675a9abd18 100644 --- a/github/apps.go +++ b/github/apps.go @@ -36,12 +36,36 @@ type InstallationToken struct { ExpiresAt *time.Time `json:"expires_at,omitempty"` } -// InstallationPermissions lists the permissions for metadata, contents, issues and single file for an installation. +// InstallationPermissions lists the repository and organization permissions for an installation. +// +// Permission names taken from: +// https://developer.github.com/v3/apps/permissions/ +// https://developer.github.com/enterprise/v3/apps/permissions/ type InstallationPermissions struct { - Metadata *string `json:"metadata,omitempty"` - Contents *string `json:"contents,omitempty"` - Issues *string `json:"issues,omitempty"` - SingleFile *string `json:"single_file,omitempty"` + Administration *string `json:"administration,omitempty"` + Checks *string `json:"checks,omitempty"` + Contents *string `json:"contents,omitempty"` + ContentReferences *string `json:"content_references,omitempty"` + Deployments *string `json:"deployments,omitempty"` + Issues *string `json:"issues,omitempty"` + Metadata *string `json:"metadata,omitempty"` + Members *string `json:"members,omitempty"` + OrganizationAdministration *string `json:"organization_administration,omitempty"` + OrganizationHooks *string `json:"organization_hooks,omitempty"` + OrganizationPlan *string `json:"organization_plan,omitempty"` + OrganizationPreReceiveHooks *string `json:"organization_pre_receive_hooks,omitempty"` + OrganizationProjects *string `json:"organization_projects,omitempty"` + OrganizationUserBlocking *string `json:"organization_user_blocking,omitempty"` + Packages *string `json:"packages,omitempty"` + Pages *string `json:"pages,omitempty"` + PullRequests *string `json:"pull_requests,omitempty"` + RepositoryHooks *string `json:"repository_hooks,omitempty"` + RepositoryProjects *string `json:"repository_projects,omitempty"` + RepositoryPreReceiveHooks *string `json:"repository_pre_receive_hooks,omitempty"` + SingleFile *string `json:"single_file,omitempty"` + Statuses *string `json:"statuses,omitempty"` + TeamDiscussions *string `json:"team_discussions,omitempty"` + VulnerabilityAlerts *string `json:"vulnerability_alerts,omitempty"` } // Installation represents a GitHub Apps installation. diff --git a/github/apps_test.go b/github/apps_test.go index 8456662b7d1..8d5b27d38ce 100644 --- a/github/apps_test.go +++ b/github/apps_test.go @@ -73,10 +73,30 @@ func TestAppsService_ListInstallations(t *testing.T) { "target_id":1, "target_type": "Organization", "permissions": { - "metadata": "read", + "administration": "read", + "checks": "read", "contents": "read", + "content_references": "read", + "deployments": "read", "issues": "write", - "single_file": "write" + "metadata": "read", + "members": "read", + "organization_administration": "write", + "organization_hooks": "write", + "organization_plan": "read", + "organization_pre_receive_hooks": "write", + "organization_projects": "read", + "organization_user_blocking": "write", + "packages": "read", + "pages": "read", + "pull_requests": "write", + "repository_hooks": "write", + "repository_projects": "read", + "repository_pre_receive_hooks": "read", + "single_file": "write", + "statuses": "write", + "team_discussions": "read", + "vulnerability_alerts": "read" }, "events": [ "push", @@ -104,10 +124,30 @@ func TestAppsService_ListInstallations(t *testing.T) { SingleFileName: String("config.yml"), RepositorySelection: String("selected"), Permissions: &InstallationPermissions{ - Metadata: String("read"), - Contents: String("read"), - Issues: String("write"), - SingleFile: String("write")}, + Administration: String("read"), + Checks: String("read"), + Contents: String("read"), + ContentReferences: String("read"), + Deployments: String("read"), + Issues: String("write"), + Metadata: String("read"), + Members: String("read"), + OrganizationAdministration: String("write"), + OrganizationHooks: String("write"), + OrganizationPlan: String("read"), + OrganizationPreReceiveHooks: String("write"), + OrganizationProjects: String("read"), + OrganizationUserBlocking: String("write"), + Packages: String("read"), + Pages: String("read"), + PullRequests: String("write"), + RepositoryHooks: String("write"), + RepositoryProjects: String("read"), + RepositoryPreReceiveHooks: String("read"), + SingleFile: String("write"), + Statuses: String("write"), + TeamDiscussions: String("read"), + VulnerabilityAlerts: String("read")}, Events: []string{"push", "pull_request"}, CreatedAt: &date, UpdatedAt: &date, diff --git a/github/github-accessors.go b/github/github-accessors.go index 9cd331038e5..0bb206bd509 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -3628,6 +3628,30 @@ func (i *InstallationEvent) GetSender() *User { return i.Sender } +// GetAdministration returns the Administration field if it's non-nil, zero value otherwise. +func (i *InstallationPermissions) GetAdministration() string { + if i == nil || i.Administration == nil { + return "" + } + return *i.Administration +} + +// GetChecks returns the Checks field if it's non-nil, zero value otherwise. +func (i *InstallationPermissions) GetChecks() string { + if i == nil || i.Checks == nil { + return "" + } + return *i.Checks +} + +// GetContentReferences returns the ContentReferences field if it's non-nil, zero value otherwise. +func (i *InstallationPermissions) GetContentReferences() string { + if i == nil || i.ContentReferences == nil { + return "" + } + return *i.ContentReferences +} + // GetContents returns the Contents field if it's non-nil, zero value otherwise. func (i *InstallationPermissions) GetContents() string { if i == nil || i.Contents == nil { @@ -3636,6 +3660,14 @@ func (i *InstallationPermissions) GetContents() string { return *i.Contents } +// GetDeployments returns the Deployments field if it's non-nil, zero value otherwise. +func (i *InstallationPermissions) GetDeployments() string { + if i == nil || i.Deployments == nil { + return "" + } + return *i.Deployments +} + // GetIssues returns the Issues field if it's non-nil, zero value otherwise. func (i *InstallationPermissions) GetIssues() string { if i == nil || i.Issues == nil { @@ -3644,6 +3676,14 @@ func (i *InstallationPermissions) GetIssues() string { return *i.Issues } +// GetMembers returns the Members field if it's non-nil, zero value otherwise. +func (i *InstallationPermissions) GetMembers() string { + if i == nil || i.Members == nil { + return "" + } + return *i.Members +} + // GetMetadata returns the Metadata field if it's non-nil, zero value otherwise. func (i *InstallationPermissions) GetMetadata() string { if i == nil || i.Metadata == nil { @@ -3652,6 +3692,102 @@ func (i *InstallationPermissions) GetMetadata() string { return *i.Metadata } +// GetOrganizationAdministration returns the OrganizationAdministration field if it's non-nil, zero value otherwise. +func (i *InstallationPermissions) GetOrganizationAdministration() string { + if i == nil || i.OrganizationAdministration == nil { + return "" + } + return *i.OrganizationAdministration +} + +// GetOrganizationHooks returns the OrganizationHooks field if it's non-nil, zero value otherwise. +func (i *InstallationPermissions) GetOrganizationHooks() string { + if i == nil || i.OrganizationHooks == nil { + return "" + } + return *i.OrganizationHooks +} + +// GetOrganizationPlan returns the OrganizationPlan field if it's non-nil, zero value otherwise. +func (i *InstallationPermissions) GetOrganizationPlan() string { + if i == nil || i.OrganizationPlan == nil { + return "" + } + return *i.OrganizationPlan +} + +// GetOrganizationPreReceiveHooks returns the OrganizationPreReceiveHooks field if it's non-nil, zero value otherwise. +func (i *InstallationPermissions) GetOrganizationPreReceiveHooks() string { + if i == nil || i.OrganizationPreReceiveHooks == nil { + return "" + } + return *i.OrganizationPreReceiveHooks +} + +// GetOrganizationProjects returns the OrganizationProjects field if it's non-nil, zero value otherwise. +func (i *InstallationPermissions) GetOrganizationProjects() string { + if i == nil || i.OrganizationProjects == nil { + return "" + } + return *i.OrganizationProjects +} + +// GetOrganizationUserBlocking returns the OrganizationUserBlocking field if it's non-nil, zero value otherwise. +func (i *InstallationPermissions) GetOrganizationUserBlocking() string { + if i == nil || i.OrganizationUserBlocking == nil { + return "" + } + return *i.OrganizationUserBlocking +} + +// GetPackages returns the Packages field if it's non-nil, zero value otherwise. +func (i *InstallationPermissions) GetPackages() string { + if i == nil || i.Packages == nil { + return "" + } + return *i.Packages +} + +// GetPages returns the Pages field if it's non-nil, zero value otherwise. +func (i *InstallationPermissions) GetPages() string { + if i == nil || i.Pages == nil { + return "" + } + return *i.Pages +} + +// GetPullRequests returns the PullRequests field if it's non-nil, zero value otherwise. +func (i *InstallationPermissions) GetPullRequests() string { + if i == nil || i.PullRequests == nil { + return "" + } + return *i.PullRequests +} + +// GetRepositoryHooks returns the RepositoryHooks field if it's non-nil, zero value otherwise. +func (i *InstallationPermissions) GetRepositoryHooks() string { + if i == nil || i.RepositoryHooks == nil { + return "" + } + return *i.RepositoryHooks +} + +// GetRepositoryPreReceiveHooks returns the RepositoryPreReceiveHooks field if it's non-nil, zero value otherwise. +func (i *InstallationPermissions) GetRepositoryPreReceiveHooks() string { + if i == nil || i.RepositoryPreReceiveHooks == nil { + return "" + } + return *i.RepositoryPreReceiveHooks +} + +// GetRepositoryProjects returns the RepositoryProjects field if it's non-nil, zero value otherwise. +func (i *InstallationPermissions) GetRepositoryProjects() string { + if i == nil || i.RepositoryProjects == nil { + return "" + } + return *i.RepositoryProjects +} + // GetSingleFile returns the SingleFile field if it's non-nil, zero value otherwise. func (i *InstallationPermissions) GetSingleFile() string { if i == nil || i.SingleFile == nil { @@ -3660,6 +3796,30 @@ func (i *InstallationPermissions) GetSingleFile() string { return *i.SingleFile } +// GetStatuses returns the Statuses field if it's non-nil, zero value otherwise. +func (i *InstallationPermissions) GetStatuses() string { + if i == nil || i.Statuses == nil { + return "" + } + return *i.Statuses +} + +// GetTeamDiscussions returns the TeamDiscussions field if it's non-nil, zero value otherwise. +func (i *InstallationPermissions) GetTeamDiscussions() string { + if i == nil || i.TeamDiscussions == nil { + return "" + } + return *i.TeamDiscussions +} + +// GetVulnerabilityAlerts returns the VulnerabilityAlerts field if it's non-nil, zero value otherwise. +func (i *InstallationPermissions) GetVulnerabilityAlerts() string { + if i == nil || i.VulnerabilityAlerts == nil { + return "" + } + return *i.VulnerabilityAlerts +} + // GetAction returns the Action field if it's non-nil, zero value otherwise. func (i *InstallationRepositoriesEvent) GetAction() string { if i == nil || i.Action == nil { From 0573e88402f1db392537e0cbb2c79f1c03d1c6a0 Mon Sep 17 00:00:00 2001 From: Glenn Lewis <6598971+gmlewis@users.noreply.github.com> Date: Thu, 20 Jun 2019 21:47:17 -0400 Subject: [PATCH 0012/1468] Add gen-stringify-test.go (#1196) --- github/gen-accessors.go | 5 +- github/gen-stringify-test.go | 358 +++++++ github/github-stringify_test.go | 1661 +++++++++++++++++++++++++++++++ github/github.go | 1 + github/github_test.go | 11 + 5 files changed, 2034 insertions(+), 2 deletions(-) create mode 100644 github/gen-stringify-test.go create mode 100644 github/github-stringify_test.go diff --git a/github/gen-accessors.go b/github/gen-accessors.go index fe92206fcf8..4c5e8eec7e7 100644 --- a/github/gen-accessors.go +++ b/github/gen-accessors.go @@ -7,8 +7,9 @@ // gen-accessors generates accessor methods for structs with pointer fields. // -// It is meant to be used by the go-github authors in conjunction with the -// go generate tool before sending a commit to GitHub. +// It is meant to be used by go-github contributors in conjunction with the +// go generate tool before sending a PR to GitHub. +// Please see the CONTRIBUTING.md file for more information. package main import ( diff --git a/github/gen-stringify-test.go b/github/gen-stringify-test.go new file mode 100644 index 00000000000..7803801e632 --- /dev/null +++ b/github/gen-stringify-test.go @@ -0,0 +1,358 @@ +// Copyright 2019 The go-github AUTHORS. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build ignore + +// gen-stringify-test generates test methods to test the String methods. +// +// These tests eliminate most of the code coverage problems so that real +// code coverage issues can be more readily identified. +// +// It is meant to be used by go-github contributors in conjunction with the +// go generate tool before sending a PR to GitHub. +// Please see the CONTRIBUTING.md file for more information. +package main + +import ( + "bytes" + "flag" + "fmt" + "go/ast" + "go/format" + "go/parser" + "go/token" + "io/ioutil" + "log" + "os" + "strings" + "text/template" +) + +const ( + ignoreFilePrefix1 = "gen-" + ignoreFilePrefix2 = "github-" + outputFileSuffix = "-stringify_test.go" +) + +var ( + verbose = flag.Bool("v", false, "Print verbose log messages") + + // blacklistStructMethod lists "struct.method" combos to skip. + blacklistStructMethod = map[string]bool{} + // blacklistStruct lists structs to skip. + blacklistStruct = map[string]bool{ + "RateLimits": true, + } + + funcMap = template.FuncMap{ + "isNotLast": func(index int, slice []*structField) string { + if index+1 < len(slice) { + return ", " + } + return "" + }, + "processZeroValue": func(v string) string { + switch v { + case "Bool(false)": + return "false" + case "Float64(0.0)": + return "0" + case "0", "Int(0)", "Int64(0)": + return "0" + case `""`, `String("")`: + return `""` + case "Timestamp{}", "&Timestamp{}": + return "github.Timestamp{0001-01-01 00:00:00 +0000 UTC}" + case "nil": + return "map[]" + } + log.Fatalf("Unhandled zero value: %q", v) + return "" + }, + } + + sourceTmpl = template.Must(template.New("source").Funcs(funcMap).Parse(source)) +) + +func main() { + flag.Parse() + fset := token.NewFileSet() + + pkgs, err := parser.ParseDir(fset, ".", sourceFilter, 0) + if err != nil { + log.Fatal(err) + return + } + + for pkgName, pkg := range pkgs { + t := &templateData{ + filename: pkgName + outputFileSuffix, + Year: 2019, // No need to change this once set (even in following years). + Package: pkgName, + Imports: map[string]string{"testing": "testing"}, + StringFuncs: map[string]bool{}, + StructFields: map[string][]*structField{}, + } + for filename, f := range pkg.Files { + logf("Processing %v...", filename) + if err := t.processAST(f); err != nil { + log.Fatal(err) + } + } + if err := t.dump(); err != nil { + log.Fatal(err) + } + } + logf("Done.") +} + +func sourceFilter(fi os.FileInfo) bool { + return !strings.HasSuffix(fi.Name(), "_test.go") && + !strings.HasPrefix(fi.Name(), ignoreFilePrefix1) && + !strings.HasPrefix(fi.Name(), ignoreFilePrefix2) +} + +type templateData struct { + filename string + Year int + Package string + Imports map[string]string + StringFuncs map[string]bool + StructFields map[string][]*structField +} + +type structField struct { + sortVal string // Lower-case version of "ReceiverType.FieldName". + ReceiverVar string // The one-letter variable name to match the ReceiverType. + ReceiverType string + FieldName string + FieldType string + ZeroValue string + NamedStruct bool // Getter for named struct. +} + +func (t *templateData) processAST(f *ast.File) error { + for _, decl := range f.Decls { + fn, ok := decl.(*ast.FuncDecl) + if ok { + if fn.Recv != nil && len(fn.Recv.List) > 0 { + id, ok := fn.Recv.List[0].Type.(*ast.Ident) + if ok && fn.Name.Name == "String" { + logf("Got FuncDecl: Name=%q, id.Name=%#v", fn.Name.Name, id.Name) + t.StringFuncs[id.Name] = true + } else { + logf("Ignoring FuncDecl: Name=%q, Type=%T", fn.Name.Name, fn.Recv.List[0].Type) + } + } else { + logf("Ignoring FuncDecl: Name=%q, fn=%#v", fn.Name.Name, fn) + } + continue + } + + gd, ok := decl.(*ast.GenDecl) + if !ok { + logf("Ignoring AST decl type %T", decl) + continue + } + for _, spec := range gd.Specs { + ts, ok := spec.(*ast.TypeSpec) + if !ok { + continue + } + // Skip unexported identifiers. + if !ts.Name.IsExported() { + logf("Struct %v is unexported; skipping.", ts.Name) + continue + } + // Check if the struct is blacklisted. + if blacklistStruct[ts.Name.Name] { + logf("Struct %v is blacklisted; skipping.", ts.Name) + continue + } + st, ok := ts.Type.(*ast.StructType) + if !ok { + logf("Ignoring AST type %T, Name=%q", ts.Type, ts.Name.String()) + continue + } + for _, field := range st.Fields.List { + if len(field.Names) == 0 { + continue + } + + fieldName := field.Names[0] + if id, ok := field.Type.(*ast.Ident); ok { + t.addIdent(id, ts.Name.String(), fieldName.String()) + continue + } + + if _, ok := field.Type.(*ast.MapType); ok { + t.addMapType(ts.Name.String(), fieldName.String()) + continue + } + + se, ok := field.Type.(*ast.StarExpr) + if !ok { + logf("Ignoring type %T for Name=%q, FieldName=%q", field.Type, ts.Name.String(), fieldName.String()) + continue + } + + // Skip unexported identifiers. + if !fieldName.IsExported() { + logf("Field %v is unexported; skipping.", fieldName) + continue + } + // Check if "struct.method" is blacklisted. + if key := fmt.Sprintf("%v.Get%v", ts.Name, fieldName); blacklistStructMethod[key] { + logf("Method %v is blacklisted; skipping.", key) + continue + } + + switch x := se.X.(type) { + case *ast.ArrayType: + case *ast.Ident: + t.addIdentPtr(x, ts.Name.String(), fieldName.String()) + case *ast.MapType: + case *ast.SelectorExpr: + default: + logf("processAST: type %q, field %q, unknown %T: %+v", ts.Name, fieldName, x, x) + } + } + } + } + return nil +} + +func (t *templateData) addMapType(receiverType, fieldName string) { + t.StructFields[receiverType] = append(t.StructFields[receiverType], newStructField(receiverType, fieldName, "map[]", "nil", false)) +} + +func (t *templateData) addIdent(x *ast.Ident, receiverType, fieldName string) { + var zeroValue string + var namedStruct = false + switch x.String() { + case "int": + zeroValue = "0" + case "int64": + zeroValue = "0" + case "float64": + zeroValue = "0.0" + case "string": + zeroValue = `""` + case "bool": + zeroValue = "false" + case "Timestamp": + zeroValue = "Timestamp{}" + default: + zeroValue = "nil" + namedStruct = true + } + + t.StructFields[receiverType] = append(t.StructFields[receiverType], newStructField(receiverType, fieldName, x.String(), zeroValue, namedStruct)) +} + +func (t *templateData) addIdentPtr(x *ast.Ident, receiverType, fieldName string) { + var zeroValue string + var namedStruct = false + switch x.String() { + case "int": + zeroValue = "Int(0)" + case "int64": + zeroValue = "Int64(0)" + case "float64": + zeroValue = "Float64(0.0)" + case "string": + zeroValue = `String("")` + case "bool": + zeroValue = "Bool(false)" + case "Timestamp": + zeroValue = "&Timestamp{}" + default: + zeroValue = "nil" + namedStruct = true + } + + t.StructFields[receiverType] = append(t.StructFields[receiverType], newStructField(receiverType, fieldName, x.String(), zeroValue, namedStruct)) +} + +func (t *templateData) dump() error { + if len(t.StructFields) == 0 { + logf("No StructFields for %v; skipping.", t.filename) + return nil + } + + // Remove unused structs. + var toDelete []string + for k := range t.StructFields { + if !t.StringFuncs[k] { + toDelete = append(toDelete, k) + continue + } + } + for _, k := range toDelete { + delete(t.StructFields, k) + } + + var buf bytes.Buffer + if err := sourceTmpl.Execute(&buf, t); err != nil { + return err + } + clean, err := format.Source(buf.Bytes()) + if err != nil { + log.Printf("failed-to-format source:\n%v", buf.String()) + return err + } + + logf("Writing %v...", t.filename) + return ioutil.WriteFile(t.filename, clean, 0644) +} + +func newStructField(receiverType, fieldName, fieldType, zeroValue string, namedStruct bool) *structField { + return &structField{ + sortVal: strings.ToLower(receiverType) + "." + strings.ToLower(fieldName), + ReceiverVar: strings.ToLower(receiverType[:1]), + ReceiverType: receiverType, + FieldName: fieldName, + FieldType: fieldType, + ZeroValue: zeroValue, + NamedStruct: namedStruct, + } +} + +func logf(fmt string, args ...interface{}) { + if *verbose { + log.Printf(fmt, args...) + } +} + +const source = `// Copyright {{.Year}} The go-github AUTHORS. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Code generated by gen-stringify-tests; DO NOT EDIT. + +package {{ $package := .Package}}{{$package}} +{{with .Imports}} +import ( + {{- range . -}} + "{{.}}" + {{end -}} +) +{{end}} +func Float64(v float64) *float64 { return &v } +{{range $key, $value := .StructFields}} +func Test{{ $key }}_String(t *testing.T) { + v := {{ $key }}{ {{range .}}{{if .NamedStruct}} + {{ .FieldName }}: &{{ .FieldType }}{},{{else}} + {{ .FieldName }}: {{.ZeroValue}},{{end}}{{end}} + } + want := ` + "`" + `{{ $package }}.{{ $key }}{{ $slice := . }}{ +{{- range $ind, $val := .}}{{if .NamedStruct}}{{ .FieldName }}:{{ $package }}.{{ .FieldType }}{}{{else}}{{ .FieldName }}:{{ processZeroValue .ZeroValue }}{{end}}{{ isNotLast $ind $slice }}{{end}}}` + "`" + ` + if got := v.String(); got != want { + t.Errorf("{{ $key }}.String = %v, want %v", got, want) + } +} +{{end}} +` diff --git a/github/github-stringify_test.go b/github/github-stringify_test.go new file mode 100644 index 00000000000..2271a9d2b11 --- /dev/null +++ b/github/github-stringify_test.go @@ -0,0 +1,1661 @@ +// Copyright 2019 The go-github AUTHORS. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Code generated by gen-stringify-tests; DO NOT EDIT. + +package github + +import ( + "testing" +) + +func Float64(v float64) *float64 { return &v } + +func TestAdminStats_String(t *testing.T) { + v := AdminStats{ + Issues: &IssueStats{}, + Hooks: &HookStats{}, + Milestones: &MilestoneStats{}, + Orgs: &OrgStats{}, + Comments: &CommentStats{}, + Pages: &PageStats{}, + Users: &UserStats{}, + Gists: &GistStats{}, + Pulls: &PullStats{}, + Repos: &RepoStats{}, + } + want := `github.AdminStats{Issues:github.IssueStats{}, Hooks:github.HookStats{}, Milestones:github.MilestoneStats{}, Orgs:github.OrgStats{}, Comments:github.CommentStats{}, Pages:github.PageStats{}, Users:github.UserStats{}, Gists:github.GistStats{}, Pulls:github.PullStats{}, Repos:github.RepoStats{}}` + if got := v.String(); got != want { + t.Errorf("AdminStats.String = %v, want %v", got, want) + } +} + +func TestAuthorization_String(t *testing.T) { + v := Authorization{ + ID: Int64(0), + URL: String(""), + Token: String(""), + TokenLastEight: String(""), + HashedToken: String(""), + App: &AuthorizationApp{}, + Note: String(""), + NoteURL: String(""), + UpdatedAt: &Timestamp{}, + CreatedAt: &Timestamp{}, + Fingerprint: String(""), + User: &User{}, + } + want := `github.Authorization{ID:0, URL:"", Token:"", TokenLastEight:"", HashedToken:"", App:github.AuthorizationApp{}, Note:"", NoteURL:"", UpdatedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, CreatedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, Fingerprint:"", User:github.User{}}` + if got := v.String(); got != want { + t.Errorf("Authorization.String = %v, want %v", got, want) + } +} + +func TestAuthorizationApp_String(t *testing.T) { + v := AuthorizationApp{ + URL: String(""), + Name: String(""), + ClientID: String(""), + } + want := `github.AuthorizationApp{URL:"", Name:"", ClientID:""}` + if got := v.String(); got != want { + t.Errorf("AuthorizationApp.String = %v, want %v", got, want) + } +} + +func TestAuthorizationRequest_String(t *testing.T) { + v := AuthorizationRequest{ + Note: String(""), + NoteURL: String(""), + ClientID: String(""), + ClientSecret: String(""), + Fingerprint: String(""), + } + want := `github.AuthorizationRequest{Note:"", NoteURL:"", ClientID:"", ClientSecret:"", Fingerprint:""}` + if got := v.String(); got != want { + t.Errorf("AuthorizationRequest.String = %v, want %v", got, want) + } +} + +func TestAuthorizationUpdateRequest_String(t *testing.T) { + v := AuthorizationUpdateRequest{ + Note: String(""), + NoteURL: String(""), + Fingerprint: String(""), + } + want := `github.AuthorizationUpdateRequest{Note:"", NoteURL:"", Fingerprint:""}` + if got := v.String(); got != want { + t.Errorf("AuthorizationUpdateRequest.String = %v, want %v", got, want) + } +} + +func TestCheckRun_String(t *testing.T) { + v := CheckRun{ + ID: Int64(0), + NodeID: String(""), + HeadSHA: String(""), + ExternalID: String(""), + URL: String(""), + HTMLURL: String(""), + DetailsURL: String(""), + Status: String(""), + Conclusion: String(""), + StartedAt: &Timestamp{}, + CompletedAt: &Timestamp{}, + Output: &CheckRunOutput{}, + Name: String(""), + CheckSuite: &CheckSuite{}, + App: &App{}, + } + want := `github.CheckRun{ID:0, NodeID:"", HeadSHA:"", ExternalID:"", URL:"", HTMLURL:"", DetailsURL:"", Status:"", Conclusion:"", StartedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, CompletedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, Output:github.CheckRunOutput{}, Name:"", CheckSuite:github.CheckSuite{}, App:github.App{}}` + if got := v.String(); got != want { + t.Errorf("CheckRun.String = %v, want %v", got, want) + } +} + +func TestCheckSuite_String(t *testing.T) { + v := CheckSuite{ + ID: Int64(0), + NodeID: String(""), + HeadBranch: String(""), + HeadSHA: String(""), + URL: String(""), + BeforeSHA: String(""), + AfterSHA: String(""), + Status: String(""), + Conclusion: String(""), + App: &App{}, + Repository: &Repository{}, + HeadCommit: &Commit{}, + } + want := `github.CheckSuite{ID:0, NodeID:"", HeadBranch:"", HeadSHA:"", URL:"", BeforeSHA:"", AfterSHA:"", Status:"", Conclusion:"", App:github.App{}, Repository:github.Repository{}, HeadCommit:github.Commit{}}` + if got := v.String(); got != want { + t.Errorf("CheckSuite.String = %v, want %v", got, want) + } +} + +func TestCodeResult_String(t *testing.T) { + v := CodeResult{ + Name: String(""), + Path: String(""), + SHA: String(""), + HTMLURL: String(""), + Repository: &Repository{}, + } + want := `github.CodeResult{Name:"", Path:"", SHA:"", HTMLURL:"", Repository:github.Repository{}}` + if got := v.String(); got != want { + t.Errorf("CodeResult.String = %v, want %v", got, want) + } +} + +func TestCombinedStatus_String(t *testing.T) { + v := CombinedStatus{ + State: String(""), + Name: String(""), + SHA: String(""), + TotalCount: Int(0), + CommitURL: String(""), + RepositoryURL: String(""), + } + want := `github.CombinedStatus{State:"", Name:"", SHA:"", TotalCount:0, CommitURL:"", RepositoryURL:""}` + if got := v.String(); got != want { + t.Errorf("CombinedStatus.String = %v, want %v", got, want) + } +} + +func TestCommentStats_String(t *testing.T) { + v := CommentStats{ + TotalCommitComments: Int(0), + TotalGistComments: Int(0), + TotalIssueComments: Int(0), + TotalPullRequestComments: Int(0), + } + want := `github.CommentStats{TotalCommitComments:0, TotalGistComments:0, TotalIssueComments:0, TotalPullRequestComments:0}` + if got := v.String(); got != want { + t.Errorf("CommentStats.String = %v, want %v", got, want) + } +} + +func TestCommit_String(t *testing.T) { + v := Commit{ + SHA: String(""), + Author: &CommitAuthor{}, + Committer: &CommitAuthor{}, + Message: String(""), + Tree: &Tree{}, + Stats: &CommitStats{}, + HTMLURL: String(""), + URL: String(""), + Verification: &SignatureVerification{}, + NodeID: String(""), + CommentCount: Int(0), + } + want := `github.Commit{SHA:"", Author:github.CommitAuthor{}, Committer:github.CommitAuthor{}, Message:"", Tree:github.Tree{}, Stats:github.CommitStats{}, HTMLURL:"", URL:"", Verification:github.SignatureVerification{}, NodeID:"", CommentCount:0}` + if got := v.String(); got != want { + t.Errorf("Commit.String = %v, want %v", got, want) + } +} + +func TestCommitAuthor_String(t *testing.T) { + v := CommitAuthor{ + Name: String(""), + Email: String(""), + Login: String(""), + } + want := `github.CommitAuthor{Name:"", Email:"", Login:""}` + if got := v.String(); got != want { + t.Errorf("CommitAuthor.String = %v, want %v", got, want) + } +} + +func TestCommitFile_String(t *testing.T) { + v := CommitFile{ + SHA: String(""), + Filename: String(""), + Additions: Int(0), + Deletions: Int(0), + Changes: Int(0), + Status: String(""), + Patch: String(""), + BlobURL: String(""), + RawURL: String(""), + ContentsURL: String(""), + PreviousFilename: String(""), + } + want := `github.CommitFile{SHA:"", Filename:"", Additions:0, Deletions:0, Changes:0, Status:"", Patch:"", BlobURL:"", RawURL:"", ContentsURL:"", PreviousFilename:""}` + if got := v.String(); got != want { + t.Errorf("CommitFile.String = %v, want %v", got, want) + } +} + +func TestCommitStats_String(t *testing.T) { + v := CommitStats{ + Additions: Int(0), + Deletions: Int(0), + Total: Int(0), + } + want := `github.CommitStats{Additions:0, Deletions:0, Total:0}` + if got := v.String(); got != want { + t.Errorf("CommitStats.String = %v, want %v", got, want) + } +} + +func TestCommitsComparison_String(t *testing.T) { + v := CommitsComparison{ + BaseCommit: &RepositoryCommit{}, + MergeBaseCommit: &RepositoryCommit{}, + Status: String(""), + AheadBy: Int(0), + BehindBy: Int(0), + TotalCommits: Int(0), + HTMLURL: String(""), + PermalinkURL: String(""), + DiffURL: String(""), + PatchURL: String(""), + URL: String(""), + } + want := `github.CommitsComparison{BaseCommit:github.RepositoryCommit{}, MergeBaseCommit:github.RepositoryCommit{}, Status:"", AheadBy:0, BehindBy:0, TotalCommits:0, HTMLURL:"", PermalinkURL:"", DiffURL:"", PatchURL:"", URL:""}` + if got := v.String(); got != want { + t.Errorf("CommitsComparison.String = %v, want %v", got, want) + } +} + +func TestContributorStats_String(t *testing.T) { + v := ContributorStats{ + Author: &Contributor{}, + Total: Int(0), + } + want := `github.ContributorStats{Author:github.Contributor{}, Total:0}` + if got := v.String(); got != want { + t.Errorf("ContributorStats.String = %v, want %v", got, want) + } +} + +func TestDiscussionComment_String(t *testing.T) { + v := DiscussionComment{ + Author: &User{}, + Body: String(""), + BodyHTML: String(""), + BodyVersion: String(""), + CreatedAt: &Timestamp{}, + LastEditedAt: &Timestamp{}, + DiscussionURL: String(""), + HTMLURL: String(""), + NodeID: String(""), + Number: Int(0), + UpdatedAt: &Timestamp{}, + URL: String(""), + Reactions: &Reactions{}, + } + want := `github.DiscussionComment{Author:github.User{}, Body:"", BodyHTML:"", BodyVersion:"", CreatedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, LastEditedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, DiscussionURL:"", HTMLURL:"", NodeID:"", Number:0, UpdatedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, URL:"", Reactions:github.Reactions{}}` + if got := v.String(); got != want { + t.Errorf("DiscussionComment.String = %v, want %v", got, want) + } +} + +func TestDraftReviewComment_String(t *testing.T) { + v := DraftReviewComment{ + Path: String(""), + Position: Int(0), + Body: String(""), + } + want := `github.DraftReviewComment{Path:"", Position:0, Body:""}` + if got := v.String(); got != want { + t.Errorf("DraftReviewComment.String = %v, want %v", got, want) + } +} + +func TestEvent_String(t *testing.T) { + v := Event{ + Type: String(""), + Public: Bool(false), + Repo: &Repository{}, + Actor: &User{}, + Org: &Organization{}, + ID: String(""), + } + want := `github.Event{Type:"", Public:false, Repo:github.Repository{}, Actor:github.User{}, Org:github.Organization{}, ID:""}` + if got := v.String(); got != want { + t.Errorf("Event.String = %v, want %v", got, want) + } +} + +func TestGPGKey_String(t *testing.T) { + v := GPGKey{ + ID: Int64(0), + PrimaryKeyID: Int64(0), + KeyID: String(""), + PublicKey: String(""), + CanSign: Bool(false), + CanEncryptComms: Bool(false), + CanEncryptStorage: Bool(false), + CanCertify: Bool(false), + } + want := `github.GPGKey{ID:0, PrimaryKeyID:0, KeyID:"", PublicKey:"", CanSign:false, CanEncryptComms:false, CanEncryptStorage:false, CanCertify:false}` + if got := v.String(); got != want { + t.Errorf("GPGKey.String = %v, want %v", got, want) + } +} + +func TestGist_String(t *testing.T) { + v := Gist{ + ID: String(""), + Description: String(""), + Public: Bool(false), + Owner: &User{}, + Files: nil, + Comments: Int(0), + HTMLURL: String(""), + GitPullURL: String(""), + GitPushURL: String(""), + NodeID: String(""), + } + want := `github.Gist{ID:"", Description:"", Public:false, Owner:github.User{}, Files:map[], Comments:0, HTMLURL:"", GitPullURL:"", GitPushURL:"", NodeID:""}` + if got := v.String(); got != want { + t.Errorf("Gist.String = %v, want %v", got, want) + } +} + +func TestGistComment_String(t *testing.T) { + v := GistComment{ + ID: Int64(0), + URL: String(""), + Body: String(""), + User: &User{}, + } + want := `github.GistComment{ID:0, URL:"", Body:"", User:github.User{}}` + if got := v.String(); got != want { + t.Errorf("GistComment.String = %v, want %v", got, want) + } +} + +func TestGistCommit_String(t *testing.T) { + v := GistCommit{ + URL: String(""), + Version: String(""), + User: &User{}, + ChangeStatus: &CommitStats{}, + CommittedAt: &Timestamp{}, + NodeID: String(""), + } + want := `github.GistCommit{URL:"", Version:"", User:github.User{}, ChangeStatus:github.CommitStats{}, CommittedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, NodeID:""}` + if got := v.String(); got != want { + t.Errorf("GistCommit.String = %v, want %v", got, want) + } +} + +func TestGistFile_String(t *testing.T) { + v := GistFile{ + Size: Int(0), + Filename: String(""), + Language: String(""), + Type: String(""), + RawURL: String(""), + Content: String(""), + } + want := `github.GistFile{Size:0, Filename:"", Language:"", Type:"", RawURL:"", Content:""}` + if got := v.String(); got != want { + t.Errorf("GistFile.String = %v, want %v", got, want) + } +} + +func TestGistFork_String(t *testing.T) { + v := GistFork{ + URL: String(""), + User: &User{}, + ID: String(""), + CreatedAt: &Timestamp{}, + UpdatedAt: &Timestamp{}, + NodeID: String(""), + } + want := `github.GistFork{URL:"", User:github.User{}, ID:"", CreatedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, UpdatedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, NodeID:""}` + if got := v.String(); got != want { + t.Errorf("GistFork.String = %v, want %v", got, want) + } +} + +func TestGistStats_String(t *testing.T) { + v := GistStats{ + TotalGists: Int(0), + PrivateGists: Int(0), + PublicGists: Int(0), + } + want := `github.GistStats{TotalGists:0, PrivateGists:0, PublicGists:0}` + if got := v.String(); got != want { + t.Errorf("GistStats.String = %v, want %v", got, want) + } +} + +func TestGitObject_String(t *testing.T) { + v := GitObject{ + Type: String(""), + SHA: String(""), + URL: String(""), + } + want := `github.GitObject{Type:"", SHA:"", URL:""}` + if got := v.String(); got != want { + t.Errorf("GitObject.String = %v, want %v", got, want) + } +} + +func TestGitignore_String(t *testing.T) { + v := Gitignore{ + Name: String(""), + Source: String(""), + } + want := `github.Gitignore{Name:"", Source:""}` + if got := v.String(); got != want { + t.Errorf("Gitignore.String = %v, want %v", got, want) + } +} + +func TestGrant_String(t *testing.T) { + v := Grant{ + ID: Int64(0), + URL: String(""), + App: &AuthorizationApp{}, + CreatedAt: &Timestamp{}, + UpdatedAt: &Timestamp{}, + } + want := `github.Grant{ID:0, URL:"", App:github.AuthorizationApp{}, CreatedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, UpdatedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}}` + if got := v.String(); got != want { + t.Errorf("Grant.String = %v, want %v", got, want) + } +} + +func TestHook_String(t *testing.T) { + v := Hook{ + URL: String(""), + ID: Int64(0), + Config: nil, + Active: Bool(false), + } + want := `github.Hook{URL:"", ID:0, Config:map[], Active:false}` + if got := v.String(); got != want { + t.Errorf("Hook.String = %v, want %v", got, want) + } +} + +func TestHookStats_String(t *testing.T) { + v := HookStats{ + TotalHooks: Int(0), + ActiveHooks: Int(0), + InactiveHooks: Int(0), + } + want := `github.HookStats{TotalHooks:0, ActiveHooks:0, InactiveHooks:0}` + if got := v.String(); got != want { + t.Errorf("HookStats.String = %v, want %v", got, want) + } +} + +func TestImport_String(t *testing.T) { + v := Import{ + VCSURL: String(""), + VCS: String(""), + VCSUsername: String(""), + VCSPassword: String(""), + TFVCProject: String(""), + UseLFS: String(""), + HasLargeFiles: Bool(false), + LargeFilesSize: Int(0), + LargeFilesCount: Int(0), + Status: String(""), + CommitCount: Int(0), + StatusText: String(""), + AuthorsCount: Int(0), + Percent: Int(0), + PushPercent: Int(0), + URL: String(""), + HTMLURL: String(""), + AuthorsURL: String(""), + RepositoryURL: String(""), + Message: String(""), + FailedStep: String(""), + HumanName: String(""), + } + want := `github.Import{VCSURL:"", VCS:"", VCSUsername:"", VCSPassword:"", TFVCProject:"", UseLFS:"", HasLargeFiles:false, LargeFilesSize:0, LargeFilesCount:0, Status:"", CommitCount:0, StatusText:"", AuthorsCount:0, Percent:0, PushPercent:0, URL:"", HTMLURL:"", AuthorsURL:"", RepositoryURL:"", Message:"", FailedStep:"", HumanName:""}` + if got := v.String(); got != want { + t.Errorf("Import.String = %v, want %v", got, want) + } +} + +func TestInstallation_String(t *testing.T) { + v := Installation{ + ID: Int64(0), + AppID: Int64(0), + TargetID: Int64(0), + Account: &User{}, + AccessTokensURL: String(""), + RepositoriesURL: String(""), + HTMLURL: String(""), + TargetType: String(""), + SingleFileName: String(""), + RepositorySelection: String(""), + Permissions: &InstallationPermissions{}, + CreatedAt: &Timestamp{}, + UpdatedAt: &Timestamp{}, + } + want := `github.Installation{ID:0, AppID:0, TargetID:0, Account:github.User{}, AccessTokensURL:"", RepositoriesURL:"", HTMLURL:"", TargetType:"", SingleFileName:"", RepositorySelection:"", Permissions:github.InstallationPermissions{}, CreatedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, UpdatedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}}` + if got := v.String(); got != want { + t.Errorf("Installation.String = %v, want %v", got, want) + } +} + +func TestInvitation_String(t *testing.T) { + v := Invitation{ + ID: Int64(0), + NodeID: String(""), + Login: String(""), + Email: String(""), + Role: String(""), + Inviter: &User{}, + TeamCount: Int(0), + InvitationTeamURL: String(""), + } + want := `github.Invitation{ID:0, NodeID:"", Login:"", Email:"", Role:"", Inviter:github.User{}, TeamCount:0, InvitationTeamURL:""}` + if got := v.String(); got != want { + t.Errorf("Invitation.String = %v, want %v", got, want) + } +} + +func TestIssue_String(t *testing.T) { + v := Issue{ + ID: Int64(0), + Number: Int(0), + State: String(""), + Locked: Bool(false), + Title: String(""), + Body: String(""), + User: &User{}, + Assignee: &User{}, + Comments: Int(0), + ClosedBy: &User{}, + URL: String(""), + HTMLURL: String(""), + CommentsURL: String(""), + EventsURL: String(""), + LabelsURL: String(""), + RepositoryURL: String(""), + Milestone: &Milestone{}, + PullRequestLinks: &PullRequestLinks{}, + Repository: &Repository{}, + Reactions: &Reactions{}, + NodeID: String(""), + ActiveLockReason: String(""), + } + want := `github.Issue{ID:0, Number:0, State:"", Locked:false, Title:"", Body:"", User:github.User{}, Assignee:github.User{}, Comments:0, ClosedBy:github.User{}, URL:"", HTMLURL:"", CommentsURL:"", EventsURL:"", LabelsURL:"", RepositoryURL:"", Milestone:github.Milestone{}, PullRequestLinks:github.PullRequestLinks{}, Repository:github.Repository{}, Reactions:github.Reactions{}, NodeID:"", ActiveLockReason:""}` + if got := v.String(); got != want { + t.Errorf("Issue.String = %v, want %v", got, want) + } +} + +func TestIssueComment_String(t *testing.T) { + v := IssueComment{ + ID: Int64(0), + NodeID: String(""), + Body: String(""), + User: &User{}, + Reactions: &Reactions{}, + AuthorAssociation: String(""), + URL: String(""), + HTMLURL: String(""), + IssueURL: String(""), + } + want := `github.IssueComment{ID:0, NodeID:"", Body:"", User:github.User{}, Reactions:github.Reactions{}, AuthorAssociation:"", URL:"", HTMLURL:"", IssueURL:""}` + if got := v.String(); got != want { + t.Errorf("IssueComment.String = %v, want %v", got, want) + } +} + +func TestIssueStats_String(t *testing.T) { + v := IssueStats{ + TotalIssues: Int(0), + OpenIssues: Int(0), + ClosedIssues: Int(0), + } + want := `github.IssueStats{TotalIssues:0, OpenIssues:0, ClosedIssues:0}` + if got := v.String(); got != want { + t.Errorf("IssueStats.String = %v, want %v", got, want) + } +} + +func TestKey_String(t *testing.T) { + v := Key{ + ID: Int64(0), + Key: String(""), + URL: String(""), + Title: String(""), + ReadOnly: Bool(false), + } + want := `github.Key{ID:0, Key:"", URL:"", Title:"", ReadOnly:false}` + if got := v.String(); got != want { + t.Errorf("Key.String = %v, want %v", got, want) + } +} + +func TestLabel_String(t *testing.T) { + v := Label{ + ID: Int64(0), + URL: String(""), + Name: String(""), + Color: String(""), + Description: String(""), + Default: Bool(false), + NodeID: String(""), + } + want := `github.Label{ID:0, URL:"", Name:"", Color:"", Description:"", Default:false, NodeID:""}` + if got := v.String(); got != want { + t.Errorf("Label.String = %v, want %v", got, want) + } +} + +func TestLabelResult_String(t *testing.T) { + v := LabelResult{ + ID: Int64(0), + URL: String(""), + Name: String(""), + Color: String(""), + Default: Bool(false), + Description: String(""), + Score: Float64(0.0), + } + want := `github.LabelResult{ID:0, URL:"", Name:"", Color:"", Default:false, Description:"", Score:0}` + if got := v.String(); got != want { + t.Errorf("LabelResult.String = %v, want %v", got, want) + } +} + +func TestLargeFile_String(t *testing.T) { + v := LargeFile{ + RefName: String(""), + Path: String(""), + OID: String(""), + Size: Int(0), + } + want := `github.LargeFile{RefName:"", Path:"", OID:"", Size:0}` + if got := v.String(); got != want { + t.Errorf("LargeFile.String = %v, want %v", got, want) + } +} + +func TestLicense_String(t *testing.T) { + v := License{ + Key: String(""), + Name: String(""), + URL: String(""), + SPDXID: String(""), + HTMLURL: String(""), + Featured: Bool(false), + Description: String(""), + Implementation: String(""), + Body: String(""), + } + want := `github.License{Key:"", Name:"", URL:"", SPDXID:"", HTMLURL:"", Featured:false, Description:"", Implementation:"", Body:""}` + if got := v.String(); got != want { + t.Errorf("License.String = %v, want %v", got, want) + } +} + +func TestMembership_String(t *testing.T) { + v := Membership{ + URL: String(""), + State: String(""), + Role: String(""), + OrganizationURL: String(""), + Organization: &Organization{}, + User: &User{}, + } + want := `github.Membership{URL:"", State:"", Role:"", OrganizationURL:"", Organization:github.Organization{}, User:github.User{}}` + if got := v.String(); got != want { + t.Errorf("Membership.String = %v, want %v", got, want) + } +} + +func TestMigration_String(t *testing.T) { + v := Migration{ + ID: Int64(0), + GUID: String(""), + State: String(""), + LockRepositories: Bool(false), + ExcludeAttachments: Bool(false), + URL: String(""), + CreatedAt: String(""), + UpdatedAt: String(""), + } + want := `github.Migration{ID:0, GUID:"", State:"", LockRepositories:false, ExcludeAttachments:false, URL:"", CreatedAt:"", UpdatedAt:""}` + if got := v.String(); got != want { + t.Errorf("Migration.String = %v, want %v", got, want) + } +} + +func TestMilestone_String(t *testing.T) { + v := Milestone{ + URL: String(""), + HTMLURL: String(""), + LabelsURL: String(""), + ID: Int64(0), + Number: Int(0), + State: String(""), + Title: String(""), + Description: String(""), + Creator: &User{}, + OpenIssues: Int(0), + ClosedIssues: Int(0), + NodeID: String(""), + } + want := `github.Milestone{URL:"", HTMLURL:"", LabelsURL:"", ID:0, Number:0, State:"", Title:"", Description:"", Creator:github.User{}, OpenIssues:0, ClosedIssues:0, NodeID:""}` + if got := v.String(); got != want { + t.Errorf("Milestone.String = %v, want %v", got, want) + } +} + +func TestMilestoneStats_String(t *testing.T) { + v := MilestoneStats{ + TotalMilestones: Int(0), + OpenMilestones: Int(0), + ClosedMilestones: Int(0), + } + want := `github.MilestoneStats{TotalMilestones:0, OpenMilestones:0, ClosedMilestones:0}` + if got := v.String(); got != want { + t.Errorf("MilestoneStats.String = %v, want %v", got, want) + } +} + +func TestNewTeam_String(t *testing.T) { + v := NewTeam{ + Name: "", + Description: String(""), + ParentTeamID: Int64(0), + Permission: String(""), + Privacy: String(""), + LDAPDN: String(""), + } + want := `github.NewTeam{Name:"", Description:"", ParentTeamID:0, Permission:"", Privacy:"", LDAPDN:""}` + if got := v.String(); got != want { + t.Errorf("NewTeam.String = %v, want %v", got, want) + } +} + +func TestOrgStats_String(t *testing.T) { + v := OrgStats{ + TotalOrgs: Int(0), + DisabledOrgs: Int(0), + TotalTeams: Int(0), + TotalTeamMembers: Int(0), + } + want := `github.OrgStats{TotalOrgs:0, DisabledOrgs:0, TotalTeams:0, TotalTeamMembers:0}` + if got := v.String(); got != want { + t.Errorf("OrgStats.String = %v, want %v", got, want) + } +} + +func TestOrganization_String(t *testing.T) { + v := Organization{ + Login: String(""), + ID: Int64(0), + NodeID: String(""), + AvatarURL: String(""), + HTMLURL: String(""), + Name: String(""), + Company: String(""), + Blog: String(""), + Location: String(""), + Email: String(""), + Description: String(""), + PublicRepos: Int(0), + PublicGists: Int(0), + Followers: Int(0), + Following: Int(0), + TotalPrivateRepos: Int(0), + OwnedPrivateRepos: Int(0), + PrivateGists: Int(0), + DiskUsage: Int(0), + Collaborators: Int(0), + BillingEmail: String(""), + Type: String(""), + Plan: &Plan{}, + TwoFactorRequirementEnabled: Bool(false), + DefaultRepoPermission: String(""), + DefaultRepoSettings: String(""), + MembersCanCreateRepos: Bool(false), + URL: String(""), + EventsURL: String(""), + HooksURL: String(""), + IssuesURL: String(""), + MembersURL: String(""), + PublicMembersURL: String(""), + ReposURL: String(""), + } + want := `github.Organization{Login:"", ID:0, NodeID:"", AvatarURL:"", HTMLURL:"", Name:"", Company:"", Blog:"", Location:"", Email:"", Description:"", PublicRepos:0, PublicGists:0, Followers:0, Following:0, TotalPrivateRepos:0, OwnedPrivateRepos:0, PrivateGists:0, DiskUsage:0, Collaborators:0, BillingEmail:"", Type:"", Plan:github.Plan{}, TwoFactorRequirementEnabled:false, DefaultRepoPermission:"", DefaultRepoSettings:"", MembersCanCreateRepos:false, URL:"", EventsURL:"", HooksURL:"", IssuesURL:"", MembersURL:"", PublicMembersURL:"", ReposURL:""}` + if got := v.String(); got != want { + t.Errorf("Organization.String = %v, want %v", got, want) + } +} + +func TestPageStats_String(t *testing.T) { + v := PageStats{ + TotalPages: Int(0), + } + want := `github.PageStats{TotalPages:0}` + if got := v.String(); got != want { + t.Errorf("PageStats.String = %v, want %v", got, want) + } +} + +func TestPlan_String(t *testing.T) { + v := Plan{ + Name: String(""), + Space: Int(0), + Collaborators: Int(0), + PrivateRepos: Int(0), + } + want := `github.Plan{Name:"", Space:0, Collaborators:0, PrivateRepos:0}` + if got := v.String(); got != want { + t.Errorf("Plan.String = %v, want %v", got, want) + } +} + +func TestPreReceiveHook_String(t *testing.T) { + v := PreReceiveHook{ + ID: Int64(0), + Name: String(""), + Enforcement: String(""), + ConfigURL: String(""), + } + want := `github.PreReceiveHook{ID:0, Name:"", Enforcement:"", ConfigURL:""}` + if got := v.String(); got != want { + t.Errorf("PreReceiveHook.String = %v, want %v", got, want) + } +} + +func TestProject_String(t *testing.T) { + v := Project{ + ID: Int64(0), + URL: String(""), + HTMLURL: String(""), + ColumnsURL: String(""), + OwnerURL: String(""), + Name: String(""), + Body: String(""), + Number: Int(0), + State: String(""), + CreatedAt: &Timestamp{}, + UpdatedAt: &Timestamp{}, + NodeID: String(""), + Creator: &User{}, + } + want := `github.Project{ID:0, URL:"", HTMLURL:"", ColumnsURL:"", OwnerURL:"", Name:"", Body:"", Number:0, State:"", CreatedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, UpdatedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, NodeID:"", Creator:github.User{}}` + if got := v.String(); got != want { + t.Errorf("Project.String = %v, want %v", got, want) + } +} + +func TestPullRequest_String(t *testing.T) { + v := PullRequest{ + ID: Int64(0), + Number: Int(0), + State: String(""), + Title: String(""), + Body: String(""), + User: &User{}, + Draft: Bool(false), + Merged: Bool(false), + Mergeable: Bool(false), + MergeableState: String(""), + MergedBy: &User{}, + MergeCommitSHA: String(""), + Comments: Int(0), + Commits: Int(0), + Additions: Int(0), + Deletions: Int(0), + ChangedFiles: Int(0), + URL: String(""), + HTMLURL: String(""), + IssueURL: String(""), + StatusesURL: String(""), + DiffURL: String(""), + PatchURL: String(""), + CommitsURL: String(""), + CommentsURL: String(""), + ReviewCommentsURL: String(""), + ReviewCommentURL: String(""), + ReviewComments: Int(0), + Assignee: &User{}, + Milestone: &Milestone{}, + MaintainerCanModify: Bool(false), + AuthorAssociation: String(""), + NodeID: String(""), + Links: &PRLinks{}, + Head: &PullRequestBranch{}, + Base: &PullRequestBranch{}, + ActiveLockReason: String(""), + } + want := `github.PullRequest{ID:0, Number:0, State:"", Title:"", Body:"", User:github.User{}, Draft:false, Merged:false, Mergeable:false, MergeableState:"", MergedBy:github.User{}, MergeCommitSHA:"", Comments:0, Commits:0, Additions:0, Deletions:0, ChangedFiles:0, URL:"", HTMLURL:"", IssueURL:"", StatusesURL:"", DiffURL:"", PatchURL:"", CommitsURL:"", CommentsURL:"", ReviewCommentsURL:"", ReviewCommentURL:"", ReviewComments:0, Assignee:github.User{}, Milestone:github.Milestone{}, MaintainerCanModify:false, AuthorAssociation:"", NodeID:"", Links:github.PRLinks{}, Head:github.PullRequestBranch{}, Base:github.PullRequestBranch{}, ActiveLockReason:""}` + if got := v.String(); got != want { + t.Errorf("PullRequest.String = %v, want %v", got, want) + } +} + +func TestPullRequestComment_String(t *testing.T) { + v := PullRequestComment{ + ID: Int64(0), + NodeID: String(""), + InReplyTo: Int64(0), + Body: String(""), + Path: String(""), + DiffHunk: String(""), + PullRequestReviewID: Int64(0), + Position: Int(0), + OriginalPosition: Int(0), + CommitID: String(""), + OriginalCommitID: String(""), + User: &User{}, + Reactions: &Reactions{}, + AuthorAssociation: String(""), + URL: String(""), + HTMLURL: String(""), + PullRequestURL: String(""), + } + want := `github.PullRequestComment{ID:0, NodeID:"", InReplyTo:0, Body:"", Path:"", DiffHunk:"", PullRequestReviewID:0, Position:0, OriginalPosition:0, CommitID:"", OriginalCommitID:"", User:github.User{}, Reactions:github.Reactions{}, AuthorAssociation:"", URL:"", HTMLURL:"", PullRequestURL:""}` + if got := v.String(); got != want { + t.Errorf("PullRequestComment.String = %v, want %v", got, want) + } +} + +func TestPullRequestReview_String(t *testing.T) { + v := PullRequestReview{ + ID: Int64(0), + NodeID: String(""), + User: &User{}, + Body: String(""), + CommitID: String(""), + HTMLURL: String(""), + PullRequestURL: String(""), + State: String(""), + } + want := `github.PullRequestReview{ID:0, NodeID:"", User:github.User{}, Body:"", CommitID:"", HTMLURL:"", PullRequestURL:"", State:""}` + if got := v.String(); got != want { + t.Errorf("PullRequestReview.String = %v, want %v", got, want) + } +} + +func TestPullRequestReviewDismissalRequest_String(t *testing.T) { + v := PullRequestReviewDismissalRequest{ + Message: String(""), + } + want := `github.PullRequestReviewDismissalRequest{Message:""}` + if got := v.String(); got != want { + t.Errorf("PullRequestReviewDismissalRequest.String = %v, want %v", got, want) + } +} + +func TestPullRequestReviewRequest_String(t *testing.T) { + v := PullRequestReviewRequest{ + NodeID: String(""), + CommitID: String(""), + Body: String(""), + Event: String(""), + } + want := `github.PullRequestReviewRequest{NodeID:"", CommitID:"", Body:"", Event:""}` + if got := v.String(); got != want { + t.Errorf("PullRequestReviewRequest.String = %v, want %v", got, want) + } +} + +func TestPullStats_String(t *testing.T) { + v := PullStats{ + TotalPulls: Int(0), + MergedPulls: Int(0), + MergablePulls: Int(0), + UnmergablePulls: Int(0), + } + want := `github.PullStats{TotalPulls:0, MergedPulls:0, MergablePulls:0, UnmergablePulls:0}` + if got := v.String(); got != want { + t.Errorf("PullStats.String = %v, want %v", got, want) + } +} + +func TestPushEvent_String(t *testing.T) { + v := PushEvent{ + PushID: Int64(0), + Head: String(""), + Ref: String(""), + Size: Int(0), + Before: String(""), + DistinctSize: Int(0), + After: String(""), + Created: Bool(false), + Deleted: Bool(false), + Forced: Bool(false), + BaseRef: String(""), + Compare: String(""), + Repo: &PushEventRepository{}, + HeadCommit: &PushEventCommit{}, + Pusher: &User{}, + Sender: &User{}, + Installation: &Installation{}, + } + want := `github.PushEvent{PushID:0, Head:"", Ref:"", Size:0, Before:"", DistinctSize:0, After:"", Created:false, Deleted:false, Forced:false, BaseRef:"", Compare:"", Repo:github.PushEventRepository{}, HeadCommit:github.PushEventCommit{}, Pusher:github.User{}, Sender:github.User{}, Installation:github.Installation{}}` + if got := v.String(); got != want { + t.Errorf("PushEvent.String = %v, want %v", got, want) + } +} + +func TestPushEventCommit_String(t *testing.T) { + v := PushEventCommit{ + Message: String(""), + Author: &CommitAuthor{}, + URL: String(""), + Distinct: Bool(false), + SHA: String(""), + ID: String(""), + TreeID: String(""), + Timestamp: &Timestamp{}, + Committer: &CommitAuthor{}, + } + want := `github.PushEventCommit{Message:"", Author:github.CommitAuthor{}, URL:"", Distinct:false, SHA:"", ID:"", TreeID:"", Timestamp:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, Committer:github.CommitAuthor{}}` + if got := v.String(); got != want { + t.Errorf("PushEventCommit.String = %v, want %v", got, want) + } +} + +func TestRate_String(t *testing.T) { + v := Rate{ + Limit: 0, + Remaining: 0, + Reset: Timestamp{}, + } + want := `github.Rate{Limit:0, Remaining:0, Reset:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}}` + if got := v.String(); got != want { + t.Errorf("Rate.String = %v, want %v", got, want) + } +} + +func TestReaction_String(t *testing.T) { + v := Reaction{ + ID: Int64(0), + User: &User{}, + NodeID: String(""), + Content: String(""), + } + want := `github.Reaction{ID:0, User:github.User{}, NodeID:"", Content:""}` + if got := v.String(); got != want { + t.Errorf("Reaction.String = %v, want %v", got, want) + } +} + +func TestReference_String(t *testing.T) { + v := Reference{ + Ref: String(""), + URL: String(""), + Object: &GitObject{}, + NodeID: String(""), + } + want := `github.Reference{Ref:"", URL:"", Object:github.GitObject{}, NodeID:""}` + if got := v.String(); got != want { + t.Errorf("Reference.String = %v, want %v", got, want) + } +} + +func TestReleaseAsset_String(t *testing.T) { + v := ReleaseAsset{ + ID: Int64(0), + URL: String(""), + Name: String(""), + Label: String(""), + State: String(""), + ContentType: String(""), + Size: Int(0), + DownloadCount: Int(0), + CreatedAt: &Timestamp{}, + UpdatedAt: &Timestamp{}, + BrowserDownloadURL: String(""), + Uploader: &User{}, + NodeID: String(""), + } + want := `github.ReleaseAsset{ID:0, URL:"", Name:"", Label:"", State:"", ContentType:"", Size:0, DownloadCount:0, CreatedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, UpdatedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, BrowserDownloadURL:"", Uploader:github.User{}, NodeID:""}` + if got := v.String(); got != want { + t.Errorf("ReleaseAsset.String = %v, want %v", got, want) + } +} + +func TestRename_String(t *testing.T) { + v := Rename{ + From: String(""), + To: String(""), + } + want := `github.Rename{From:"", To:""}` + if got := v.String(); got != want { + t.Errorf("Rename.String = %v, want %v", got, want) + } +} + +func TestRepoStats_String(t *testing.T) { + v := RepoStats{ + TotalRepos: Int(0), + RootRepos: Int(0), + ForkRepos: Int(0), + OrgRepos: Int(0), + TotalPushes: Int(0), + TotalWikis: Int(0), + } + want := `github.RepoStats{TotalRepos:0, RootRepos:0, ForkRepos:0, OrgRepos:0, TotalPushes:0, TotalWikis:0}` + if got := v.String(); got != want { + t.Errorf("RepoStats.String = %v, want %v", got, want) + } +} + +func TestRepoStatus_String(t *testing.T) { + v := RepoStatus{ + ID: Int64(0), + NodeID: String(""), + URL: String(""), + State: String(""), + TargetURL: String(""), + Description: String(""), + Context: String(""), + Creator: &User{}, + } + want := `github.RepoStatus{ID:0, NodeID:"", URL:"", State:"", TargetURL:"", Description:"", Context:"", Creator:github.User{}}` + if got := v.String(); got != want { + t.Errorf("RepoStatus.String = %v, want %v", got, want) + } +} + +func TestRepository_String(t *testing.T) { + v := Repository{ + ID: Int64(0), + NodeID: String(""), + Owner: &User{}, + Name: String(""), + FullName: String(""), + Description: String(""), + Homepage: String(""), + CodeOfConduct: &CodeOfConduct{}, + DefaultBranch: String(""), + MasterBranch: String(""), + CreatedAt: &Timestamp{}, + PushedAt: &Timestamp{}, + UpdatedAt: &Timestamp{}, + HTMLURL: String(""), + CloneURL: String(""), + GitURL: String(""), + MirrorURL: String(""), + SSHURL: String(""), + SVNURL: String(""), + Language: String(""), + Fork: Bool(false), + ForksCount: Int(0), + NetworkCount: Int(0), + OpenIssuesCount: Int(0), + StargazersCount: Int(0), + SubscribersCount: Int(0), + WatchersCount: Int(0), + Size: Int(0), + AutoInit: Bool(false), + Parent: &Repository{}, + Source: &Repository{}, + Organization: &Organization{}, + AllowRebaseMerge: Bool(false), + AllowSquashMerge: Bool(false), + AllowMergeCommit: Bool(false), + Archived: Bool(false), + Disabled: Bool(false), + License: &License{}, + Private: Bool(false), + HasIssues: Bool(false), + HasWiki: Bool(false), + HasPages: Bool(false), + HasProjects: Bool(false), + HasDownloads: Bool(false), + LicenseTemplate: String(""), + GitignoreTemplate: String(""), + TeamID: Int64(0), + URL: String(""), + ArchiveURL: String(""), + AssigneesURL: String(""), + BlobsURL: String(""), + BranchesURL: String(""), + CollaboratorsURL: String(""), + CommentsURL: String(""), + CommitsURL: String(""), + CompareURL: String(""), + ContentsURL: String(""), + ContributorsURL: String(""), + DeploymentsURL: String(""), + DownloadsURL: String(""), + EventsURL: String(""), + ForksURL: String(""), + GitCommitsURL: String(""), + GitRefsURL: String(""), + GitTagsURL: String(""), + HooksURL: String(""), + IssueCommentURL: String(""), + IssueEventsURL: String(""), + IssuesURL: String(""), + KeysURL: String(""), + LabelsURL: String(""), + LanguagesURL: String(""), + MergesURL: String(""), + MilestonesURL: String(""), + NotificationsURL: String(""), + PullsURL: String(""), + ReleasesURL: String(""), + StargazersURL: String(""), + StatusesURL: String(""), + SubscribersURL: String(""), + SubscriptionURL: String(""), + TagsURL: String(""), + TreesURL: String(""), + TeamsURL: String(""), + } + want := `github.Repository{ID:0, NodeID:"", Owner:github.User{}, Name:"", FullName:"", Description:"", Homepage:"", CodeOfConduct:github.CodeOfConduct{}, DefaultBranch:"", MasterBranch:"", CreatedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, PushedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, UpdatedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, HTMLURL:"", CloneURL:"", GitURL:"", MirrorURL:"", SSHURL:"", SVNURL:"", Language:"", Fork:false, ForksCount:0, NetworkCount:0, OpenIssuesCount:0, StargazersCount:0, SubscribersCount:0, WatchersCount:0, Size:0, AutoInit:false, Parent:github.Repository{}, Source:github.Repository{}, Organization:github.Organization{}, AllowRebaseMerge:false, AllowSquashMerge:false, AllowMergeCommit:false, Archived:false, Disabled:false, License:github.License{}, Private:false, HasIssues:false, HasWiki:false, HasPages:false, HasProjects:false, HasDownloads:false, LicenseTemplate:"", GitignoreTemplate:"", TeamID:0, URL:"", ArchiveURL:"", AssigneesURL:"", BlobsURL:"", BranchesURL:"", CollaboratorsURL:"", CommentsURL:"", CommitsURL:"", CompareURL:"", ContentsURL:"", ContributorsURL:"", DeploymentsURL:"", DownloadsURL:"", EventsURL:"", ForksURL:"", GitCommitsURL:"", GitRefsURL:"", GitTagsURL:"", HooksURL:"", IssueCommentURL:"", IssueEventsURL:"", IssuesURL:"", KeysURL:"", LabelsURL:"", LanguagesURL:"", MergesURL:"", MilestonesURL:"", NotificationsURL:"", PullsURL:"", ReleasesURL:"", StargazersURL:"", StatusesURL:"", SubscribersURL:"", SubscriptionURL:"", TagsURL:"", TreesURL:"", TeamsURL:""}` + if got := v.String(); got != want { + t.Errorf("Repository.String = %v, want %v", got, want) + } +} + +func TestRepositoryComment_String(t *testing.T) { + v := RepositoryComment{ + HTMLURL: String(""), + URL: String(""), + ID: Int64(0), + CommitID: String(""), + User: &User{}, + Reactions: &Reactions{}, + Body: String(""), + Path: String(""), + Position: Int(0), + } + want := `github.RepositoryComment{HTMLURL:"", URL:"", ID:0, CommitID:"", User:github.User{}, Reactions:github.Reactions{}, Body:"", Path:"", Position:0}` + if got := v.String(); got != want { + t.Errorf("RepositoryComment.String = %v, want %v", got, want) + } +} + +func TestRepositoryCommit_String(t *testing.T) { + v := RepositoryCommit{ + NodeID: String(""), + SHA: String(""), + Commit: &Commit{}, + Author: &User{}, + Committer: &User{}, + HTMLURL: String(""), + URL: String(""), + CommentsURL: String(""), + Stats: &CommitStats{}, + } + want := `github.RepositoryCommit{NodeID:"", SHA:"", Commit:github.Commit{}, Author:github.User{}, Committer:github.User{}, HTMLURL:"", URL:"", CommentsURL:"", Stats:github.CommitStats{}}` + if got := v.String(); got != want { + t.Errorf("RepositoryCommit.String = %v, want %v", got, want) + } +} + +func TestRepositoryContent_String(t *testing.T) { + v := RepositoryContent{ + Type: String(""), + Target: String(""), + Encoding: String(""), + Size: Int(0), + Name: String(""), + Path: String(""), + Content: String(""), + SHA: String(""), + URL: String(""), + GitURL: String(""), + HTMLURL: String(""), + DownloadURL: String(""), + } + want := `github.RepositoryContent{Type:"", Target:"", Encoding:"", Size:0, Name:"", Path:"", Content:"", SHA:"", URL:"", GitURL:"", HTMLURL:"", DownloadURL:""}` + if got := v.String(); got != want { + t.Errorf("RepositoryContent.String = %v, want %v", got, want) + } +} + +func TestRepositoryLicense_String(t *testing.T) { + v := RepositoryLicense{ + Name: String(""), + Path: String(""), + SHA: String(""), + Size: Int(0), + URL: String(""), + HTMLURL: String(""), + GitURL: String(""), + DownloadURL: String(""), + Type: String(""), + Content: String(""), + Encoding: String(""), + License: &License{}, + } + want := `github.RepositoryLicense{Name:"", Path:"", SHA:"", Size:0, URL:"", HTMLURL:"", GitURL:"", DownloadURL:"", Type:"", Content:"", Encoding:"", License:github.License{}}` + if got := v.String(); got != want { + t.Errorf("RepositoryLicense.String = %v, want %v", got, want) + } +} + +func TestRepositoryRelease_String(t *testing.T) { + v := RepositoryRelease{ + TagName: String(""), + TargetCommitish: String(""), + Name: String(""), + Body: String(""), + Draft: Bool(false), + Prerelease: Bool(false), + ID: Int64(0), + CreatedAt: &Timestamp{}, + PublishedAt: &Timestamp{}, + URL: String(""), + HTMLURL: String(""), + AssetsURL: String(""), + UploadURL: String(""), + ZipballURL: String(""), + TarballURL: String(""), + Author: &User{}, + NodeID: String(""), + } + want := `github.RepositoryRelease{TagName:"", TargetCommitish:"", Name:"", Body:"", Draft:false, Prerelease:false, ID:0, CreatedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, PublishedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, URL:"", HTMLURL:"", AssetsURL:"", UploadURL:"", ZipballURL:"", TarballURL:"", Author:github.User{}, NodeID:""}` + if got := v.String(); got != want { + t.Errorf("RepositoryRelease.String = %v, want %v", got, want) + } +} + +func TestSourceImportAuthor_String(t *testing.T) { + v := SourceImportAuthor{ + ID: Int64(0), + RemoteID: String(""), + RemoteName: String(""), + Email: String(""), + Name: String(""), + URL: String(""), + ImportURL: String(""), + } + want := `github.SourceImportAuthor{ID:0, RemoteID:"", RemoteName:"", Email:"", Name:"", URL:"", ImportURL:""}` + if got := v.String(); got != want { + t.Errorf("SourceImportAuthor.String = %v, want %v", got, want) + } +} + +func TestTeam_String(t *testing.T) { + v := Team{ + ID: Int64(0), + NodeID: String(""), + Name: String(""), + Description: String(""), + URL: String(""), + Slug: String(""), + Permission: String(""), + Privacy: String(""), + MembersCount: Int(0), + ReposCount: Int(0), + Organization: &Organization{}, + MembersURL: String(""), + RepositoriesURL: String(""), + Parent: &Team{}, + LDAPDN: String(""), + } + want := `github.Team{ID:0, NodeID:"", Name:"", Description:"", URL:"", Slug:"", Permission:"", Privacy:"", MembersCount:0, ReposCount:0, Organization:github.Organization{}, MembersURL:"", RepositoriesURL:"", Parent:github.Team{}, LDAPDN:""}` + if got := v.String(); got != want { + t.Errorf("Team.String = %v, want %v", got, want) + } +} + +func TestTeamDiscussion_String(t *testing.T) { + v := TeamDiscussion{ + Author: &User{}, + Body: String(""), + BodyHTML: String(""), + BodyVersion: String(""), + CommentsCount: Int(0), + CommentsURL: String(""), + CreatedAt: &Timestamp{}, + LastEditedAt: &Timestamp{}, + HTMLURL: String(""), + NodeID: String(""), + Number: Int(0), + Pinned: Bool(false), + Private: Bool(false), + TeamURL: String(""), + Title: String(""), + UpdatedAt: &Timestamp{}, + URL: String(""), + Reactions: &Reactions{}, + } + want := `github.TeamDiscussion{Author:github.User{}, Body:"", BodyHTML:"", BodyVersion:"", CommentsCount:0, CommentsURL:"", CreatedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, LastEditedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, HTMLURL:"", NodeID:"", Number:0, Pinned:false, Private:false, TeamURL:"", Title:"", UpdatedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, URL:"", Reactions:github.Reactions{}}` + if got := v.String(); got != want { + t.Errorf("TeamDiscussion.String = %v, want %v", got, want) + } +} + +func TestTeamLDAPMapping_String(t *testing.T) { + v := TeamLDAPMapping{ + ID: Int64(0), + LDAPDN: String(""), + URL: String(""), + Name: String(""), + Slug: String(""), + Description: String(""), + Privacy: String(""), + Permission: String(""), + MembersURL: String(""), + RepositoriesURL: String(""), + } + want := `github.TeamLDAPMapping{ID:0, LDAPDN:"", URL:"", Name:"", Slug:"", Description:"", Privacy:"", Permission:"", MembersURL:"", RepositoriesURL:""}` + if got := v.String(); got != want { + t.Errorf("TeamLDAPMapping.String = %v, want %v", got, want) + } +} + +func TestTextMatch_String(t *testing.T) { + v := TextMatch{ + ObjectURL: String(""), + ObjectType: String(""), + Property: String(""), + Fragment: String(""), + } + want := `github.TextMatch{ObjectURL:"", ObjectType:"", Property:"", Fragment:""}` + if got := v.String(); got != want { + t.Errorf("TextMatch.String = %v, want %v", got, want) + } +} + +func TestTree_String(t *testing.T) { + v := Tree{ + SHA: String(""), + Truncated: Bool(false), + } + want := `github.Tree{SHA:"", Truncated:false}` + if got := v.String(); got != want { + t.Errorf("Tree.String = %v, want %v", got, want) + } +} + +func TestTreeEntry_String(t *testing.T) { + v := TreeEntry{ + SHA: String(""), + Path: String(""), + Mode: String(""), + Type: String(""), + Size: Int(0), + Content: String(""), + URL: String(""), + } + want := `github.TreeEntry{SHA:"", Path:"", Mode:"", Type:"", Size:0, Content:"", URL:""}` + if got := v.String(); got != want { + t.Errorf("TreeEntry.String = %v, want %v", got, want) + } +} + +func TestUser_String(t *testing.T) { + v := User{ + Login: String(""), + ID: Int64(0), + NodeID: String(""), + AvatarURL: String(""), + HTMLURL: String(""), + GravatarID: String(""), + Name: String(""), + Company: String(""), + Blog: String(""), + Location: String(""), + Email: String(""), + Hireable: Bool(false), + Bio: String(""), + PublicRepos: Int(0), + PublicGists: Int(0), + Followers: Int(0), + Following: Int(0), + CreatedAt: &Timestamp{}, + UpdatedAt: &Timestamp{}, + SuspendedAt: &Timestamp{}, + Type: String(""), + SiteAdmin: Bool(false), + TotalPrivateRepos: Int(0), + OwnedPrivateRepos: Int(0), + PrivateGists: Int(0), + DiskUsage: Int(0), + Collaborators: Int(0), + TwoFactorAuthentication: Bool(false), + Plan: &Plan{}, + URL: String(""), + EventsURL: String(""), + FollowingURL: String(""), + FollowersURL: String(""), + GistsURL: String(""), + OrganizationsURL: String(""), + ReceivedEventsURL: String(""), + ReposURL: String(""), + StarredURL: String(""), + SubscriptionsURL: String(""), + } + want := `github.User{Login:"", ID:0, NodeID:"", AvatarURL:"", HTMLURL:"", GravatarID:"", Name:"", Company:"", Blog:"", Location:"", Email:"", Hireable:false, Bio:"", PublicRepos:0, PublicGists:0, Followers:0, Following:0, CreatedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, UpdatedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, SuspendedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, Type:"", SiteAdmin:false, TotalPrivateRepos:0, OwnedPrivateRepos:0, PrivateGists:0, DiskUsage:0, Collaborators:0, TwoFactorAuthentication:false, Plan:github.Plan{}, URL:"", EventsURL:"", FollowingURL:"", FollowersURL:"", GistsURL:"", OrganizationsURL:"", ReceivedEventsURL:"", ReposURL:"", StarredURL:"", SubscriptionsURL:""}` + if got := v.String(); got != want { + t.Errorf("User.String = %v, want %v", got, want) + } +} + +func TestUserLDAPMapping_String(t *testing.T) { + v := UserLDAPMapping{ + ID: Int64(0), + LDAPDN: String(""), + Login: String(""), + AvatarURL: String(""), + GravatarID: String(""), + Type: String(""), + SiteAdmin: Bool(false), + URL: String(""), + EventsURL: String(""), + FollowingURL: String(""), + FollowersURL: String(""), + GistsURL: String(""), + OrganizationsURL: String(""), + ReceivedEventsURL: String(""), + ReposURL: String(""), + StarredURL: String(""), + SubscriptionsURL: String(""), + } + want := `github.UserLDAPMapping{ID:0, LDAPDN:"", Login:"", AvatarURL:"", GravatarID:"", Type:"", SiteAdmin:false, URL:"", EventsURL:"", FollowingURL:"", FollowersURL:"", GistsURL:"", OrganizationsURL:"", ReceivedEventsURL:"", ReposURL:"", StarredURL:"", SubscriptionsURL:""}` + if got := v.String(); got != want { + t.Errorf("UserLDAPMapping.String = %v, want %v", got, want) + } +} + +func TestUserMigration_String(t *testing.T) { + v := UserMigration{ + ID: Int64(0), + GUID: String(""), + State: String(""), + LockRepositories: Bool(false), + ExcludeAttachments: Bool(false), + URL: String(""), + CreatedAt: String(""), + UpdatedAt: String(""), + } + want := `github.UserMigration{ID:0, GUID:"", State:"", LockRepositories:false, ExcludeAttachments:false, URL:"", CreatedAt:"", UpdatedAt:""}` + if got := v.String(); got != want { + t.Errorf("UserMigration.String = %v, want %v", got, want) + } +} + +func TestUserStats_String(t *testing.T) { + v := UserStats{ + TotalUsers: Int(0), + AdminUsers: Int(0), + SuspendedUsers: Int(0), + } + want := `github.UserStats{TotalUsers:0, AdminUsers:0, SuspendedUsers:0}` + if got := v.String(); got != want { + t.Errorf("UserStats.String = %v, want %v", got, want) + } +} + +func TestWebHookAuthor_String(t *testing.T) { + v := WebHookAuthor{ + Email: String(""), + Name: String(""), + Username: String(""), + } + want := `github.WebHookAuthor{Email:"", Name:"", Username:""}` + if got := v.String(); got != want { + t.Errorf("WebHookAuthor.String = %v, want %v", got, want) + } +} + +func TestWebHookCommit_String(t *testing.T) { + v := WebHookCommit{ + Author: &WebHookAuthor{}, + Committer: &WebHookAuthor{}, + Distinct: Bool(false), + ID: String(""), + Message: String(""), + } + want := `github.WebHookCommit{Author:github.WebHookAuthor{}, Committer:github.WebHookAuthor{}, Distinct:false, ID:"", Message:""}` + if got := v.String(); got != want { + t.Errorf("WebHookCommit.String = %v, want %v", got, want) + } +} + +func TestWebHookPayload_String(t *testing.T) { + v := WebHookPayload{ + After: String(""), + Before: String(""), + Compare: String(""), + Created: Bool(false), + Deleted: Bool(false), + Forced: Bool(false), + HeadCommit: &WebHookCommit{}, + Pusher: &User{}, + Ref: String(""), + Repo: &Repository{}, + Sender: &User{}, + } + want := `github.WebHookPayload{After:"", Before:"", Compare:"", Created:false, Deleted:false, Forced:false, HeadCommit:github.WebHookCommit{}, Pusher:github.User{}, Ref:"", Repo:github.Repository{}, Sender:github.User{}}` + if got := v.String(); got != want { + t.Errorf("WebHookPayload.String = %v, want %v", got, want) + } +} + +func TestWeeklyCommitActivity_String(t *testing.T) { + v := WeeklyCommitActivity{ + Total: Int(0), + Week: &Timestamp{}, + } + want := `github.WeeklyCommitActivity{Total:0, Week:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}}` + if got := v.String(); got != want { + t.Errorf("WeeklyCommitActivity.String = %v, want %v", got, want) + } +} + +func TestWeeklyStats_String(t *testing.T) { + v := WeeklyStats{ + Week: &Timestamp{}, + Additions: Int(0), + Deletions: Int(0), + Commits: Int(0), + } + want := `github.WeeklyStats{Week:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, Additions:0, Deletions:0, Commits:0}` + if got := v.String(); got != want { + t.Errorf("WeeklyStats.String = %v, want %v", got, want) + } +} diff --git a/github/github.go b/github/github.go index 45a72d7acbe..b1323f9e767 100644 --- a/github/github.go +++ b/github/github.go @@ -4,6 +4,7 @@ // license that can be found in the LICENSE file. //go:generate go run gen-accessors.go +//go:generate go run gen-stringify-test.go package github diff --git a/github/github_test.go b/github/github_test.go index 47f009cf50a..8dd75e4d7e6 100644 --- a/github/github_test.go +++ b/github/github_test.go @@ -221,6 +221,17 @@ func TestClient_rateLimits(t *testing.T) { } } +func TestRateLimits_String(t *testing.T) { + v := RateLimits{ + Core: &Rate{}, + Search: &Rate{}, + } + want := `github.RateLimits{Core:github.Rate{Limit:0, Remaining:0, Reset:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}}, Search:github.Rate{Limit:0, Remaining:0, Reset:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}}}` + if got := v.String(); got != want { + t.Errorf("RateLimits.String = %v, want %v", got, want) + } +} + func TestNewRequest(t *testing.T) { c := NewClient(nil) From cd2824bde7c1f5e5e88216ccd188f7360d0741d8 Mon Sep 17 00:00:00 2001 From: Glenn Lewis <6598971+gmlewis@users.noreply.github.com> Date: Thu, 20 Jun 2019 22:02:21 -0400 Subject: [PATCH 0013/1468] Coverage: activity.go (#1201) --- github/activity_test.go | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/github/activity_test.go b/github/activity_test.go index 92b42d3a727..9c4e566fb7d 100644 --- a/github/activity_test.go +++ b/github/activity_test.go @@ -10,6 +10,7 @@ import ( "net/http" "reflect" "testing" + "time" ) func TestActivityService_List(t *testing.T) { @@ -23,13 +24,41 @@ func TestActivityService_List(t *testing.T) { w.Write(feedsJSON) }) - got, _, err := client.Activity.ListFeeds(context.Background()) + ctx := context.Background() + got, resp, err := client.Activity.ListFeeds(ctx) if err != nil { t.Errorf("Activity.ListFeeds returned error: %v", err) } if want := wantFeeds; !reflect.DeepEqual(got, want) { t.Errorf("Activity.ListFeeds = %+v, want %+v", got, want) } + + // Test s.client.NewRequest failure + client.BaseURL.Path = "" + got, resp, err = client.Activity.ListFeeds(ctx) + if got != nil { + t.Errorf("client.BaseURL.Path='' ListFeeds = %#v, want nil", got) + } + if resp != nil { + t.Errorf("client.BaseURL.Path='' ListFeeds resp = %#v, want nil", resp) + } + if err == nil { + t.Error("client.BaseURL.Path='' ListFeeds err = nil, want error") + } + + // Test s.client.Do failure + client.BaseURL.Path = "/api-v3/" + client.rateLimits[0].Reset.Time = time.Now().Add(10 * time.Minute) + got, resp, err = client.Activity.ListFeeds(ctx) + if got != nil { + t.Errorf("rate.Reset.Time > now ListFeeds = %#v, want nil", got) + } + if want := http.StatusForbidden; resp == nil || resp.Response.StatusCode != want { + t.Errorf("rate.Reset.Time > now ListFeeds resp = %#v, want StatusCode=%v", resp.Response, want) + } + if err == nil { + t.Error("rate.Reset.Time > now ListFeeds err = nil, want error") + } } var feedsJSON = []byte(`{ From 67ad7e40c8c4ccfdb42900a661606dce20236d19 Mon Sep 17 00:00:00 2001 From: Glenn Lewis <6598971+gmlewis@users.noreply.github.com> Date: Thu, 20 Jun 2019 22:44:09 -0400 Subject: [PATCH 0014/1468] Coverage: repos_traffic.go (#1202) --- github/repos_traffic_test.go | 152 +++++++++++++++++++++++++++++++---- 1 file changed, 136 insertions(+), 16 deletions(-) diff --git a/github/repos_traffic_test.go b/github/repos_traffic_test.go index 0a2eb4f36d2..796544f3ce0 100644 --- a/github/repos_traffic_test.go +++ b/github/repos_traffic_test.go @@ -26,9 +26,10 @@ func TestRepositoriesService_ListTrafficReferrers(t *testing.T) { "uniques": 3 }]`) }) - referrers, _, err := client.Repositories.ListTrafficReferrers(context.Background(), "o", "r") + ctx := context.Background() + got, resp, err := client.Repositories.ListTrafficReferrers(ctx, "o", "r") if err != nil { - t.Errorf("Repositories.ListPaths returned error: %+v", err) + t.Errorf("Repositories.ListTrafficReferrers returned error: %+v", err) } want := []*TrafficReferrer{{ @@ -36,10 +37,36 @@ func TestRepositoriesService_ListTrafficReferrers(t *testing.T) { Count: Int(4), Uniques: Int(3), }} - if !reflect.DeepEqual(referrers, want) { - t.Errorf("Repositories.ListReferrers returned %+v, want %+v", referrers, want) + if !reflect.DeepEqual(got, want) { + t.Errorf("Repositories.ListTrafficReferrers returned %+v, want %+v", got, want) } + // Test s.client.NewRequest failure + client.BaseURL.Path = "" + got, resp, err = client.Repositories.ListTrafficReferrers(ctx, "o", "r") + if got != nil { + t.Errorf("client.BaseURL.Path='' ListTrafficReferrers = %#v, want nil", got) + } + if resp != nil { + t.Errorf("client.BaseURL.Path='' ListTrafficReferrers resp = %#v, want nil", resp) + } + if err == nil { + t.Error("client.BaseURL.Path='' ListTrafficReferrers err = nil, want error") + } + + // Test s.client.Do failure + client.BaseURL.Path = "/api-v3/" + client.rateLimits[0].Reset.Time = time.Now().Add(10 * time.Minute) + got, resp, err = client.Repositories.ListTrafficReferrers(ctx, "o", "r") + if got != nil { + t.Errorf("rate.Reset.Time > now ListTrafficReferrers = %#v, want nil", got) + } + if want := http.StatusForbidden; resp == nil || resp.Response.StatusCode != want { + t.Errorf("rate.Reset.Time > now ListTrafficReferrers resp = %#v, want StatusCode=%v", resp.Response, want) + } + if err == nil { + t.Error("rate.Reset.Time > now ListTrafficReferrers err = nil, want error") + } } func TestRepositoriesService_ListTrafficPaths(t *testing.T) { @@ -55,9 +82,10 @@ func TestRepositoriesService_ListTrafficPaths(t *testing.T) { "uniques": 2225 }]`) }) - paths, _, err := client.Repositories.ListTrafficPaths(context.Background(), "o", "r") + ctx := context.Background() + got, resp, err := client.Repositories.ListTrafficPaths(ctx, "o", "r") if err != nil { - t.Errorf("Repositories.ListPaths returned error: %+v", err) + t.Errorf("Repositories.ListTrafficPaths returned error: %+v", err) } want := []*TrafficPath{{ @@ -66,10 +94,36 @@ func TestRepositoriesService_ListTrafficPaths(t *testing.T) { Count: Int(3542), Uniques: Int(2225), }} - if !reflect.DeepEqual(paths, want) { - t.Errorf("Repositories.ListPaths returned %+v, want %+v", paths, want) + if !reflect.DeepEqual(got, want) { + t.Errorf("Repositories.ListTrafficPaths returned %+v, want %+v", got, want) + } + + // Test s.client.NewRequest failure + client.BaseURL.Path = "" + got, resp, err = client.Repositories.ListTrafficPaths(ctx, "o", "r") + if got != nil { + t.Errorf("client.BaseURL.Path='' ListTrafficPaths = %#v, want nil", got) + } + if resp != nil { + t.Errorf("client.BaseURL.Path='' ListTrafficPaths resp = %#v, want nil", resp) + } + if err == nil { + t.Error("client.BaseURL.Path='' ListTrafficPaths err = nil, want error") } + // Test s.client.Do failure + client.BaseURL.Path = "/api-v3/" + client.rateLimits[0].Reset.Time = time.Now().Add(10 * time.Minute) + got, resp, err = client.Repositories.ListTrafficPaths(ctx, "o", "r") + if got != nil { + t.Errorf("rate.Reset.Time > now ListTrafficPaths = %#v, want nil", got) + } + if want := http.StatusForbidden; resp == nil || resp.Response.StatusCode != want { + t.Errorf("rate.Reset.Time > now ListTrafficPaths resp = %#v, want StatusCode=%v", resp.Response, want) + } + if err == nil { + t.Error("rate.Reset.Time > now ListTrafficPaths err = nil, want error") + } } func TestRepositoriesService_ListTrafficViews(t *testing.T) { @@ -87,9 +141,10 @@ func TestRepositoriesService_ListTrafficViews(t *testing.T) { }]}`) }) - views, _, err := client.Repositories.ListTrafficViews(context.Background(), "o", "r", nil) + ctx := context.Background() + got, resp, err := client.Repositories.ListTrafficViews(ctx, "o", "r", nil) if err != nil { - t.Errorf("Repositories.ListPaths returned error: %+v", err) + t.Errorf("Repositories.ListTrafficViews returned error: %+v", err) } want := &TrafficViews{ @@ -102,10 +157,42 @@ func TestRepositoriesService_ListTrafficViews(t *testing.T) { Uniques: Int(6), } - if !reflect.DeepEqual(views, want) { - t.Errorf("Repositories.ListViews returned %+v, want %+v", views, want) + if !reflect.DeepEqual(got, want) { + t.Errorf("Repositories.ListTrafficViews returned %+v, want %+v", got, want) + } + + // Test addOptions failure + got, resp, err = client.Repositories.ListTrafficViews(ctx, "\n", "\n", &TrafficBreakdownOptions{}) + if err == nil { + t.Error("bad options ListTrafficViews err = nil, want error") } + // Test s.client.NewRequest failure + client.BaseURL.Path = "" + got, resp, err = client.Repositories.ListTrafficViews(ctx, "o", "r", nil) + if got != nil { + t.Errorf("client.BaseURL.Path='' ListTrafficViews = %#v, want nil", got) + } + if resp != nil { + t.Errorf("client.BaseURL.Path='' ListTrafficViews resp = %#v, want nil", resp) + } + if err == nil { + t.Error("client.BaseURL.Path='' ListTrafficViews err = nil, want error") + } + + // Test s.client.Do failure + client.BaseURL.Path = "/api-v3/" + client.rateLimits[0].Reset.Time = time.Now().Add(10 * time.Minute) + got, resp, err = client.Repositories.ListTrafficViews(ctx, "o", "r", nil) + if got != nil { + t.Errorf("rate.Reset.Time > now ListTrafficViews = %#v, want nil", got) + } + if want := http.StatusForbidden; resp == nil || resp.Response.StatusCode != want { + t.Errorf("rate.Reset.Time > now ListTrafficViews resp = %#v, want StatusCode=%v", resp.Response, want) + } + if err == nil { + t.Error("rate.Reset.Time > now ListTrafficViews err = nil, want error") + } } func TestRepositoriesService_ListTrafficClones(t *testing.T) { @@ -123,9 +210,10 @@ func TestRepositoriesService_ListTrafficClones(t *testing.T) { }]}`) }) - clones, _, err := client.Repositories.ListTrafficClones(context.Background(), "o", "r", nil) + ctx := context.Background() + got, resp, err := client.Repositories.ListTrafficClones(ctx, "o", "r", nil) if err != nil { - t.Errorf("Repositories.ListPaths returned error: %+v", err) + t.Errorf("Repositories.ListTrafficClones returned error: %+v", err) } want := &TrafficClones{ @@ -138,8 +226,40 @@ func TestRepositoriesService_ListTrafficClones(t *testing.T) { Uniques: Int(6), } - if !reflect.DeepEqual(clones, want) { - t.Errorf("Repositories.ListViews returned %+v, want %+v", clones, want) + if !reflect.DeepEqual(got, want) { + t.Errorf("Repositories.ListTrafficClones returned %+v, want %+v", got, want) + } + + // Test addOptions failure + got, resp, err = client.Repositories.ListTrafficClones(ctx, "\n", "\n", &TrafficBreakdownOptions{}) + if err == nil { + t.Error("bad options ListTrafficViews err = nil, want error") + } + + // Test s.client.NewRequest failure + client.BaseURL.Path = "" + got, resp, err = client.Repositories.ListTrafficClones(ctx, "o", "r", nil) + if got != nil { + t.Errorf("client.BaseURL.Path='' ListTrafficClones = %#v, want nil", got) + } + if resp != nil { + t.Errorf("client.BaseURL.Path='' ListTrafficClones resp = %#v, want nil", resp) + } + if err == nil { + t.Error("client.BaseURL.Path='' ListTrafficClones err = nil, want error") } + // Test s.client.Do failure + client.BaseURL.Path = "/api-v3/" + client.rateLimits[0].Reset.Time = time.Now().Add(10 * time.Minute) + got, resp, err = client.Repositories.ListTrafficClones(ctx, "o", "r", nil) + if got != nil { + t.Errorf("rate.Reset.Time > now ListTrafficClones = %#v, want nil", got) + } + if want := http.StatusForbidden; resp == nil || resp.Response.StatusCode != want { + t.Errorf("rate.Reset.Time > now ListTrafficClones resp = %#v, want StatusCode=%v", resp.Response, want) + } + if err == nil { + t.Error("rate.Reset.Time > now ListTrafficClones err = nil, want error") + } } From 477f37dae43aaa76cf83b89dc18250c4ae5cc305 Mon Sep 17 00:00:00 2001 From: Glenn Lewis <6598971+gmlewis@users.noreply.github.com> Date: Thu, 20 Jun 2019 22:59:42 -0400 Subject: [PATCH 0015/1468] Coverage: pulls_reviewers.go (#1204) --- github/pulls_reviewers_test.go | 89 +++++++++++++++++++++++++++++++--- 1 file changed, 82 insertions(+), 7 deletions(-) diff --git a/github/pulls_reviewers_test.go b/github/pulls_reviewers_test.go index 7c550e1bc57..8599bd777e7 100644 --- a/github/pulls_reviewers_test.go +++ b/github/pulls_reviewers_test.go @@ -11,6 +11,7 @@ import ( "net/http" "reflect" "testing" + "time" ) func TestRequestReviewers(t *testing.T) { @@ -24,13 +25,41 @@ func TestRequestReviewers(t *testing.T) { }) // This returns a PR, unmarshalling of which is tested elsewhere - pull, _, err := client.PullRequests.RequestReviewers(context.Background(), "o", "r", 1, ReviewersRequest{Reviewers: []string{"octocat", "googlebot"}, TeamReviewers: []string{"justice-league", "injustice-league"}}) + ctx := context.Background() + got, resp, err := client.PullRequests.RequestReviewers(ctx, "o", "r", 1, ReviewersRequest{Reviewers: []string{"octocat", "googlebot"}, TeamReviewers: []string{"justice-league", "injustice-league"}}) if err != nil { t.Errorf("PullRequests.RequestReviewers returned error: %v", err) } want := &PullRequest{Number: Int(1)} - if !reflect.DeepEqual(pull, want) { - t.Errorf("PullRequests.RequestReviewers returned %+v, want %+v", pull, want) + if !reflect.DeepEqual(got, want) { + t.Errorf("PullRequests.RequestReviewers returned %+v, want %+v", got, want) + } + + // Test s.client.NewRequest failure + client.BaseURL.Path = "" + got, resp, err = client.PullRequests.RequestReviewers(ctx, "o", "r", 1, ReviewersRequest{Reviewers: []string{"octocat", "googlebot"}, TeamReviewers: []string{"justice-league", "injustice-league"}}) + if got != nil { + t.Errorf("client.BaseURL.Path='' RequestReviewers = %#v, want nil", got) + } + if resp != nil { + t.Errorf("client.BaseURL.Path='' RequestReviewers resp = %#v, want nil", resp) + } + if err == nil { + t.Error("client.BaseURL.Path='' RequestReviewers err = nil, want error") + } + + // Test s.client.Do failure + client.BaseURL.Path = "/api-v3/" + client.rateLimits[0].Reset.Time = time.Now().Add(10 * time.Minute) + got, resp, err = client.PullRequests.RequestReviewers(ctx, "o", "r", 1, ReviewersRequest{Reviewers: []string{"octocat", "googlebot"}, TeamReviewers: []string{"justice-league", "injustice-league"}}) + if got != nil { + t.Errorf("rate.Reset.Time > now RequestReviewers = %#v, want nil", got) + } + if want := http.StatusForbidden; resp == nil || resp.Response.StatusCode != want { + t.Errorf("rate.Reset.Time > now RequestReviewers resp = %#v, want StatusCode=%v", resp.Response, want) + } + if err == nil { + t.Error("rate.Reset.Time > now RequestReviewers err = nil, want error") } } @@ -43,10 +72,21 @@ func TestRemoveReviewers(t *testing.T) { testBody(t, r, `{"reviewers":["octocat","googlebot"],"team_reviewers":["justice-league"]}`+"\n") }) - _, err := client.PullRequests.RemoveReviewers(context.Background(), "o", "r", 1, ReviewersRequest{Reviewers: []string{"octocat", "googlebot"}, TeamReviewers: []string{"justice-league"}}) + ctx := context.Background() + _, err := client.PullRequests.RemoveReviewers(ctx, "o", "r", 1, ReviewersRequest{Reviewers: []string{"octocat", "googlebot"}, TeamReviewers: []string{"justice-league"}}) if err != nil { t.Errorf("PullRequests.RemoveReviewers returned error: %v", err) } + + // Test s.client.NewRequest failure + client.BaseURL.Path = "" + resp, err := client.PullRequests.RemoveReviewers(ctx, "o", "r", 1, ReviewersRequest{Reviewers: []string{"octocat", "googlebot"}, TeamReviewers: []string{"justice-league"}}) + if resp != nil { + t.Errorf("client.BaseURL.Path='' RemoveReviewers resp = %#v, want nil", resp) + } + if err == nil { + t.Error("client.BaseURL.Path='' RemoveReviewers err = nil, want error") + } } func TestListReviewers(t *testing.T) { @@ -58,7 +98,8 @@ func TestListReviewers(t *testing.T) { fmt.Fprint(w, `{"users":[{"login":"octocat","id":1}],"teams":[{"id":1,"name":"Justice League"}]}`) }) - reviewers, _, err := client.PullRequests.ListReviewers(context.Background(), "o", "r", 1, nil) + ctx := context.Background() + got, resp, err := client.PullRequests.ListReviewers(ctx, "o", "r", 1, nil) if err != nil { t.Errorf("PullRequests.ListReviewers returned error: %v", err) } @@ -77,8 +118,35 @@ func TestListReviewers(t *testing.T) { }, }, } - if !reflect.DeepEqual(reviewers, want) { - t.Errorf("PullRequests.ListReviewers returned %+v, want %+v", reviewers, want) + if !reflect.DeepEqual(got, want) { + t.Errorf("PullRequests.ListReviewers returned %+v, want %+v", got, want) + } + + // Test s.client.NewRequest failure + client.BaseURL.Path = "" + got, resp, err = client.PullRequests.ListReviewers(ctx, "o", "r", 1, nil) + if got != nil { + t.Errorf("client.BaseURL.Path='' ListReviewers = %#v, want nil", got) + } + if resp != nil { + t.Errorf("client.BaseURL.Path='' ListReviewers resp = %#v, want nil", resp) + } + if err == nil { + t.Error("client.BaseURL.Path='' ListReviewers err = nil, want error") + } + + // Test s.client.Do failure + client.BaseURL.Path = "/api-v3/" + client.rateLimits[0].Reset.Time = time.Now().Add(10 * time.Minute) + got, resp, err = client.PullRequests.ListReviewers(ctx, "o", "r", 1, nil) + if got != nil { + t.Errorf("rate.Reset.Time > now ListReviewers = %#v, want nil", got) + } + if want := http.StatusForbidden; resp == nil || resp.Response.StatusCode != want { + t.Errorf("rate.Reset.Time > now ListReviewers resp = %#v, want StatusCode=%v", resp.Response, want) + } + if err == nil { + t.Error("rate.Reset.Time > now ListReviewers err = nil, want error") } } @@ -98,4 +166,11 @@ func TestListReviewers_withOptions(t *testing.T) { if err != nil { t.Errorf("PullRequests.ListReviewers returned error: %v", err) } + + // Test addOptions failure + _, _, err = client.PullRequests.ListReviewers(context.Background(), "\n", "\n", 1, &ListOptions{Page: 2}) + if err == nil { + t.Error("bad options ListReviewers err = nil, want error") + } + } From d62be1b1b7051fa43c64c83c8a0364f2bf0cde2f Mon Sep 17 00:00:00 2001 From: Glenn Lewis <6598971+gmlewis@users.noreply.github.com> Date: Thu, 20 Jun 2019 23:38:14 -0400 Subject: [PATCH 0016/1468] Coverage: repos.go (#1205) --- github/repos_test.go | 246 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 221 insertions(+), 25 deletions(-) diff --git a/github/repos_test.go b/github/repos_test.go index 6dd9973cd59..ebc1d8a782c 100644 --- a/github/repos_test.go +++ b/github/repos_test.go @@ -13,6 +13,7 @@ import ( "reflect" "strings" "testing" + "time" ) func TestRepositoriesService_List_authenticatedUser(t *testing.T) { @@ -26,14 +27,35 @@ func TestRepositoriesService_List_authenticatedUser(t *testing.T) { fmt.Fprint(w, `[{"id":1},{"id":2}]`) }) - repos, _, err := client.Repositories.List(context.Background(), "", nil) + ctx := context.Background() + got, resp, err := client.Repositories.List(ctx, "", nil) if err != nil { t.Errorf("Repositories.List returned error: %v", err) } want := []*Repository{{ID: Int64(1)}, {ID: Int64(2)}} - if !reflect.DeepEqual(repos, want) { - t.Errorf("Repositories.List returned %+v, want %+v", repos, want) + if !reflect.DeepEqual(got, want) { + t.Errorf("Repositories.List returned %+v, want %+v", got, want) + } + + // Test addOptions failure + got, resp, err = client.Repositories.List(ctx, "\n", &RepositoryListOptions{}) + if err == nil { + t.Error("bad options List err = nil, want error") + } + + // Test s.client.Do failure + client.BaseURL.Path = "/api-v3/" + client.rateLimits[0].Reset.Time = time.Now().Add(10 * time.Minute) + got, resp, err = client.Repositories.List(ctx, "", nil) + if got != nil { + t.Errorf("rate.Reset.Time > now List = %#v, want nil", got) + } + if want := http.StatusForbidden; resp == nil || resp.Response.StatusCode != want { + t.Errorf("rate.Reset.Time > now List resp = %#v, want StatusCode=%v", resp.Response, want) + } + if err == nil { + t.Error("rate.Reset.Time > now List err = nil, want error") } } @@ -124,15 +146,36 @@ func TestRepositoriesService_ListByOrg(t *testing.T) { fmt.Fprint(w, `[{"id":1}]`) }) + ctx := context.Background() opt := &RepositoryListByOrgOptions{"forks", ListOptions{Page: 2}} - repos, _, err := client.Repositories.ListByOrg(context.Background(), "o", opt) + got, resp, err := client.Repositories.ListByOrg(ctx, "o", opt) if err != nil { t.Errorf("Repositories.ListByOrg returned error: %v", err) } want := []*Repository{{ID: Int64(1)}} - if !reflect.DeepEqual(repos, want) { - t.Errorf("Repositories.ListByOrg returned %+v, want %+v", repos, want) + if !reflect.DeepEqual(got, want) { + t.Errorf("Repositories.ListByOrg returned %+v, want %+v", got, want) + } + + // Test addOptions failure + got, resp, err = client.Repositories.ListByOrg(ctx, "\n", opt) + if err == nil { + t.Error("bad options ListByOrg err = nil, want error") + } + + // Test s.client.Do failure + client.BaseURL.Path = "/api-v3/" + client.rateLimits[0].Reset.Time = time.Now().Add(10 * time.Minute) + got, resp, err = client.Repositories.ListByOrg(ctx, "o", opt) + if got != nil { + t.Errorf("rate.Reset.Time > now ListByOrg = %#v, want nil", got) + } + if want := http.StatusForbidden; resp == nil || resp.Response.StatusCode != want { + t.Errorf("rate.Reset.Time > now ListByOrg resp = %#v, want StatusCode=%v", resp.Response, want) + } + if err == nil { + t.Error("rate.Reset.Time > now ListByOrg err = nil, want error") } } @@ -156,15 +199,43 @@ func TestRepositoriesService_ListAll(t *testing.T) { fmt.Fprint(w, `[{"id":1}]`) }) + ctx := context.Background() opt := &RepositoryListAllOptions{1} - repos, _, err := client.Repositories.ListAll(context.Background(), opt) + got, resp, err := client.Repositories.ListAll(ctx, opt) if err != nil { t.Errorf("Repositories.ListAll returned error: %v", err) } want := []*Repository{{ID: Int64(1)}} - if !reflect.DeepEqual(repos, want) { - t.Errorf("Repositories.ListAll returned %+v, want %+v", repos, want) + if !reflect.DeepEqual(got, want) { + t.Errorf("Repositories.ListAll returned %+v, want %+v", got, want) + } + + // Test s.client.NewRequest failure + client.BaseURL.Path = "" + got, resp, err = client.Repositories.ListAll(ctx, &RepositoryListAllOptions{1}) + if got != nil { + t.Errorf("client.BaseURL.Path='' ListAll = %#v, want nil", got) + } + if resp != nil { + t.Errorf("client.BaseURL.Path='' ListAll resp = %#v, want nil", resp) + } + if err == nil { + t.Error("client.BaseURL.Path='' ListAll err = nil, want error") + } + + // Test s.client.Do failure + client.BaseURL.Path = "/api-v3/" + client.rateLimits[0].Reset.Time = time.Now().Add(10 * time.Minute) + got, resp, err = client.Repositories.ListAll(ctx, &RepositoryListAllOptions{1}) + if got != nil { + t.Errorf("rate.Reset.Time > now ListAll = %#v, want nil", got) + } + if want := http.StatusForbidden; resp == nil || resp.Response.StatusCode != want { + t.Errorf("rate.Reset.Time > now ListAll resp = %#v, want StatusCode=%v", resp.Response, want) + } + if err == nil { + t.Error("rate.Reset.Time > now ListAll err = nil, want error") } } @@ -190,14 +261,42 @@ func TestRepositoriesService_Create_user(t *testing.T) { fmt.Fprint(w, `{"id":1}`) }) - repo, _, err := client.Repositories.Create(context.Background(), "", input) + ctx := context.Background() + got, resp, err := client.Repositories.Create(ctx, "", input) if err != nil { t.Errorf("Repositories.Create returned error: %v", err) } want := &Repository{ID: Int64(1)} - if !reflect.DeepEqual(repo, want) { - t.Errorf("Repositories.Create returned %+v, want %+v", repo, want) + if !reflect.DeepEqual(got, want) { + t.Errorf("Repositories.Create returned %+v, want %+v", got, want) + } + + // Test s.client.NewRequest failure + client.BaseURL.Path = "" + got, resp, err = client.Repositories.Create(ctx, "", input) + if got != nil { + t.Errorf("client.BaseURL.Path='' Create = %#v, want nil", got) + } + if resp != nil { + t.Errorf("client.BaseURL.Path='' Create resp = %#v, want nil", resp) + } + if err == nil { + t.Error("client.BaseURL.Path='' Create err = nil, want error") + } + + // Test s.client.Do failure + client.BaseURL.Path = "/api-v3/" + client.rateLimits[0].Reset.Time = time.Now().Add(10 * time.Minute) + got, resp, err = client.Repositories.Create(ctx, "", input) + if got != nil { + t.Errorf("rate.Reset.Time > now Create = %#v, want nil", got) + } + if want := http.StatusForbidden; resp == nil || resp.Response.StatusCode != want { + t.Errorf("rate.Reset.Time > now Create resp = %#v, want StatusCode=%v", resp.Response, want) + } + if err == nil { + t.Error("rate.Reset.Time > now Create err = nil, want error") } } @@ -245,14 +344,29 @@ func TestRepositoriesService_Get(t *testing.T) { fmt.Fprint(w, `{"id":1,"name":"n","description":"d","owner":{"login":"l"},"license":{"key":"mit"}}`) }) - repo, _, err := client.Repositories.Get(context.Background(), "o", "r") + ctx := context.Background() + got, resp, err := client.Repositories.Get(ctx, "o", "r") if err != nil { t.Errorf("Repositories.Get returned error: %v", err) } want := &Repository{ID: Int64(1), Name: String("n"), Description: String("d"), Owner: &User{Login: String("l")}, License: &License{Key: String("mit")}} - if !reflect.DeepEqual(repo, want) { - t.Errorf("Repositories.Get returned %+v, want %+v", repo, want) + if !reflect.DeepEqual(got, want) { + t.Errorf("Repositories.Get returned %+v, want %+v", got, want) + } + + // Test s.client.Do failure + client.BaseURL.Path = "/api-v3/" + client.rateLimits[0].Reset.Time = time.Now().Add(10 * time.Minute) + got, resp, err = client.Repositories.Get(ctx, "o", "r") + if got != nil { + t.Errorf("rate.Reset.Time > now Get = %#v, want nil", got) + } + if want := http.StatusForbidden; resp == nil || resp.Response.StatusCode != want { + t.Errorf("rate.Reset.Time > now Get resp = %#v, want StatusCode=%v", resp.Response, want) + } + if err == nil { + t.Error("rate.Reset.Time > now Get err = nil, want error") } } @@ -271,7 +385,8 @@ func TestRepositoriesService_GetCodeOfConduct(t *testing.T) { ) }) - coc, _, err := client.Repositories.GetCodeOfConduct(context.Background(), "o", "r") + ctx := context.Background() + got, resp, err := client.Repositories.GetCodeOfConduct(ctx, "o", "r") if err != nil { t.Errorf("Repositories.GetCodeOfConduct returned error: %v", err) } @@ -283,8 +398,35 @@ func TestRepositoriesService_GetCodeOfConduct(t *testing.T) { Body: String("body"), } - if !reflect.DeepEqual(coc, want) { - t.Errorf("Repositories.Get returned %+v, want %+v", coc, want) + if !reflect.DeepEqual(got, want) { + t.Errorf("Repositories.GetCodeOfConduct returned %+v, want %+v", got, want) + } + + // Test s.client.NewRequest failure + client.BaseURL.Path = "" + got, resp, err = client.Repositories.GetCodeOfConduct(ctx, "o", "r") + if got != nil { + t.Errorf("client.BaseURL.Path='' GetCodeOfConduct = %#v, want nil", got) + } + if resp != nil { + t.Errorf("client.BaseURL.Path='' GetCodeOfConduct resp = %#v, want nil", resp) + } + if err == nil { + t.Error("client.BaseURL.Path='' GetCodeOfConduct err = nil, want error") + } + + // Test s.client.Do failure + client.BaseURL.Path = "/api-v3/" + client.rateLimits[0].Reset.Time = time.Now().Add(10 * time.Minute) + got, resp, err = client.Repositories.GetCodeOfConduct(ctx, "o", "r") + if got != nil { + t.Errorf("rate.Reset.Time > now GetCodeOfConduct = %#v, want nil", got) + } + if want := http.StatusForbidden; resp == nil || resp.Response.StatusCode != want { + t.Errorf("rate.Reset.Time > now GetCodeOfConduct resp = %#v, want StatusCode=%v", resp.Response, want) + } + if err == nil { + t.Error("rate.Reset.Time > now GetCodeOfConduct err = nil, want error") } } @@ -297,14 +439,42 @@ func TestRepositoriesService_GetByID(t *testing.T) { fmt.Fprint(w, `{"id":1,"name":"n","description":"d","owner":{"login":"l"},"license":{"key":"mit"}}`) }) - repo, _, err := client.Repositories.GetByID(context.Background(), 1) + ctx := context.Background() + got, resp, err := client.Repositories.GetByID(ctx, 1) if err != nil { t.Fatalf("Repositories.GetByID returned error: %v", err) } want := &Repository{ID: Int64(1), Name: String("n"), Description: String("d"), Owner: &User{Login: String("l")}, License: &License{Key: String("mit")}} - if !reflect.DeepEqual(repo, want) { - t.Errorf("Repositories.GetByID returned %+v, want %+v", repo, want) + if !reflect.DeepEqual(got, want) { + t.Errorf("Repositories.GetByID returned %+v, want %+v", got, want) + } + + // Test s.client.NewRequest failure + client.BaseURL.Path = "" + got, resp, err = client.Repositories.GetByID(ctx, 1) + if got != nil { + t.Errorf("client.BaseURL.Path='' GetByID = %#v, want nil", got) + } + if resp != nil { + t.Errorf("client.BaseURL.Path='' GetByID resp = %#v, want nil", resp) + } + if err == nil { + t.Error("client.BaseURL.Path='' GetByID err = nil, want error") + } + + // Test s.client.Do failure + client.BaseURL.Path = "/api-v3/" + client.rateLimits[0].Reset.Time = time.Now().Add(10 * time.Minute) + got, resp, err = client.Repositories.GetByID(ctx, 1) + if got != nil { + t.Errorf("rate.Reset.Time > now GetByID = %#v, want nil", got) + } + if want := http.StatusForbidden; resp == nil || resp.Response.StatusCode != want { + t.Errorf("rate.Reset.Time > now GetByID resp = %#v, want StatusCode=%v", resp.Response, want) + } + if err == nil { + t.Error("rate.Reset.Time > now GetByID err = nil, want error") } } @@ -326,14 +496,29 @@ func TestRepositoriesService_Edit(t *testing.T) { fmt.Fprint(w, `{"id":1}`) }) - repo, _, err := client.Repositories.Edit(context.Background(), "o", "r", input) + ctx := context.Background() + got, resp, err := client.Repositories.Edit(ctx, "o", "r", input) if err != nil { t.Errorf("Repositories.Edit returned error: %v", err) } want := &Repository{ID: Int64(1)} - if !reflect.DeepEqual(repo, want) { - t.Errorf("Repositories.Edit returned %+v, want %+v", repo, want) + if !reflect.DeepEqual(got, want) { + t.Errorf("Repositories.Edit returned %+v, want %+v", got, want) + } + + // Test s.client.Do failure + client.BaseURL.Path = "/api-v3/" + client.rateLimits[0].Reset.Time = time.Now().Add(10 * time.Minute) + got, resp, err = client.Repositories.Edit(ctx, "o", "r", input) + if got != nil { + t.Errorf("rate.Reset.Time > now Edit = %#v, want nil", got) + } + if want := http.StatusForbidden; resp == nil || resp.Response.StatusCode != want { + t.Errorf("rate.Reset.Time > now Edit resp = %#v, want StatusCode=%v", resp.Response, want) + } + if err == nil { + t.Error("rate.Reset.Time > now Edit err = nil, want error") } } @@ -345,10 +530,21 @@ func TestRepositoriesService_Delete(t *testing.T) { testMethod(t, r, "DELETE") }) - _, err := client.Repositories.Delete(context.Background(), "o", "r") + ctx := context.Background() + resp, err := client.Repositories.Delete(ctx, "o", "r") if err != nil { t.Errorf("Repositories.Delete returned error: %v", err) } + + // Test s.client.NewRequest failure + client.BaseURL.Path = "" + resp, err = client.Repositories.Delete(ctx, "o", "r") + if resp != nil { + t.Errorf("client.BaseURL.Path='' Delete resp = %#v, want nil", resp) + } + if err == nil { + t.Error("client.BaseURL.Path='' Delete err = nil, want error") + } } func TestRepositoriesService_Get_invalidOwner(t *testing.T) { From cbe45b0df73f1c7e08497180a4cb754eb5b757b3 Mon Sep 17 00:00:00 2001 From: Anandkumar Patel Date: Sat, 22 Jun 2019 12:36:27 -0400 Subject: [PATCH 0017/1468] Add SignKey GPG entity param to allow easier signing of commits (#1198) --- github/git_commits.go | 65 ++++++++ github/git_commits_test.go | 311 ++++++++++++++++++++++++++++++++++++- 2 files changed, 370 insertions(+), 6 deletions(-) diff --git a/github/git_commits.go b/github/git_commits.go index 9dfd3afb3b5..741961980a1 100644 --- a/github/git_commits.go +++ b/github/git_commits.go @@ -6,9 +6,14 @@ package github import ( + "bytes" "context" + "errors" "fmt" + "strings" "time" + + "golang.org/x/crypto/openpgp" ) // SignatureVerification represents GPG signature verification. @@ -37,6 +42,11 @@ type Commit struct { // is only populated for requests that fetch GitHub data like // Pulls.ListCommits, Repositories.ListCommits, etc. CommentCount *int `json:"comment_count,omitempty"` + + // SigningKey denotes a key to sign the commit with. If not nil this key will + // be used to sign the commit. The private key must be present and already + // decrypted. Ignored if Verification.Signature is defined. + SigningKey *openpgp.Entity `json:"-"` } func (c Commit) String() string { @@ -116,6 +126,13 @@ func (s *GitService) CreateCommit(ctx context.Context, owner string, repo string if commit.Tree != nil { body.Tree = commit.Tree.SHA } + if commit.SigningKey != nil { + signature, err := createSignature(commit.SigningKey, body) + if err != nil { + return nil, nil, err + } + body.Signature = &signature + } if commit.Verification != nil { body.Signature = commit.Verification.Signature } @@ -133,3 +150,51 @@ func (s *GitService) CreateCommit(ctx context.Context, owner string, repo string return c, resp, nil } + +func createSignature(signingKey *openpgp.Entity, commit *createCommit) (string, error) { + if signingKey == nil || commit == nil { + return "", errors.New("createSignature: invalid parameters") + } + + message, err := createSignatureMessage(commit) + if err != nil { + return "", err + } + + writer := new(bytes.Buffer) + reader := bytes.NewReader([]byte(message)) + if err := openpgp.ArmoredDetachSign(writer, signingKey, reader, nil); err != nil { + return "", err + } + + return writer.String(), nil +} + +func createSignatureMessage(commit *createCommit) (string, error) { + if commit == nil || commit.Message == nil || *commit.Message == "" || commit.Author == nil { + return "", errors.New("createSignatureMessage: invalid parameters") + } + + var message []string + + if commit.Tree != nil { + message = append(message, fmt.Sprintf("tree %s", *commit.Tree)) + } + + for _, parent := range commit.Parents { + message = append(message, fmt.Sprintf("parent %s", parent)) + } + + message = append(message, fmt.Sprintf("author %s <%s> %d %s", commit.Author.GetName(), commit.Author.GetEmail(), commit.Author.GetDate().Unix(), commit.Author.GetDate().Format("-0700"))) + + committer := commit.Committer + if committer == nil { + committer = commit.Author + } + + // There needs to be a double newline after committer + message = append(message, fmt.Sprintf("committer %s <%s> %d %s\n", committer.GetName(), committer.GetEmail(), committer.GetDate().Unix(), committer.GetDate().Format("-0700"))) + message = append(message, *commit.Message) + + return strings.Join(message, "\n"), nil +} diff --git a/github/git_commits_test.go b/github/git_commits_test.go index 83f56407295..580e6b05515 100644 --- a/github/git_commits_test.go +++ b/github/git_commits_test.go @@ -11,7 +11,11 @@ import ( "fmt" "net/http" "reflect" + "strings" "testing" + "time" + + "golang.org/x/crypto/openpgp" ) func TestGitService_GetCommit(t *testing.T) { @@ -20,7 +24,7 @@ func TestGitService_GetCommit(t *testing.T) { mux.HandleFunc("/repos/o/r/git/commits/s", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") - fmt.Fprint(w, `{"sha":"s","message":"m","author":{"name":"n"}}`) + fmt.Fprint(w, `{"sha":"s","message":"Commit Message.","author":{"name":"n"}}`) }) commit, _, err := client.Git.GetCommit(context.Background(), "o", "r", "s") @@ -28,7 +32,7 @@ func TestGitService_GetCommit(t *testing.T) { t.Errorf("Git.GetCommit returned error: %v", err) } - want := &Commit{SHA: String("s"), Message: String("m"), Author: &CommitAuthor{Name: String("n")}} + want := &Commit{SHA: String("s"), Message: String("Commit Message."), Author: &CommitAuthor{Name: String("n")}} if !reflect.DeepEqual(commit, want) { t.Errorf("Git.GetCommit returned %+v, want %+v", commit, want) } @@ -47,7 +51,7 @@ func TestGitService_CreateCommit(t *testing.T) { defer teardown() input := &Commit{ - Message: String("m"), + Message: String("Commit Message."), Tree: &Tree{SHA: String("t")}, Parents: []Commit{{SHA: String("p")}}, } @@ -87,7 +91,7 @@ func TestGitService_CreateSignedCommit(t *testing.T) { signature := "----- BEGIN PGP SIGNATURE -----\n\naaaa\naaaa\n----- END PGP SIGNATURE -----" input := &Commit{ - Message: String("m"), + Message: String("Commit Message."), Tree: &Tree{SHA: String("t")}, Parents: []Commit{{SHA: String("p")}}, Verification: &SignatureVerification{ @@ -110,7 +114,7 @@ func TestGitService_CreateSignedCommit(t *testing.T) { if !reflect.DeepEqual(v, want) { t.Errorf("Request body = %+v, want %+v", v, want) } - fmt.Fprint(w, `{"sha":"s"}`) + fmt.Fprint(w, `{"sha":"commitSha"}`) }) commit, _, err := client.Git.CreateCommit(context.Background(), "o", "r", input) @@ -118,12 +122,248 @@ func TestGitService_CreateSignedCommit(t *testing.T) { t.Errorf("Git.CreateCommit returned error: %v", err) } - want := &Commit{SHA: String("s")} + want := &Commit{SHA: String("commitSha")} + if !reflect.DeepEqual(commit, want) { + t.Errorf("Git.CreateCommit returned %+v, want %+v", commit, want) + } +} +func TestGitService_CreateSignedCommitWithInvalidParams(t *testing.T) { + client, _, _, teardown := setup() + defer teardown() + + input := &Commit{ + SigningKey: &openpgp.Entity{}, + } + + _, _, err := client.Git.CreateCommit(context.Background(), "o", "r", input) + if err == nil { + t.Errorf("Expected error to be returned because invalid params was passed") + } +} + +func TestGitService_CreateSignedCommitWithKey(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + s := strings.NewReader(testGPGKey) + keyring, err := openpgp.ReadArmoredKeyRing(s) + + date, _ := time.Parse("Mon Jan 02 15:04:05 2006 -0700", "Thu May 04 00:03:43 2017 +0200") + author := CommitAuthor{ + Name: String("go-github"), + Email: String("go-github@github.com"), + Date: &date, + } + input := &Commit{ + Message: String("Commit Message."), + Tree: &Tree{SHA: String("t")}, + Parents: []Commit{{SHA: String("p")}}, + SigningKey: keyring[0], + Author: &author, + } + + messageReader := strings.NewReader(`tree t +parent p +author go-github 1493849023 +0200 +committer go-github 1493849023 +0200 + +Commit Message.`) + + mux.HandleFunc("/repos/o/r/git/commits", func(w http.ResponseWriter, r *http.Request) { + v := new(createCommit) + json.NewDecoder(r.Body).Decode(v) + + testMethod(t, r, "POST") + + want := &createCommit{ + Message: input.Message, + Tree: String("t"), + Parents: []string{"p"}, + Author: &author, + } + + sigReader := strings.NewReader(*v.Signature) + signer, err := openpgp.CheckArmoredDetachedSignature(keyring, messageReader, sigReader) + if err != nil { + t.Errorf("Error verifying signature: %+v", err) + } + if signer.Identities["go-github "].Name != "go-github " { + t.Errorf("Signer is incorrect. got: %+v, want %+v", signer.Identities["go-github "].Name, "go-github ") + } + // Nullify Signature since we checked it above + v.Signature = nil + if !reflect.DeepEqual(v, want) { + t.Errorf("Request body = %+v, want %+v", v, want) + } + fmt.Fprint(w, `{"sha":"commitSha"}`) + }) + + commit, _, err := client.Git.CreateCommit(context.Background(), "o", "r", input) + if err != nil { + t.Errorf("Git.CreateCommit returned error: %v", err) + } + + want := &Commit{SHA: String("commitSha")} if !reflect.DeepEqual(commit, want) { t.Errorf("Git.CreateCommit returned %+v, want %+v", commit, want) } } +func TestGitService_createSignature_nilSigningKey(t *testing.T) { + a := &createCommit{ + Message: String("Commit Message."), + Tree: String("t"), + Parents: []string{"p"}, + } + + _, err := createSignature(nil, a) + + if err == nil { + t.Errorf("Expected error to be returned because no author was passed") + } +} + +func TestGitService_createSignature_nilCommit(t *testing.T) { + _, err := createSignature(&openpgp.Entity{}, nil) + + if err == nil { + t.Errorf("Expected error to be returned because no author was passed") + } +} + +func TestGitService_createSignature_noAuthor(t *testing.T) { + a := &createCommit{ + Message: String("Commit Message."), + Tree: String("t"), + Parents: []string{"p"}, + } + + _, err := createSignature(&openpgp.Entity{}, a) + + if err == nil { + t.Errorf("Expected error to be returned because no author was passed") + } +} + +func TestGitService_createSignature_invalidKey(t *testing.T) { + date, _ := time.Parse("Mon Jan 02 15:04:05 2006 -0700", "Thu May 04 00:03:43 2017 +0200") + + _, err := createSignature(&openpgp.Entity{}, &createCommit{ + Message: String("Commit Message."), + Tree: String("t"), + Parents: []string{"p"}, + Author: &CommitAuthor{ + Name: String("go-github"), + Email: String("go-github@github.com"), + Date: &date, + }, + }) + + if err == nil { + t.Errorf("Expected error to be returned due to invalid key") + } +} + +func TestGitService_createSignatureMessage_nilCommit(t *testing.T) { + _, err := createSignatureMessage(nil) + if err == nil { + t.Errorf("Expected error to be returned due to nil key") + } +} + +func TestGitService_createSignatureMessage_nilMessage(t *testing.T) { + date, _ := time.Parse("Mon Jan 02 15:04:05 2006 -0700", "Thu May 04 00:03:43 2017 +0200") + + _, err := createSignatureMessage(&createCommit{ + Message: nil, + Parents: []string{"p"}, + Author: &CommitAuthor{ + Name: String("go-github"), + Email: String("go-github@github.com"), + Date: &date, + }, + }) + if err == nil { + t.Errorf("Expected error to be returned due to nil key") + } +} + +func TestGitService_createSignatureMessage_emptyMessage(t *testing.T) { + date, _ := time.Parse("Mon Jan 02 15:04:05 2006 -0700", "Thu May 04 00:03:43 2017 +0200") + emptyString := "" + _, err := createSignatureMessage(&createCommit{ + Message: &emptyString, + Parents: []string{"p"}, + Author: &CommitAuthor{ + Name: String("go-github"), + Email: String("go-github@github.com"), + Date: &date, + }, + }) + if err == nil { + t.Errorf("Expected error to be returned due to nil key") + } +} + +func TestGitService_createSignatureMessage_nilAuthor(t *testing.T) { + _, err := createSignatureMessage(&createCommit{ + Message: String("Commit Message."), + Parents: []string{"p"}, + Author: nil, + }) + if err == nil { + t.Errorf("Expected error to be returned due to nil key") + } +} + +func TestGitService_createSignatureMessage_withoutTree(t *testing.T) { + date, _ := time.Parse("Mon Jan 02 15:04:05 2006 -0700", "Thu May 04 00:03:43 2017 +0200") + + msg, _ := createSignatureMessage(&createCommit{ + Message: String("Commit Message."), + Parents: []string{"p"}, + Author: &CommitAuthor{ + Name: String("go-github"), + Email: String("go-github@github.com"), + Date: &date, + }, + }) + expected := `parent p +author go-github 1493849023 +0200 +committer go-github 1493849023 +0200 + +Commit Message.` + if msg != expected { + t.Errorf("Returned message incorrect. returned %s, want %s", msg, expected) + } +} + +func TestGitService_createSignatureMessage_withoutCommitter(t *testing.T) { + date, _ := time.Parse("Mon Jan 02 15:04:05 2006 -0700", "Thu May 04 00:03:43 2017 +0200") + + msg, _ := createSignatureMessage(&createCommit{ + Message: String("Commit Message."), + Parents: []string{"p"}, + Author: &CommitAuthor{ + Name: String("go-github"), + Email: String("go-github@github.com"), + Date: &date, + }, + Committer: &CommitAuthor{ + Name: String("foo"), + Email: String("foo@bar.com"), + Date: &date, + }, + }) + expected := `parent p +author go-github 1493849023 +0200 +committer foo 1493849023 +0200 + +Commit Message.` + if msg != expected { + t.Errorf("Returned message incorrect. returned %s, want %s", msg, expected) + } +} + func TestGitService_CreateCommit_invalidOwner(t *testing.T) { client, _, _, teardown := setup() defer teardown() @@ -131,3 +371,62 @@ func TestGitService_CreateCommit_invalidOwner(t *testing.T) { _, _, err := client.Git.CreateCommit(context.Background(), "%", "%", &Commit{}) testURLParseError(t, err) } + +const testGPGKey = ` +-----BEGIN PGP PRIVATE KEY BLOCK----- + +lQOYBFyi1qYBCAD3EPfLJzIt4qkAceUKkhdvfaIvOsBwXbfr5sSu/lkMqL0Wq47+ +iv+SRwOC7zvN8SlB8nPUgs5dbTRCJJfG5MAqTRR7KZRbyq2jBpi4BtmO30Ul/qId +3A18cVUfgVbxH85K9bdnyOxep/Q2NjLjTKmWLkzgmgkfbUmSLuWW9HRXPjYy9B7i +dOFD6GdkN/HwPAaId8ym0TE1mIuSpw8UQHyxusAkK52Pn4h/PgJhLTzbSi1X2eDt +OgzjhbdxTPzKFQfs97dY8y9C7Bt+CqH6Bvr3785LeKdxiUnCjfUJ+WAoJy780ec+ +IVwSpPp1CaEtzu73w6GH5945GELHE8HRe25FABEBAAEAB/9dtx72/VAoXZCTbaBe +iRnAnZwWZCe4t6PbJHa4lhv7FEpdPggIf3r/5lXrpYk+zdpDfI75LgDPKWwoJq83 +r29A3GoHabcvtkp0yzzEmTyO2BvnlJWz09N9v5N1Vt8+qTzb7CZ8hJc8NGMK6TYW +R+8P21In4+XP+OluPMGzp9g1etHScLhQUtF/xcN3JQGkeq4CPX6jUSYlJNeEtuLm +xjBTLBdg8zK5mJ3tolvnS/VhSTdiBeUaYtVt/qxq+fPqdFGHrO5H9ORbt56ahU+f +Ne86sOjQfJZPsx9z8ffP+XhLZPT1ZUGJMI/Vysx9gwDiEnaxrCJ02fO0Dnqsj/o2 +T14lBAD55+KtaS0C0OpHpA/F+XhL3IDcYQOYgu8idBTshr4vv7M+jdZqpECOn72Q +8SZJ+gYMcA9Z07Afnin1DVdtxiMN/tbyOu7e1BE7y77eA+zQw4PjLJPZJMbco7z+ +q9ZnZF3GyRyil6HkKUTfrao8AMtb0allZnqXwpPb5Mza32VqtwQA/RdbG6OIS6og +OpP7zKu4GP4guBk8NrVpVuV5Xz4r8JlL+POt0TadlT93coW/SajLrN/eeUwk6jQw +wrabmIGMarG5mrC4tnXLze5LICJTpOuqCACyFwL6w/ag+c7Qt9t9hvLMDFifcZW/ +mylqY7Z1eVcnbOcFsQG+0LzJBU0qouMEAKkXmJcQ3lJM8yoJuYOvbwexVR+5Y+5v +FNEGPlp3H/fq6ETYWHjMxPOE5dvGbQL8oKWZgkkHEGAKAavEGebM/y/qIPOCAluT +tn1sfx//n6kTMhswpg/3+BciUaJFjwYbIwUH5XD0vFbe9O2VOfTVdo1p19wegVs5 +LMf8rWFWYXtqUgG0IGdvLWdpdGh1YiA8Z28tZ2l0aHViQGdpdGh1Yi5jb20+iQFU +BBMBCAA+FiEELZ6AMqOpBMVblK0uiKTQXVy+MAsFAlyi1qYCGwMFCQPCZwAFCwkI +BwIGFQoJCAsCBBYCAwECHgECF4AACgkQiKTQXVy+MAtEYggA0LRecz71HUjEKXJj +C5Wgds1hZ0q+g3ew7zms4fuascd/2PqT5lItHU3oezdzMOHetSPvPzJILjl7RYcY +pWvoyzEBC5MutlmuzfwUa7qYCiuRDkYRjke8a4o8ijsxc8ANXwulXcI3udjAZdV0 +CKjrjPTyrHFUnPyZyaZp8p2eX62iPYhaXkoBnEiarf0xKtJuT/8IlP5n/redlKYz +GIHG5Svg3uDq9E09BOjFsgemhPyqbf7yrh5aRwDOIdHtn9mNevFPfQ1jO8lI/wbe +4kC6zXM7te0/ZkM06DYRhcaeoYdeyY/gvE+w7wU/+f7Wzqt+LxOMIjKk0oDxZIv9 +praEM50DmARcotamAQgAsiO75WZvjt7BEAzdTvWekWXqBo4NOes2UgzSYToVs6xW +8iXnE+mpDS7GHtNQLU6oeC0vizUjCwBfU+qGqw1JjI3I1pwv7xRqBIlA6f5ancVK +KiMx+/HxasbBrbav8DmZT8E8VaJhYM614Kav91W8YoqK5YXmP/A+OwwhkVEGo8v3 +Iy7mnJPMSjNiNTpiDgc5wvRiTan+uf+AtNPUS0k0fbrTZWosbrSmBymhrEy8stMj +rG2wZX5aRY7AXrQXoIXedqvP3kW/nqd0wvuiD11ZZWvoawjZRRVsT27DED0x2+o6 +aAEKrSLj8LlWvGVkD/jP9lSkC81uwGgD5VIMeXv6EQARAQABAAf7BHef8SdJ+ee9 +KLVh4WaIdPX80fBDBaZP5OvcZMLLo4dZYNYxfs7XxfRb1I8RDinQUL81V4TcHZ0D +Rvv1J5n8M7GkjTk6fIDjDb0RayzNQfKeIwNh8AMHvllApyYTMG+JWDYs2KrrTT2x +0vHrLMUyJbh6tjnO5eCU9u8dcmL5Syc6DzGUvDl6ZdJxlHEEJOwMlVCwQn5LQDVI +t0KEXigqs7eDCpTduJeAI7oA96s/8LwdlG5t6q9vbkEjl1XpR5FfKvJcZbd7Kmk9 +6R0EdbH6Ffe8qAp8lGmjx+91gqeL7jyl500H4gK/ybzlxQczIsbQ7WcZTPEnROIX +tCFWh6puvwQAyV6ygcatz+1BfCfgxWNYFXyowwOGSP9Nma+/aDVdeRCjZ69Is0lz +GV0NNqh7hpaoVbXS9Vc3sFOwBr5ZyKQaf07BoCDW+XJtvPyyZNLb004smtB5uHCf +uWDBpQ9erlrpSkOLgifbzfkYHdSvhc2ws9Tgab7Mk7P/ExOZjnUJPOcEAOJ3q/2/ +0wqRnkSelgkWwUmZ+hFIBz6lgWS3KTJs6Qc5WBnXono+EOoqhFxsiRM4lewExxHM +kPIcxb+0hiNz8hJkWOHEdgkXNim9Q08J0HPz6owtlD/rtmOi2+7d5BukbY/3JEXs +r2bjqbXXIE7heytIn/dQv7aEDyDqexiJKnpHBACQItjuYlewLt94NMNdGcwxmKdJ +bfaoIQz1h8fX5uSGKU+hXatI6sltD9PrhwwhdqJNcQ0K1dRkm24olO4I/sJwactI +G3r1UTq6BMV94eIyS/zZH5xChlOUavy9PrgU3kAK21bdmAFuNwbHnN34BBUk9J6f +IIxEZUOxw2CrKhsubUOuiQE8BBgBCAAmFiEELZ6AMqOpBMVblK0uiKTQXVy+MAsF +Alyi1qYCGwwFCQPCZwAACgkQiKTQXVy+MAstJAf/Tm2hfagVjzgJ5pFHmpP+fYxp +8dIPZLonP5HW12iaSOXThtvWBY578Cb9RmU+WkHyPXg8SyshW7aco4HrUDk+Qmyi +f9BvHS5RsLbyPlhgCqNkn+3QS62fZiIlbHLrQ/6iHXkgLV04Fnj+F4v8YYpOI9nY +NFc5iWm0zZRcLiRKZk1up8SCngyolcjVuTuCXDKyAUX1jRqDu7tlN0qVH0CYDGch +BqTKXNkzAvV+CKOyaUILSBBWdef+cxVrDCJuuC3894x3G1FjJycOy0m9PArvGtSG +g7/0Bp9oLXwiHzFoUMDvx+WlPnPHQNcufmQXUNdZvg+Ad4/unEU81EGDBDz3Eg== +=VFSn +-----END PGP PRIVATE KEY BLOCK-----` From 445d3bd422a8e75398ca4c1a6a287d05056f4068 Mon Sep 17 00:00:00 2001 From: Martin Taillefer Date: Mon, 24 Jun 2019 20:19:40 -0700 Subject: [PATCH 0018/1468] Add missing RepositoryComment.NodeID field. (#1209) --- github/github-accessors.go | 8 ++++++++ github/github-stringify_test.go | 3 ++- github/repos_comments.go | 1 + 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/github/github-accessors.go b/github/github-accessors.go index 0bb206bd509..687c9689f09 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -9940,6 +9940,14 @@ func (r *RepositoryComment) GetID() int64 { return *r.ID } +// GetNodeID returns the NodeID field if it's non-nil, zero value otherwise. +func (r *RepositoryComment) GetNodeID() string { + if r == nil || r.NodeID == nil { + return "" + } + return *r.NodeID +} + // GetPath returns the Path field if it's non-nil, zero value otherwise. func (r *RepositoryComment) GetPath() string { if r == nil || r.Path == nil { diff --git a/github/github-stringify_test.go b/github/github-stringify_test.go index 2271a9d2b11..e8c0e2683ac 100644 --- a/github/github-stringify_test.go +++ b/github/github-stringify_test.go @@ -1262,6 +1262,7 @@ func TestRepositoryComment_String(t *testing.T) { HTMLURL: String(""), URL: String(""), ID: Int64(0), + NodeID: String(""), CommitID: String(""), User: &User{}, Reactions: &Reactions{}, @@ -1269,7 +1270,7 @@ func TestRepositoryComment_String(t *testing.T) { Path: String(""), Position: Int(0), } - want := `github.RepositoryComment{HTMLURL:"", URL:"", ID:0, CommitID:"", User:github.User{}, Reactions:github.Reactions{}, Body:"", Path:"", Position:0}` + want := `github.RepositoryComment{HTMLURL:"", URL:"", ID:0, NodeID:"", CommitID:"", User:github.User{}, Reactions:github.Reactions{}, Body:"", Path:"", Position:0}` if got := v.String(); got != want { t.Errorf("RepositoryComment.String = %v, want %v", got, want) } diff --git a/github/repos_comments.go b/github/repos_comments.go index fa2377d403d..380ca3d3b43 100644 --- a/github/repos_comments.go +++ b/github/repos_comments.go @@ -16,6 +16,7 @@ type RepositoryComment struct { HTMLURL *string `json:"html_url,omitempty"` URL *string `json:"url,omitempty"` ID *int64 `json:"id,omitempty"` + NodeID *string `json:"node_id,omitempty"` CommitID *string `json:"commit_id,omitempty"` User *User `json:"user,omitempty"` Reactions *Reactions `json:"reactions,omitempty"` From ababee01b03f69965d0ec370e65b61ec7967be34 Mon Sep 17 00:00:00 2001 From: anjanashenoy Date: Tue, 25 Jun 2019 15:29:59 -0400 Subject: [PATCH 0019/1468] Add missing `LdapDn` field in Users class (#1211) Fixes #1210 for GitHub Enterprise users. --- github/github-accessors.go | 8 ++++++++ github/github-stringify_test.go | 3 ++- github/users.go | 1 + 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/github/github-accessors.go b/github/github-accessors.go index 687c9689f09..b92e81fec29 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -12164,6 +12164,14 @@ func (u *User) GetID() int64 { return *u.ID } +// GetLdapDn returns the LdapDn field if it's non-nil, zero value otherwise. +func (u *User) GetLdapDn() string { + if u == nil || u.LdapDn == nil { + return "" + } + return *u.LdapDn +} + // GetLocation returns the Location field if it's non-nil, zero value otherwise. func (u *User) GetLocation() string { if u == nil || u.Location == nil { diff --git a/github/github-stringify_test.go b/github/github-stringify_test.go index e8c0e2683ac..6934f237c1d 100644 --- a/github/github-stringify_test.go +++ b/github/github-stringify_test.go @@ -1519,6 +1519,7 @@ func TestUser_String(t *testing.T) { Collaborators: Int(0), TwoFactorAuthentication: Bool(false), Plan: &Plan{}, + LdapDn: String(""), URL: String(""), EventsURL: String(""), FollowingURL: String(""), @@ -1530,7 +1531,7 @@ func TestUser_String(t *testing.T) { StarredURL: String(""), SubscriptionsURL: String(""), } - want := `github.User{Login:"", ID:0, NodeID:"", AvatarURL:"", HTMLURL:"", GravatarID:"", Name:"", Company:"", Blog:"", Location:"", Email:"", Hireable:false, Bio:"", PublicRepos:0, PublicGists:0, Followers:0, Following:0, CreatedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, UpdatedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, SuspendedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, Type:"", SiteAdmin:false, TotalPrivateRepos:0, OwnedPrivateRepos:0, PrivateGists:0, DiskUsage:0, Collaborators:0, TwoFactorAuthentication:false, Plan:github.Plan{}, URL:"", EventsURL:"", FollowingURL:"", FollowersURL:"", GistsURL:"", OrganizationsURL:"", ReceivedEventsURL:"", ReposURL:"", StarredURL:"", SubscriptionsURL:""}` + want := `github.User{Login:"", ID:0, NodeID:"", AvatarURL:"", HTMLURL:"", GravatarID:"", Name:"", Company:"", Blog:"", Location:"", Email:"", Hireable:false, Bio:"", PublicRepos:0, PublicGists:0, Followers:0, Following:0, CreatedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, UpdatedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, SuspendedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, Type:"", SiteAdmin:false, TotalPrivateRepos:0, OwnedPrivateRepos:0, PrivateGists:0, DiskUsage:0, Collaborators:0, TwoFactorAuthentication:false, Plan:github.Plan{}, LdapDn:"", URL:"", EventsURL:"", FollowingURL:"", FollowersURL:"", GistsURL:"", OrganizationsURL:"", ReceivedEventsURL:"", ReposURL:"", StarredURL:"", SubscriptionsURL:""}` if got := v.String(); got != want { t.Errorf("User.String = %v, want %v", got, want) } diff --git a/github/users.go b/github/users.go index 87cfa7f84b7..2592aea0f4f 100644 --- a/github/users.go +++ b/github/users.go @@ -47,6 +47,7 @@ type User struct { Collaborators *int `json:"collaborators,omitempty"` TwoFactorAuthentication *bool `json:"two_factor_authentication,omitempty"` Plan *Plan `json:"plan,omitempty"` + LdapDn *string `json:"ldap_dn,omitempty"` // API URLs URL *string `json:"url,omitempty"` From 0ffc27d42b7ad05ff6890030162d9a3d495224e8 Mon Sep 17 00:00:00 2001 From: Glenn Lewis <6598971+gmlewis@users.noreply.github.com> Date: Tue, 25 Jun 2019 15:32:54 -0400 Subject: [PATCH 0020/1468] Update AUTHORS with recent contributors --- AUTHORS | 2 ++ 1 file changed, 2 insertions(+) diff --git a/AUTHORS b/AUTHORS index afb59217078..b1faeb0f7f3 100644 --- a/AUTHORS +++ b/AUTHORS @@ -27,6 +27,7 @@ Andrew Ryabchun Andy Grunwald Andy Hume Andy Lindeman +anjanashenoy Anshuman Bhartiya Antoine Antoine Pelisse @@ -152,6 +153,7 @@ Luke Kysow Luke Roberts Luke Young Maksim Zhylinski +Mark Tareshawty Martin-Louis Bright Marwan Sulaiman Mat Geist From 7ce06781fd4e9d426dc100ce97783dbd434a9d41 Mon Sep 17 00:00:00 2001 From: Masayuki Izumi Date: Thu, 4 Jul 2019 22:04:04 +0900 Subject: [PATCH 0021/1468] Add Visibility to UserEmail (#1215) --- github/github-accessors.go | 8 ++++++++ github/users_emails.go | 7 ++++--- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/github/github-accessors.go b/github/github-accessors.go index b92e81fec29..9218107be67 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -12388,6 +12388,14 @@ func (u *UserEmail) GetVerified() bool { return *u.Verified } +// GetVisibility returns the Visibility field if it's non-nil, zero value otherwise. +func (u *UserEmail) GetVisibility() string { + if u == nil || u.Visibility == nil { + return "" + } + return *u.Visibility +} + // GetAvatarURL returns the AvatarURL field if it's non-nil, zero value otherwise. func (u *UserLDAPMapping) GetAvatarURL() string { if u == nil || u.AvatarURL == nil { diff --git a/github/users_emails.go b/github/users_emails.go index 0bbd4627e3b..78d21491191 100644 --- a/github/users_emails.go +++ b/github/users_emails.go @@ -9,9 +9,10 @@ import "context" // UserEmail represents user's email address type UserEmail struct { - Email *string `json:"email,omitempty"` - Primary *bool `json:"primary,omitempty"` - Verified *bool `json:"verified,omitempty"` + Email *string `json:"email,omitempty"` + Primary *bool `json:"primary,omitempty"` + Verified *bool `json:"verified,omitempty"` + Visibility *string `json:"visibility,omitempty"` } // ListEmails lists all email addresses for the authenticated user. From 035bec247b66da1f419269776ae7c1633799d145 Mon Sep 17 00:00:00 2001 From: William Cooke Date: Mon, 8 Jul 2019 23:02:04 +0100 Subject: [PATCH 0022/1468] Consistent errors for GetRef when a Ref doesn't exist (#1207) Fixes #1208. --- github/git_refs.go | 5 ++++- github/git_refs_test.go | 19 ++++++++++++++++++- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/github/git_refs.go b/github/git_refs.go index 3f381d5f2b6..fe16880e7b0 100644 --- a/github/git_refs.go +++ b/github/git_refs.go @@ -68,7 +68,10 @@ func (s *GitService) GetRef(ctx context.Context, owner string, repo string, ref resp, err := s.client.Do(ctx, req, r) if _, ok := err.(*json.UnmarshalTypeError); ok { // Multiple refs, means there wasn't an exact match. - return nil, resp, errors.New("no exact match found for this ref") + return nil, resp, errors.New("multiple matches found for this ref") + } else if resp.StatusCode == 404 { + // No ref, there was no match for the ref + return nil, resp, errors.New("no match found for this ref") } else if err != nil { return nil, resp, err } diff --git a/github/git_refs_test.go b/github/git_refs_test.go index 3cae3c085fd..6c8a1d87951 100644 --- a/github/git_refs_test.go +++ b/github/git_refs_test.go @@ -56,6 +56,23 @@ func TestGitService_GetRef_singleRef(t *testing.T) { } } +func TestGitService_GetRef_noRefs(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/repos/o/r/git/refs/heads/b", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + w.WriteHeader(http.StatusNotFound) + fmt.Fprint(w, "[]") + }) + + _, _, err := client.Git.GetRef(context.Background(), "o", "r", "refs/heads/b") + want := "no match found for this ref" + if err.Error() != want { + t.Errorf("Git.GetRef returned %+v, want %+v", err, want) + } +} + func TestGitService_GetRef_multipleRefs(t *testing.T) { client, mux, _, teardown := setup() defer teardown() @@ -87,7 +104,7 @@ func TestGitService_GetRef_multipleRefs(t *testing.T) { }) _, _, err := client.Git.GetRef(context.Background(), "o", "r", "refs/heads/b") - want := "no exact match found for this ref" + want := "multiple matches found for this ref" if err.Error() != want { t.Errorf("Git.GetRef returned %+v, want %+v", err, want) } From 60c47f346f58f34c2d24f22058b8b0ab21341fa6 Mon Sep 17 00:00:00 2001 From: Vaibhav Singh Date: Tue, 9 Jul 2019 03:36:19 +0530 Subject: [PATCH 0023/1468] Added Support preview Team Sync API for GitHub Enterprise Cloud users (#1212) Fixes #1200. --- github/github-accessors.go | 24 +++++++++ github/github.go | 3 ++ github/teams.go | 84 ++++++++++++++++++++++++++++++ github/teams_test.go | 101 +++++++++++++++++++++++++++++++++++++ 4 files changed, 212 insertions(+) diff --git a/github/github-accessors.go b/github/github-accessors.go index 9218107be67..0e37a9c29cb 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -3324,6 +3324,30 @@ func (h *HookStats) GetTotalHooks() int { return *h.TotalHooks } +// GetGroupDescription returns the GroupDescription field if it's non-nil, zero value otherwise. +func (i *IDPGroup) GetGroupDescription() string { + if i == nil || i.GroupDescription == nil { + return "" + } + return *i.GroupDescription +} + +// GetGroupID returns the GroupID field if it's non-nil, zero value otherwise. +func (i *IDPGroup) GetGroupID() string { + if i == nil || i.GroupID == nil { + return "" + } + return *i.GroupID +} + +// GetGroupName returns the GroupName field if it's non-nil, zero value otherwise. +func (i *IDPGroup) GetGroupName() string { + if i == nil || i.GroupName == nil { + return "" + } + return *i.GroupName +} + // GetAuthorsCount returns the AuthorsCount field if it's non-nil, zero value otherwise. func (i *Import) GetAuthorsCount() int { if i == nil || i.AuthorsCount == nil { diff --git a/github/github.go b/github/github.go index b1323f9e767..7857c024cf1 100644 --- a/github/github.go +++ b/github/github.go @@ -147,6 +147,9 @@ const ( // https://developer.github.com/changes/2019-04-11-pulls-branches-for-commit/ mediaTypeListPullsOrBranchesForCommitPreview = "application/vnd.github.groot-preview+json" + + // https://developer.github.com/changes/2019-06-12-team-sync/ + mediaTypeTeamSyncPreview = "application/vnd.github.team-sync-preview+json" ) // A Client manages communication with the GitHub API. diff --git a/github/teams.go b/github/teams.go index a8247a3b7cc..b4953e63871 100644 --- a/github/teams.go +++ b/github/teams.go @@ -476,3 +476,87 @@ func (s *TeamsService) RemoveTeamProject(ctx context.Context, teamID int64, proj return s.client.Do(ctx, req, nil) } + +// IDPGroupList represents a list of external identity provider (IDP) groups. +type IDPGroupList struct { + Groups []*IDPGroup `json:"groups,omitempty"` +} + +// IDPGroup represents an external identity provider (IDP) group. +type IDPGroup struct { + GroupID *string `json:"group_id,omitempty"` + GroupName *string `json:"group_name,omitempty"` + GroupDescription *string `json:"group_description,omitempty"` +} + +// ListIDPGroupsInOrganization lists IDP groups available in an organization. +// +// GitHub API docs: https://developer.github.com/v3/teams/team_sync/#list-idp-groups-in-an-organization +func (s *TeamsService) ListIDPGroupsInOrganization(ctx context.Context, org string, opt *ListOptions) (*IDPGroupList, *Response, error) { + u := fmt.Sprintf("orgs/%v/team-sync/groups", org) + 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. + req.Header.Set("Accept", mediaTypeTeamSyncPreview) + + groups := new(IDPGroupList) + resp, err := s.client.Do(ctx, req, groups) + if err != nil { + return nil, resp, err + } + return groups, resp, nil +} + +// ListIDPGroupsForTeam lists IDP groups connected to a team on GitHub. +// +// GitHub API docs: https://developer.github.com/v3/teams/team_sync/#list-idp-groups-for-a-team +func (s *TeamsService) ListIDPGroupsForTeam(ctx context.Context, teamID string) (*IDPGroupList, *Response, error) { + u := fmt.Sprintf("teams/%v/team-sync/group-mappings", teamID) + + 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", mediaTypeTeamSyncPreview) + + groups := new(IDPGroupList) + resp, err := s.client.Do(ctx, req, groups) + if err != nil { + return nil, resp, err + } + return groups, resp, err +} + +// CreateOrUpdateIDPGroupConnections creates, updates, or removes a connection between a team +// and an IDP group. +// +// GitHub API docs: https://developer.github.com/v3/teams/team_sync/#create-or-update-idp-group-connections +func (s *TeamsService) CreateOrUpdateIDPGroupConnections(ctx context.Context, teamID string, opt IDPGroupList) (*IDPGroupList, *Response, error) { + u := fmt.Sprintf("teams/%v/team-sync/group-mappings", teamID) + + req, err := s.client.NewRequest("PATCH", u, opt) + if err != nil { + return nil, nil, err + } + + // TODO: remove custom Accept header when this API fully launches. + req.Header.Set("Accept", mediaTypeTeamSyncPreview) + + groups := new(IDPGroupList) + resp, err := s.client.Do(ctx, req, groups) + if err != nil { + return nil, resp, err + } + + return groups, resp, nil +} diff --git a/github/teams_test.go b/github/teams_test.go index 84514ee932b..6210bb596ae 100644 --- a/github/teams_test.go +++ b/github/teams_test.go @@ -601,3 +601,104 @@ func TestTeamsService_RemoveTeamProject(t *testing.T) { t.Errorf("Teams.RemoveTeamProject returned error: %v", err) } } + +func TestTeamsService_ListIDPGroupsInOrganization(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/orgs/o/team-sync/groups", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + testHeader(t, r, "Accept", mediaTypeTeamSyncPreview) + testFormValues(t, r, values{ + "page": "2", + }) + fmt.Fprint(w, `{"groups": [{"group_id": "1", "group_name": "n", "group_description": "d"}]}`) + }) + + opt := &ListOptions{Page: 2} + groups, _, err := client.Teams.ListIDPGroupsInOrganization(context.Background(), "o", opt) + if err != nil { + t.Errorf("Teams.ListIDPGroupsInOrganization returned error: %v", err) + } + + want := &IDPGroupList{ + Groups: []*IDPGroup{ + { + GroupID: String("1"), + GroupName: String("n"), + GroupDescription: String("d"), + }, + }, + } + if !reflect.DeepEqual(groups, want) { + t.Errorf("Teams.ListIDPGroupsInOrganization returned %+v. want %+v", groups, want) + } +} + +func TestTeamsService_ListIDPGroupsForTeam(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/teams/1/team-sync/group-mappings", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + testHeader(t, r, "Accept", mediaTypeTeamSyncPreview) + fmt.Fprint(w, `{"groups": [{"group_id": "1", "group_name": "n", "group_description": "d"}]}`) + }) + + groups, _, err := client.Teams.ListIDPGroupsForTeam(context.Background(), "1") + if err != nil { + t.Errorf("Teams.ListIDPGroupsForTeam returned error: %v", err) + } + + want := &IDPGroupList{ + Groups: []*IDPGroup{ + { + GroupID: String("1"), + GroupName: String("n"), + GroupDescription: String("d"), + }, + }, + } + if !reflect.DeepEqual(groups, want) { + t.Errorf("Teams.ListIDPGroupsForTeam returned %+v. want %+v", groups, want) + } +} + +func TestTeamsService_CreateOrUpdateIDPGroupConnections(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/teams/1/team-sync/group-mappings", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "PATCH") + testHeader(t, r, "Accept", mediaTypeTeamSyncPreview) + fmt.Fprint(w, `{"groups": [{"group_id": "1", "group_name": "n", "group_description": "d"}]}`) + }) + + input := IDPGroupList{ + Groups: []*IDPGroup{ + { + GroupID: String("1"), + GroupName: String("n"), + GroupDescription: String("d"), + }, + }, + } + + groups, _, err := client.Teams.CreateOrUpdateIDPGroupConnections(context.Background(), "1", input) + if err != nil { + t.Errorf("Teams.CreateOrUpdateIDPGroupConnections returned error: %v", err) + } + + want := &IDPGroupList{ + Groups: []*IDPGroup{ + { + GroupID: String("1"), + GroupName: String("n"), + GroupDescription: String("d"), + }, + }, + } + if !reflect.DeepEqual(groups, want) { + t.Errorf("Teams.CreateOrUpdateIDPGroupConnections returned %+v. want %+v", groups, want) + } +} From 1bab17eebddef9e1de2372cd48785ef27f2ae424 Mon Sep 17 00:00:00 2001 From: David Date: Tue, 9 Jul 2019 07:27:19 +0900 Subject: [PATCH 0024/1468] Add repository creation permissions field (#1213) --- AUTHORS | 1 + github/github-accessors.go | 8 ++++ github/github-stringify_test.go | 73 +++++++++++++++++---------------- github/github.go | 3 ++ github/orgs.go | 7 ++++ github/orgs_test.go | 1 + 6 files changed, 57 insertions(+), 36 deletions(-) diff --git a/AUTHORS b/AUTHORS index b1faeb0f7f3..8a41ba02676 100644 --- a/AUTHORS +++ b/AUTHORS @@ -70,6 +70,7 @@ Dave Du Cros Dave Henderson David Deng David Jannotta +David Ji Davide Zipeto Dennis Webb Dhi Aurrahman diff --git a/github/github-accessors.go b/github/github-accessors.go index 0e37a9c29cb..b4ca033d300 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -6156,6 +6156,14 @@ func (o *Organization) GetLogin() string { return *o.Login } +// GetMembersAllowedRepositoryCreationType returns the MembersAllowedRepositoryCreationType field if it's non-nil, zero value otherwise. +func (o *Organization) GetMembersAllowedRepositoryCreationType() string { + if o == nil || o.MembersAllowedRepositoryCreationType == nil { + return "" + } + return *o.MembersAllowedRepositoryCreationType +} + // GetMembersCanCreateRepos returns the MembersCanCreateRepos field if it's non-nil, zero value otherwise. func (o *Organization) GetMembersCanCreateRepos() bool { if o == nil || o.MembersCanCreateRepos == nil { diff --git a/github/github-stringify_test.go b/github/github-stringify_test.go index 6934f237c1d..f424531e1f3 100644 --- a/github/github-stringify_test.go +++ b/github/github-stringify_test.go @@ -793,42 +793,43 @@ func TestOrgStats_String(t *testing.T) { func TestOrganization_String(t *testing.T) { v := Organization{ - Login: String(""), - ID: Int64(0), - NodeID: String(""), - AvatarURL: String(""), - HTMLURL: String(""), - Name: String(""), - Company: String(""), - Blog: String(""), - Location: String(""), - Email: String(""), - Description: String(""), - PublicRepos: Int(0), - PublicGists: Int(0), - Followers: Int(0), - Following: Int(0), - TotalPrivateRepos: Int(0), - OwnedPrivateRepos: Int(0), - PrivateGists: Int(0), - DiskUsage: Int(0), - Collaborators: Int(0), - BillingEmail: String(""), - Type: String(""), - Plan: &Plan{}, - TwoFactorRequirementEnabled: Bool(false), - DefaultRepoPermission: String(""), - DefaultRepoSettings: String(""), - MembersCanCreateRepos: Bool(false), - URL: String(""), - EventsURL: String(""), - HooksURL: String(""), - IssuesURL: String(""), - MembersURL: String(""), - PublicMembersURL: String(""), - ReposURL: String(""), - } - want := `github.Organization{Login:"", ID:0, NodeID:"", AvatarURL:"", HTMLURL:"", Name:"", Company:"", Blog:"", Location:"", Email:"", Description:"", PublicRepos:0, PublicGists:0, Followers:0, Following:0, TotalPrivateRepos:0, OwnedPrivateRepos:0, PrivateGists:0, DiskUsage:0, Collaborators:0, BillingEmail:"", Type:"", Plan:github.Plan{}, TwoFactorRequirementEnabled:false, DefaultRepoPermission:"", DefaultRepoSettings:"", MembersCanCreateRepos:false, URL:"", EventsURL:"", HooksURL:"", IssuesURL:"", MembersURL:"", PublicMembersURL:"", ReposURL:""}` + Login: String(""), + ID: Int64(0), + NodeID: String(""), + AvatarURL: String(""), + HTMLURL: String(""), + Name: String(""), + Company: String(""), + Blog: String(""), + Location: String(""), + Email: String(""), + Description: String(""), + PublicRepos: Int(0), + PublicGists: Int(0), + Followers: Int(0), + Following: Int(0), + TotalPrivateRepos: Int(0), + OwnedPrivateRepos: Int(0), + PrivateGists: Int(0), + DiskUsage: Int(0), + Collaborators: Int(0), + BillingEmail: String(""), + Type: String(""), + Plan: &Plan{}, + TwoFactorRequirementEnabled: Bool(false), + DefaultRepoPermission: String(""), + DefaultRepoSettings: String(""), + MembersCanCreateRepos: Bool(false), + MembersAllowedRepositoryCreationType: String(""), + URL: String(""), + EventsURL: String(""), + HooksURL: String(""), + IssuesURL: String(""), + MembersURL: String(""), + PublicMembersURL: String(""), + ReposURL: String(""), + } + want := `github.Organization{Login:"", ID:0, NodeID:"", AvatarURL:"", HTMLURL:"", Name:"", Company:"", Blog:"", Location:"", Email:"", Description:"", PublicRepos:0, PublicGists:0, Followers:0, Following:0, TotalPrivateRepos:0, OwnedPrivateRepos:0, PrivateGists:0, DiskUsage:0, Collaborators:0, BillingEmail:"", Type:"", Plan:github.Plan{}, TwoFactorRequirementEnabled:false, DefaultRepoPermission:"", DefaultRepoSettings:"", MembersCanCreateRepos:false, MembersAllowedRepositoryCreationType:"", URL:"", EventsURL:"", HooksURL:"", IssuesURL:"", MembersURL:"", PublicMembersURL:"", ReposURL:""}` if got := v.String(); got != want { t.Errorf("Organization.String = %v, want %v", got, want) } diff --git a/github/github.go b/github/github.go index 7857c024cf1..7a82677c415 100644 --- a/github/github.go +++ b/github/github.go @@ -150,6 +150,9 @@ const ( // https://developer.github.com/changes/2019-06-12-team-sync/ mediaTypeTeamSyncPreview = "application/vnd.github.team-sync-preview+json" + + // https://developer.github.com/v3/previews/#repository-creation-permissions + mediaTypeMemberAllowedRepoCreationTypePreview = "application/vnd.github.surtur-preview+json" ) // A Client manages communication with the GitHub API. diff --git a/github/orgs.go b/github/orgs.go index c70039ba080..e1aa20db0b1 100644 --- a/github/orgs.go +++ b/github/orgs.go @@ -56,6 +56,10 @@ type Organization struct { // MembersCanCreateRepos default value is true and is only used in Organizations.Edit. MembersCanCreateRepos *bool `json:"members_can_create_repositories,omitempty"` + // MembersAllowedRepositoryCreationType denotes if organization members can create repositories + // and the type of repositories they can create. Possible values are: "all", "private", or "none". + MembersAllowedRepositoryCreationType *string `json:"members_allowed_repository_creation_type,omitempty"` + // API URLs URL *string `json:"url,omitempty"` EventsURL *string `json:"events_url,omitempty"` @@ -160,6 +164,9 @@ func (s *OrganizationsService) Get(ctx context.Context, org string) (*Organizati return nil, nil, err } + // TODO: remove custom Accept header when this API fully launches. + req.Header.Set("Accept", mediaTypeMemberAllowedRepoCreationTypePreview) + organization := new(Organization) resp, err := s.client.Do(ctx, req, organization) if err != nil { diff --git a/github/orgs_test.go b/github/orgs_test.go index 9fe484dbb1e..3b938fc993b 100644 --- a/github/orgs_test.go +++ b/github/orgs_test.go @@ -93,6 +93,7 @@ func TestOrganizationsService_Get(t *testing.T) { mux.HandleFunc("/orgs/o", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") + testHeader(t, r, "Accept", mediaTypeMemberAllowedRepoCreationTypePreview) fmt.Fprint(w, `{"id":1, "login":"l", "url":"u", "avatar_url": "a", "location":"l"}`) }) From cad32f26bbd0216620995d028657c304c95a5eab Mon Sep 17 00:00:00 2001 From: Quentin Leffray Date: Tue, 9 Jul 2019 00:29:48 +0200 Subject: [PATCH 0025/1468] Add methods for GitHub Enterprise endpoints (#1214) --- github/admin_orgs.go | 43 +++++++++++++++++++++++++++ github/admin_orgs_test.go | 47 +++++++++++++++++++++++++++++ github/admin_stats.go | 4 +-- github/admin_users.go | 61 ++++++++++++++++++++++++++++++++++++++ github/admin_users_test.go | 57 +++++++++++++++++++++++++++++++++++ 5 files changed, 210 insertions(+), 2 deletions(-) create mode 100644 github/admin_orgs.go create mode 100644 github/admin_orgs_test.go create mode 100644 github/admin_users.go create mode 100644 github/admin_users_test.go diff --git a/github/admin_orgs.go b/github/admin_orgs.go new file mode 100644 index 00000000000..f063831085b --- /dev/null +++ b/github/admin_orgs.go @@ -0,0 +1,43 @@ +// Copyright 2019 The go-github AUTHORS. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package github + +import "context" + +// createOrgRequest is a subset of Organization and is used internally +// by CreateOrg to pass only the known fields for the endpoint. +type createOrgRequest struct { + Login *string `json:"login,omitempty"` + Admin *string `json:"admin,omitempty"` +} + +// CreateOrg creates a new organization in GitHub Enterprise. +// +// Note that only a subset of the org fields are used and org must +// not be nil. +// +// GitHub Enterprise API docs: https://developer.github.com/enterprise/v3/enterprise-admin/orgs/#create-an-organization +func (s *AdminService) CreateOrg(ctx context.Context, org *Organization, admin string) (*Organization, *Response, error) { + u := "admin/organizations" + + orgReq := &createOrgRequest{ + Login: org.Login, + Admin: &admin, + } + + req, err := s.client.NewRequest("POST", u, orgReq) + if err != nil { + return nil, nil, err + } + + o := new(Organization) + resp, err := s.client.Do(ctx, req, o) + if err != nil { + return nil, resp, err + } + + return o, resp, nil +} diff --git a/github/admin_orgs_test.go b/github/admin_orgs_test.go new file mode 100644 index 00000000000..6966a179c05 --- /dev/null +++ b/github/admin_orgs_test.go @@ -0,0 +1,47 @@ +// Copyright 2019 The go-github AUTHORS. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package github + +import ( + "context" + "encoding/json" + "fmt" + "net/http" + "reflect" + "testing" +) + +func TestAdminOrgs_Create(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + input := &Organization{ + Login: String("github"), + } + + mux.HandleFunc("/admin/organizations", func(w http.ResponseWriter, r *http.Request) { + v := new(createOrgRequest) + json.NewDecoder(r.Body).Decode(v) + + testMethod(t, r, "POST") + want := &createOrgRequest{Login: String("github"), Admin: String("ghAdmin")} + if !reflect.DeepEqual(v, want) { + t.Errorf("Request body = %+v, want %+v", v, want) + } + + fmt.Fprint(w, `{"login":"github","id":1}`) + }) + + org, _, err := client.Admin.CreateOrg(context.Background(), input, "ghAdmin") + if err != nil { + t.Errorf("Admin.CreateOrg returned error: %v", err) + } + + want := &Organization{ID: Int64(1), Login: String("github")} + if !reflect.DeepEqual(org, want) { + t.Errorf("Admin.CreateOrg returned %+v, want %+v", org, want) + } +} diff --git a/github/admin_stats.go b/github/admin_stats.go index b5645f8c176..dabefde3e7b 100644 --- a/github/admin_stats.go +++ b/github/admin_stats.go @@ -10,7 +10,7 @@ import ( "fmt" ) -// AdminStats represents a variety of stats of a Github Enterprise +// AdminStats represents a variety of stats of a GitHub Enterprise // installation. type AdminStats struct { Issues *IssueStats `json:"issues,omitempty"` @@ -147,7 +147,7 @@ func (s RepoStats) String() string { return Stringify(s) } -// GetAdminStats returns a variety of metrics about a Github Enterprise +// GetAdminStats returns a variety of metrics about a GitHub Enterprise // installation. // // Please note that this is only available to site administrators, diff --git a/github/admin_users.go b/github/admin_users.go new file mode 100644 index 00000000000..ea7a47d31ce --- /dev/null +++ b/github/admin_users.go @@ -0,0 +1,61 @@ +// Copyright 2019 The go-github AUTHORS. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package github + +import ( + "context" +) + +// createUserRequest is a subset of User and is used internally +// by CreateUser to pass only the known fields for the endpoint. +type createUserRequest struct { + Login *string `json:"login,omitempty"` + Email *string `json:"email,omitempty"` +} + +// CreateUser creates a new user in GitHub Enterprise. +// +// GitHub Enterprise API docs: https://developer.github.com/enterprise/v3/enterprise-admin/users/#create-a-new-user +func (s *AdminService) CreateUser(ctx context.Context, login, email string) (*User, *Response, error) { + u := "admin/users" + + userReq := &createUserRequest{ + Login: &login, + Email: &email, + } + + req, err := s.client.NewRequest("POST", u, userReq) + if err != nil { + return nil, nil, err + } + + var user User + resp, err := s.client.Do(ctx, req, &user) + if err != nil { + return nil, resp, err + } + + return &user, resp, nil +} + +// DeleteUser deletes a user in GitHub Enterprise. +// +// GitHub Enterprise API docs: https://developer.github.com/enterprise/v3/enterprise-admin/users/#delete-a-user +func (s *AdminService) DeleteUser(ctx context.Context, username string) (*Response, error) { + u := "admin/users/" + username + + req, err := s.client.NewRequest("DELETE", u, nil) + if err != nil { + return nil, err + } + + resp, err := s.client.Do(ctx, req, nil) + if err != nil { + return resp, err + } + + return resp, nil +} diff --git a/github/admin_users_test.go b/github/admin_users_test.go new file mode 100644 index 00000000000..ad5379e2f2b --- /dev/null +++ b/github/admin_users_test.go @@ -0,0 +1,57 @@ +// Copyright 2019 The go-github AUTHORS. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package github + +import ( + "context" + "encoding/json" + "fmt" + "net/http" + "reflect" + "testing" +) + +func TestAdminUsers_Create(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/admin/users", func(w http.ResponseWriter, r *http.Request) { + v := new(createUserRequest) + json.NewDecoder(r.Body).Decode(v) + + testMethod(t, r, "POST") + want := &createUserRequest{Login: String("github"), Email: String("email@domain.com")} + if !reflect.DeepEqual(v, want) { + t.Errorf("Request body = %+v, want %+v", v, want) + } + + fmt.Fprint(w, `{"login":"github","id":1}`) + }) + + org, _, err := client.Admin.CreateUser(context.Background(), "github", "email@domain.com") + if err != nil { + t.Errorf("Admin.CreateUser returned error: %v", err) + } + + want := &User{ID: Int64(1), Login: String("github")} + if !reflect.DeepEqual(org, want) { + t.Errorf("Admin.CreateUser returned %+v, want %+v", org, want) + } +} + +func TestAdminUsers_Delete(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/admin/users/github", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "DELETE") + }) + + _, err := client.Admin.DeleteUser(context.Background(), "github") + if err != nil { + t.Errorf("Admin.DeleteUser returned error: %v", err) + } +} From fddcd1329128828b72531536cc753d859043e872 Mon Sep 17 00:00:00 2001 From: SriVignessh Pss Date: Mon, 15 Jul 2019 17:25:23 -0700 Subject: [PATCH 0026/1468] Add options to list gist forks endpoint (#1229) --- github/gists.go | 7 ++++- github/gists_test.go | 65 ++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 66 insertions(+), 6 deletions(-) diff --git a/github/gists.go b/github/gists.go index 15e0bc2cd9d..36d9361967c 100644 --- a/github/gists.go +++ b/github/gists.go @@ -341,8 +341,13 @@ func (s *GistsService) Fork(ctx context.Context, id string) (*Gist, *Response, e // ListForks lists forks of a gist. // // GitHub API docs: https://developer.github.com/v3/gists/#list-gist-forks -func (s *GistsService) ListForks(ctx context.Context, id string) ([]*GistFork, *Response, error) { +func (s *GistsService) ListForks(ctx context.Context, id string, opt *ListOptions) ([]*GistFork, *Response, error) { u := fmt.Sprintf("gists/%v/forks", id) + 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 diff --git a/github/gists_test.go b/github/gists_test.go index 2d79b8c5e8b..d24e0e40b83 100644 --- a/github/gists_test.go +++ b/github/gists_test.go @@ -568,6 +568,14 @@ func TestGistsService_ListCommits_withOptions(t *testing.T) { } } +func TestGistsService_ListCommits_invalidID(t *testing.T) { + client, _, _, teardown := setup() + defer teardown() + + _, _, err := client.Gists.ListCommits(context.Background(), "%", nil) + testURLParseError(t, err) +} + func TestGistsService_Delete(t *testing.T) { client, mux, _, teardown := setup() defer teardown() @@ -717,7 +725,7 @@ func TestGistsService_ListForks(t *testing.T) { `) }) - gistForks, _, err := client.Gists.ListForks(context.Background(), "1") + gistForks, _, err := client.Gists.ListForks(context.Background(), "1", nil) if err != nil { t.Errorf("Gists.ListForks returned error: %v", err) } @@ -732,12 +740,59 @@ func TestGistsService_ListForks(t *testing.T) { if !reflect.DeepEqual(gistForks, want) { t.Errorf("Gists.ListForks returned %+v, want %+v", gistForks, want) } + } -func TestGistsService_Fork_invalidID(t *testing.T) { - client, _, _, teardown := setup() +func TestGistsService_ListForks_withOptions(t *testing.T) { + client, mux, _, teardown := setup() defer teardown() - _, _, err := client.Gists.Fork(context.Background(), "%") - testURLParseError(t, err) + mux.HandleFunc("/gists/1/forks", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + testFormValues(t, r, values{ + "page": "2", + }) + fmt.Fprint(w, `[]`) + }) + + gistForks, _, err := client.Gists.ListForks(context.Background(), "1", &ListOptions{Page: 2}) + if err != nil { + t.Errorf("Gists.ListForks returned error: %v", err) + } + + want := []*GistFork{} + if !reflect.DeepEqual(gistForks, want) { + t.Errorf("Gists.ListForks returned %+v, want %+v", gistForks, want) + } + + // Test addOptions failure + _, _, err = client.Gists.ListForks(context.Background(), "%", &ListOptions{}) + if err == nil { + t.Error("Gists.ListForks returned err = nil") + } + + // Test client.NewRequest failure + got, resp, err := client.Gists.ListForks(context.Background(), "%", nil) + if got != nil { + t.Errorf("Gists.ListForks = %#v, want nil", got) + } + if resp != nil { + t.Errorf("Gists.ListForks resp = %#v, want nil", resp) + } + if err == nil { + t.Error("Gists.ListForks err = nil, want error") + } + + // Test client.Do failure + client.rateLimits[0].Reset.Time = time.Now().Add(10 * time.Minute) + got, resp, err = client.Gists.ListForks(context.Background(), "1", &ListOptions{Page: 2}) + if got != nil { + t.Errorf("Gists.ListForks returned = %#v, want nil", got) + } + if want := http.StatusForbidden; resp == nil || resp.Response.StatusCode != want { + t.Errorf("Gists.ListForks returned resp = %#v, want StatusCode=%v", resp.Response, want) + } + if err == nil { + t.Error("rGists.ListForks returned err = nil, want error") + } } From 955a14c8ede799deb6529c0dc9b5b0b27d19a8bd Mon Sep 17 00:00:00 2001 From: Glenn Lewis <6598971+gmlewis@users.noreply.github.com> Date: Mon, 15 Jul 2019 20:27:12 -0400 Subject: [PATCH 0027/1468] Bump version to v27 --- README.md | 2 +- example/appengine/app.go | 2 +- example/basicauth/main.go | 2 +- example/commitpr/main.go | 2 +- example/migrations/main.go | 2 +- example/newrepo/main.go | 2 +- example/simple/main.go | 2 +- github/doc.go | 2 +- github/examples_test.go | 2 +- go.mod | 2 +- test/fields/fields.go | 2 +- test/integration/activity_test.go | 2 +- test/integration/authorizations_test.go | 2 +- test/integration/github_test.go | 2 +- test/integration/repos_test.go | 2 +- test/integration/users_test.go | 2 +- 16 files changed, 16 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 2f2e89ab1fe..eb26b6f914a 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ If you're interested in using the [GraphQL API v4][], the recommended library is ## Usage ## ```go -import "github.com/google/go-github/v26/github" // with go modules enabled (GO111MODULE=on or outside GOPATH) +import "github.com/google/go-github/v27/github" // with go modules enabled (GO111MODULE=on or outside GOPATH) import "github.com/google/go-github/github" // with go modules disabled ``` diff --git a/example/appengine/app.go b/example/appengine/app.go index 5ed7573a3d1..2f716c6c2c4 100644 --- a/example/appengine/app.go +++ b/example/appengine/app.go @@ -12,7 +12,7 @@ import ( "net/http" "os" - "github.com/google/go-github/v26/github" + "github.com/google/go-github/v27/github" "golang.org/x/oauth2" "google.golang.org/appengine" "google.golang.org/appengine/log" diff --git a/example/basicauth/main.go b/example/basicauth/main.go index cc3b0ccc9ae..d87866fb8c0 100644 --- a/example/basicauth/main.go +++ b/example/basicauth/main.go @@ -16,7 +16,7 @@ import ( "strings" "syscall" - "github.com/google/go-github/v26/github" + "github.com/google/go-github/v27/github" "golang.org/x/crypto/ssh/terminal" ) diff --git a/example/commitpr/main.go b/example/commitpr/main.go index 33324ce1ff0..e0c60355e28 100644 --- a/example/commitpr/main.go +++ b/example/commitpr/main.go @@ -31,7 +31,7 @@ import ( "strings" "time" - "github.com/google/go-github/v26/github" + "github.com/google/go-github/v27/github" "golang.org/x/oauth2" ) diff --git a/example/migrations/main.go b/example/migrations/main.go index 9c6ae4d98c7..c36ddd76afc 100644 --- a/example/migrations/main.go +++ b/example/migrations/main.go @@ -12,7 +12,7 @@ import ( "context" "fmt" - "github.com/google/go-github/v26/github" + "github.com/google/go-github/v27/github" "golang.org/x/oauth2" ) diff --git a/example/newrepo/main.go b/example/newrepo/main.go index 65736d7afbf..f91c5c56b40 100644 --- a/example/newrepo/main.go +++ b/example/newrepo/main.go @@ -16,7 +16,7 @@ import ( "log" "os" - "github.com/google/go-github/v26/github" + "github.com/google/go-github/v27/github" "golang.org/x/oauth2" ) diff --git a/example/simple/main.go b/example/simple/main.go index 8c291b76d39..8b790f46a7f 100644 --- a/example/simple/main.go +++ b/example/simple/main.go @@ -12,7 +12,7 @@ import ( "context" "fmt" - "github.com/google/go-github/v26/github" + "github.com/google/go-github/v27/github" ) // Fetch all the public organizations' membership of a user. diff --git a/github/doc.go b/github/doc.go index 1d3151edbaf..1fc5634d6f2 100644 --- a/github/doc.go +++ b/github/doc.go @@ -8,7 +8,7 @@ Package github provides a client for using the GitHub API. Usage: - import "github.com/google/go-github/v26/github" // with go modules enabled (GO111MODULE=on or outside GOPATH) + import "github.com/google/go-github/v27/github" // with go modules enabled (GO111MODULE=on or outside GOPATH) import "github.com/google/go-github/github" // with go modules disabled Construct a new GitHub client, then use the various services on the client to diff --git a/github/examples_test.go b/github/examples_test.go index 3d385edb915..e44df67efb7 100644 --- a/github/examples_test.go +++ b/github/examples_test.go @@ -12,7 +12,7 @@ import ( "fmt" "log" - "github.com/google/go-github/v26/github" + "github.com/google/go-github/v27/github" ) func ExampleClient_Markdown() { diff --git a/go.mod b/go.mod index ac4c2dab09c..14b5af851f6 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module github.com/google/go-github/v26 +module github.com/google/go-github/v27 require ( github.com/golang/protobuf v1.2.0 // indirect diff --git a/test/fields/fields.go b/test/fields/fields.go index a858fdcf92e..ef0dc2a1b11 100644 --- a/test/fields/fields.go +++ b/test/fields/fields.go @@ -25,7 +25,7 @@ import ( "reflect" "strings" - "github.com/google/go-github/v26/github" + "github.com/google/go-github/v27/github" "golang.org/x/oauth2" ) diff --git a/test/integration/activity_test.go b/test/integration/activity_test.go index 082380074e5..a8d508a808a 100644 --- a/test/integration/activity_test.go +++ b/test/integration/activity_test.go @@ -11,7 +11,7 @@ import ( "context" "testing" - "github.com/google/go-github/v26/github" + "github.com/google/go-github/v27/github" ) const ( diff --git a/test/integration/authorizations_test.go b/test/integration/authorizations_test.go index b87ec240854..ed6e39df829 100644 --- a/test/integration/authorizations_test.go +++ b/test/integration/authorizations_test.go @@ -16,7 +16,7 @@ import ( "testing" "time" - "github.com/google/go-github/v26/github" + "github.com/google/go-github/v27/github" ) const msgEnvMissing = "Skipping test because the required environment variable (%v) is not present." diff --git a/test/integration/github_test.go b/test/integration/github_test.go index d1449b30ab1..d4f66c2e2c3 100644 --- a/test/integration/github_test.go +++ b/test/integration/github_test.go @@ -14,7 +14,7 @@ import ( "net/http" "os" - "github.com/google/go-github/v26/github" + "github.com/google/go-github/v27/github" "golang.org/x/oauth2" ) diff --git a/test/integration/repos_test.go b/test/integration/repos_test.go index fb938020b6b..d98c62f8f40 100644 --- a/test/integration/repos_test.go +++ b/test/integration/repos_test.go @@ -13,7 +13,7 @@ import ( "reflect" "testing" - "github.com/google/go-github/v26/github" + "github.com/google/go-github/v27/github" ) func TestRepositories_CRUD(t *testing.T) { diff --git a/test/integration/users_test.go b/test/integration/users_test.go index b1bfaf64933..e30b84c6e3d 100644 --- a/test/integration/users_test.go +++ b/test/integration/users_test.go @@ -13,7 +13,7 @@ import ( "math/rand" "testing" - "github.com/google/go-github/v26/github" + "github.com/google/go-github/v27/github" ) func TestUsers_Get(t *testing.T) { From c756c329c19dbbadba0675b42af693093c3f2c45 Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Sat, 20 Jul 2019 03:58:03 +0200 Subject: [PATCH 0028/1468] Fix ineffectual assignments and error handling in tests (#1234) --- github/activity_test.go | 4 ++-- github/git_commits_test.go | 3 +++ github/pulls_reviewers_test.go | 8 +++---- github/repos_test.go | 40 +++++++++++++++++----------------- github/repos_traffic_test.go | 20 ++++++++--------- 5 files changed, 39 insertions(+), 36 deletions(-) diff --git a/github/activity_test.go b/github/activity_test.go index 9c4e566fb7d..b577118aad3 100644 --- a/github/activity_test.go +++ b/github/activity_test.go @@ -25,7 +25,7 @@ func TestActivityService_List(t *testing.T) { }) ctx := context.Background() - got, resp, err := client.Activity.ListFeeds(ctx) + got, _, err := client.Activity.ListFeeds(ctx) if err != nil { t.Errorf("Activity.ListFeeds returned error: %v", err) } @@ -35,7 +35,7 @@ func TestActivityService_List(t *testing.T) { // Test s.client.NewRequest failure client.BaseURL.Path = "" - got, resp, err = client.Activity.ListFeeds(ctx) + got, resp, err := client.Activity.ListFeeds(ctx) if got != nil { t.Errorf("client.BaseURL.Path='' ListFeeds = %#v, want nil", got) } diff --git a/github/git_commits_test.go b/github/git_commits_test.go index 580e6b05515..f316f01e0fd 100644 --- a/github/git_commits_test.go +++ b/github/git_commits_test.go @@ -146,6 +146,9 @@ func TestGitService_CreateSignedCommitWithKey(t *testing.T) { defer teardown() s := strings.NewReader(testGPGKey) keyring, err := openpgp.ReadArmoredKeyRing(s) + if err != nil { + t.Errorf("Error reading keyring: %+v", err) + } date, _ := time.Parse("Mon Jan 02 15:04:05 2006 -0700", "Thu May 04 00:03:43 2017 +0200") author := CommitAuthor{ diff --git a/github/pulls_reviewers_test.go b/github/pulls_reviewers_test.go index 8599bd777e7..98d6e656f49 100644 --- a/github/pulls_reviewers_test.go +++ b/github/pulls_reviewers_test.go @@ -26,7 +26,7 @@ func TestRequestReviewers(t *testing.T) { // This returns a PR, unmarshalling of which is tested elsewhere ctx := context.Background() - got, resp, err := client.PullRequests.RequestReviewers(ctx, "o", "r", 1, ReviewersRequest{Reviewers: []string{"octocat", "googlebot"}, TeamReviewers: []string{"justice-league", "injustice-league"}}) + got, _, err := client.PullRequests.RequestReviewers(ctx, "o", "r", 1, ReviewersRequest{Reviewers: []string{"octocat", "googlebot"}, TeamReviewers: []string{"justice-league", "injustice-league"}}) if err != nil { t.Errorf("PullRequests.RequestReviewers returned error: %v", err) } @@ -37,7 +37,7 @@ func TestRequestReviewers(t *testing.T) { // Test s.client.NewRequest failure client.BaseURL.Path = "" - got, resp, err = client.PullRequests.RequestReviewers(ctx, "o", "r", 1, ReviewersRequest{Reviewers: []string{"octocat", "googlebot"}, TeamReviewers: []string{"justice-league", "injustice-league"}}) + got, resp, err := client.PullRequests.RequestReviewers(ctx, "o", "r", 1, ReviewersRequest{Reviewers: []string{"octocat", "googlebot"}, TeamReviewers: []string{"justice-league", "injustice-league"}}) if got != nil { t.Errorf("client.BaseURL.Path='' RequestReviewers = %#v, want nil", got) } @@ -99,7 +99,7 @@ func TestListReviewers(t *testing.T) { }) ctx := context.Background() - got, resp, err := client.PullRequests.ListReviewers(ctx, "o", "r", 1, nil) + got, _, err := client.PullRequests.ListReviewers(ctx, "o", "r", 1, nil) if err != nil { t.Errorf("PullRequests.ListReviewers returned error: %v", err) } @@ -124,7 +124,7 @@ func TestListReviewers(t *testing.T) { // Test s.client.NewRequest failure client.BaseURL.Path = "" - got, resp, err = client.PullRequests.ListReviewers(ctx, "o", "r", 1, nil) + got, resp, err := client.PullRequests.ListReviewers(ctx, "o", "r", 1, nil) if got != nil { t.Errorf("client.BaseURL.Path='' ListReviewers = %#v, want nil", got) } diff --git a/github/repos_test.go b/github/repos_test.go index ebc1d8a782c..75e09a83e4b 100644 --- a/github/repos_test.go +++ b/github/repos_test.go @@ -28,7 +28,7 @@ func TestRepositoriesService_List_authenticatedUser(t *testing.T) { }) ctx := context.Background() - got, resp, err := client.Repositories.List(ctx, "", nil) + got, _, err := client.Repositories.List(ctx, "", nil) if err != nil { t.Errorf("Repositories.List returned error: %v", err) } @@ -39,7 +39,7 @@ func TestRepositoriesService_List_authenticatedUser(t *testing.T) { } // Test addOptions failure - got, resp, err = client.Repositories.List(ctx, "\n", &RepositoryListOptions{}) + _, _, err = client.Repositories.List(ctx, "\n", &RepositoryListOptions{}) if err == nil { t.Error("bad options List err = nil, want error") } @@ -47,7 +47,7 @@ func TestRepositoriesService_List_authenticatedUser(t *testing.T) { // Test s.client.Do failure client.BaseURL.Path = "/api-v3/" client.rateLimits[0].Reset.Time = time.Now().Add(10 * time.Minute) - got, resp, err = client.Repositories.List(ctx, "", nil) + got, resp, err := client.Repositories.List(ctx, "", nil) if got != nil { t.Errorf("rate.Reset.Time > now List = %#v, want nil", got) } @@ -148,7 +148,7 @@ func TestRepositoriesService_ListByOrg(t *testing.T) { ctx := context.Background() opt := &RepositoryListByOrgOptions{"forks", ListOptions{Page: 2}} - got, resp, err := client.Repositories.ListByOrg(ctx, "o", opt) + got, _, err := client.Repositories.ListByOrg(ctx, "o", opt) if err != nil { t.Errorf("Repositories.ListByOrg returned error: %v", err) } @@ -159,7 +159,7 @@ func TestRepositoriesService_ListByOrg(t *testing.T) { } // Test addOptions failure - got, resp, err = client.Repositories.ListByOrg(ctx, "\n", opt) + _, _, err = client.Repositories.ListByOrg(ctx, "\n", opt) if err == nil { t.Error("bad options ListByOrg err = nil, want error") } @@ -167,7 +167,7 @@ func TestRepositoriesService_ListByOrg(t *testing.T) { // Test s.client.Do failure client.BaseURL.Path = "/api-v3/" client.rateLimits[0].Reset.Time = time.Now().Add(10 * time.Minute) - got, resp, err = client.Repositories.ListByOrg(ctx, "o", opt) + got, resp, err := client.Repositories.ListByOrg(ctx, "o", opt) if got != nil { t.Errorf("rate.Reset.Time > now ListByOrg = %#v, want nil", got) } @@ -201,7 +201,7 @@ func TestRepositoriesService_ListAll(t *testing.T) { ctx := context.Background() opt := &RepositoryListAllOptions{1} - got, resp, err := client.Repositories.ListAll(ctx, opt) + got, _, err := client.Repositories.ListAll(ctx, opt) if err != nil { t.Errorf("Repositories.ListAll returned error: %v", err) } @@ -213,7 +213,7 @@ func TestRepositoriesService_ListAll(t *testing.T) { // Test s.client.NewRequest failure client.BaseURL.Path = "" - got, resp, err = client.Repositories.ListAll(ctx, &RepositoryListAllOptions{1}) + got, resp, err := client.Repositories.ListAll(ctx, &RepositoryListAllOptions{1}) if got != nil { t.Errorf("client.BaseURL.Path='' ListAll = %#v, want nil", got) } @@ -262,7 +262,7 @@ func TestRepositoriesService_Create_user(t *testing.T) { }) ctx := context.Background() - got, resp, err := client.Repositories.Create(ctx, "", input) + got, _, err := client.Repositories.Create(ctx, "", input) if err != nil { t.Errorf("Repositories.Create returned error: %v", err) } @@ -274,7 +274,7 @@ func TestRepositoriesService_Create_user(t *testing.T) { // Test s.client.NewRequest failure client.BaseURL.Path = "" - got, resp, err = client.Repositories.Create(ctx, "", input) + got, resp, err := client.Repositories.Create(ctx, "", input) if got != nil { t.Errorf("client.BaseURL.Path='' Create = %#v, want nil", got) } @@ -345,7 +345,7 @@ func TestRepositoriesService_Get(t *testing.T) { }) ctx := context.Background() - got, resp, err := client.Repositories.Get(ctx, "o", "r") + got, _, err := client.Repositories.Get(ctx, "o", "r") if err != nil { t.Errorf("Repositories.Get returned error: %v", err) } @@ -358,7 +358,7 @@ func TestRepositoriesService_Get(t *testing.T) { // Test s.client.Do failure client.BaseURL.Path = "/api-v3/" client.rateLimits[0].Reset.Time = time.Now().Add(10 * time.Minute) - got, resp, err = client.Repositories.Get(ctx, "o", "r") + got, resp, err := client.Repositories.Get(ctx, "o", "r") if got != nil { t.Errorf("rate.Reset.Time > now Get = %#v, want nil", got) } @@ -386,7 +386,7 @@ func TestRepositoriesService_GetCodeOfConduct(t *testing.T) { }) ctx := context.Background() - got, resp, err := client.Repositories.GetCodeOfConduct(ctx, "o", "r") + got, _, err := client.Repositories.GetCodeOfConduct(ctx, "o", "r") if err != nil { t.Errorf("Repositories.GetCodeOfConduct returned error: %v", err) } @@ -404,7 +404,7 @@ func TestRepositoriesService_GetCodeOfConduct(t *testing.T) { // Test s.client.NewRequest failure client.BaseURL.Path = "" - got, resp, err = client.Repositories.GetCodeOfConduct(ctx, "o", "r") + got, resp, err := client.Repositories.GetCodeOfConduct(ctx, "o", "r") if got != nil { t.Errorf("client.BaseURL.Path='' GetCodeOfConduct = %#v, want nil", got) } @@ -440,7 +440,7 @@ func TestRepositoriesService_GetByID(t *testing.T) { }) ctx := context.Background() - got, resp, err := client.Repositories.GetByID(ctx, 1) + got, _, err := client.Repositories.GetByID(ctx, 1) if err != nil { t.Fatalf("Repositories.GetByID returned error: %v", err) } @@ -452,7 +452,7 @@ func TestRepositoriesService_GetByID(t *testing.T) { // Test s.client.NewRequest failure client.BaseURL.Path = "" - got, resp, err = client.Repositories.GetByID(ctx, 1) + got, resp, err := client.Repositories.GetByID(ctx, 1) if got != nil { t.Errorf("client.BaseURL.Path='' GetByID = %#v, want nil", got) } @@ -497,7 +497,7 @@ func TestRepositoriesService_Edit(t *testing.T) { }) ctx := context.Background() - got, resp, err := client.Repositories.Edit(ctx, "o", "r", input) + got, _, err := client.Repositories.Edit(ctx, "o", "r", input) if err != nil { t.Errorf("Repositories.Edit returned error: %v", err) } @@ -510,7 +510,7 @@ func TestRepositoriesService_Edit(t *testing.T) { // Test s.client.Do failure client.BaseURL.Path = "/api-v3/" client.rateLimits[0].Reset.Time = time.Now().Add(10 * time.Minute) - got, resp, err = client.Repositories.Edit(ctx, "o", "r", input) + got, resp, err := client.Repositories.Edit(ctx, "o", "r", input) if got != nil { t.Errorf("rate.Reset.Time > now Edit = %#v, want nil", got) } @@ -531,14 +531,14 @@ func TestRepositoriesService_Delete(t *testing.T) { }) ctx := context.Background() - resp, err := client.Repositories.Delete(ctx, "o", "r") + _, err := client.Repositories.Delete(ctx, "o", "r") if err != nil { t.Errorf("Repositories.Delete returned error: %v", err) } // Test s.client.NewRequest failure client.BaseURL.Path = "" - resp, err = client.Repositories.Delete(ctx, "o", "r") + resp, err := client.Repositories.Delete(ctx, "o", "r") if resp != nil { t.Errorf("client.BaseURL.Path='' Delete resp = %#v, want nil", resp) } diff --git a/github/repos_traffic_test.go b/github/repos_traffic_test.go index 796544f3ce0..1479caaaf56 100644 --- a/github/repos_traffic_test.go +++ b/github/repos_traffic_test.go @@ -27,7 +27,7 @@ func TestRepositoriesService_ListTrafficReferrers(t *testing.T) { }]`) }) ctx := context.Background() - got, resp, err := client.Repositories.ListTrafficReferrers(ctx, "o", "r") + got, _, err := client.Repositories.ListTrafficReferrers(ctx, "o", "r") if err != nil { t.Errorf("Repositories.ListTrafficReferrers returned error: %+v", err) } @@ -43,7 +43,7 @@ func TestRepositoriesService_ListTrafficReferrers(t *testing.T) { // Test s.client.NewRequest failure client.BaseURL.Path = "" - got, resp, err = client.Repositories.ListTrafficReferrers(ctx, "o", "r") + got, resp, err := client.Repositories.ListTrafficReferrers(ctx, "o", "r") if got != nil { t.Errorf("client.BaseURL.Path='' ListTrafficReferrers = %#v, want nil", got) } @@ -83,7 +83,7 @@ func TestRepositoriesService_ListTrafficPaths(t *testing.T) { }]`) }) ctx := context.Background() - got, resp, err := client.Repositories.ListTrafficPaths(ctx, "o", "r") + got, _, err := client.Repositories.ListTrafficPaths(ctx, "o", "r") if err != nil { t.Errorf("Repositories.ListTrafficPaths returned error: %+v", err) } @@ -100,7 +100,7 @@ func TestRepositoriesService_ListTrafficPaths(t *testing.T) { // Test s.client.NewRequest failure client.BaseURL.Path = "" - got, resp, err = client.Repositories.ListTrafficPaths(ctx, "o", "r") + got, resp, err := client.Repositories.ListTrafficPaths(ctx, "o", "r") if got != nil { t.Errorf("client.BaseURL.Path='' ListTrafficPaths = %#v, want nil", got) } @@ -142,7 +142,7 @@ func TestRepositoriesService_ListTrafficViews(t *testing.T) { }) ctx := context.Background() - got, resp, err := client.Repositories.ListTrafficViews(ctx, "o", "r", nil) + got, _, err := client.Repositories.ListTrafficViews(ctx, "o", "r", nil) if err != nil { t.Errorf("Repositories.ListTrafficViews returned error: %+v", err) } @@ -162,14 +162,14 @@ func TestRepositoriesService_ListTrafficViews(t *testing.T) { } // Test addOptions failure - got, resp, err = client.Repositories.ListTrafficViews(ctx, "\n", "\n", &TrafficBreakdownOptions{}) + _, _, err = client.Repositories.ListTrafficViews(ctx, "\n", "\n", &TrafficBreakdownOptions{}) if err == nil { t.Error("bad options ListTrafficViews err = nil, want error") } // Test s.client.NewRequest failure client.BaseURL.Path = "" - got, resp, err = client.Repositories.ListTrafficViews(ctx, "o", "r", nil) + got, resp, err := client.Repositories.ListTrafficViews(ctx, "o", "r", nil) if got != nil { t.Errorf("client.BaseURL.Path='' ListTrafficViews = %#v, want nil", got) } @@ -211,7 +211,7 @@ func TestRepositoriesService_ListTrafficClones(t *testing.T) { }) ctx := context.Background() - got, resp, err := client.Repositories.ListTrafficClones(ctx, "o", "r", nil) + got, _, err := client.Repositories.ListTrafficClones(ctx, "o", "r", nil) if err != nil { t.Errorf("Repositories.ListTrafficClones returned error: %+v", err) } @@ -231,14 +231,14 @@ func TestRepositoriesService_ListTrafficClones(t *testing.T) { } // Test addOptions failure - got, resp, err = client.Repositories.ListTrafficClones(ctx, "\n", "\n", &TrafficBreakdownOptions{}) + _, _, err = client.Repositories.ListTrafficClones(ctx, "\n", "\n", &TrafficBreakdownOptions{}) if err == nil { t.Error("bad options ListTrafficViews err = nil, want error") } // Test s.client.NewRequest failure client.BaseURL.Path = "" - got, resp, err = client.Repositories.ListTrafficClones(ctx, "o", "r", nil) + got, resp, err := client.Repositories.ListTrafficClones(ctx, "o", "r", nil) if got != nil { t.Errorf("client.BaseURL.Path='' ListTrafficClones = %#v, want nil", got) } From 74c31241980287ea7859378a98271f4f4e303d2f Mon Sep 17 00:00:00 2001 From: shane Date: Thu, 25 Jul 2019 07:05:16 -0500 Subject: [PATCH 0029/1468] Add support for creating and using template repos (#1236) Fixes #1235. --- github/github-accessors.go | 48 +++++++++ github/github-stringify_test.go | 174 ++++++++++++++++---------------- github/github.go | 3 + github/repos.go | 117 +++++++++++++-------- github/repos_test.go | 66 +++++++++++- 5 files changed, 281 insertions(+), 127 deletions(-) diff --git a/github/github-accessors.go b/github/github-accessors.go index b4ca033d300..13e60abb843 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -9612,6 +9612,14 @@ func (r *Repository) GetIssuesURL() string { return *r.IssuesURL } +// GetIsTemplate returns the IsTemplate field if it's non-nil, zero value otherwise. +func (r *Repository) GetIsTemplate() bool { + if r == nil || r.IsTemplate == nil { + return false + } + return *r.IsTemplate +} + // GetKeysURL returns the KeysURL field if it's non-nil, zero value otherwise. func (r *Repository) GetKeysURL() string { if r == nil || r.KeysURL == nil { @@ -9900,6 +9908,14 @@ func (r *Repository) GetTeamsURL() string { return *r.TeamsURL } +// GetTemplateRepository returns the TemplateRepository field. +func (r *Repository) GetTemplateRepository() *Repository { + if r == nil { + return nil + } + return r.TemplateRepository +} + // GetTreesURL returns the TreesURL field if it's non-nil, zero value otherwise. func (r *Repository) GetTreesURL() string { if r == nil || r.TreesURL == nil { @@ -11668,6 +11684,38 @@ func (t *TeamProjectOptions) GetPermission() string { return *t.Permission } +// GetDescription returns the Description field if it's non-nil, zero value otherwise. +func (t *TemplateRepoRequest) GetDescription() string { + if t == nil || t.Description == nil { + return "" + } + return *t.Description +} + +// GetName returns the Name field if it's non-nil, zero value otherwise. +func (t *TemplateRepoRequest) GetName() string { + if t == nil || t.Name == nil { + return "" + } + return *t.Name +} + +// GetOwner returns the Owner field if it's non-nil, zero value otherwise. +func (t *TemplateRepoRequest) GetOwner() string { + if t == nil || t.Owner == nil { + return "" + } + return *t.Owner +} + +// GetPrivate returns the Private field if it's non-nil, zero value otherwise. +func (t *TemplateRepoRequest) GetPrivate() bool { + if t == nil || t.Private == nil { + return false + } + return *t.Private +} + // GetFragment returns the Fragment field if it's non-nil, zero value otherwise. func (t *TextMatch) GetFragment() string { if t == nil || t.Fragment == nil { diff --git a/github/github-stringify_test.go b/github/github-stringify_test.go index f424531e1f3..c91f7b5a277 100644 --- a/github/github-stringify_test.go +++ b/github/github-stringify_test.go @@ -1167,92 +1167,94 @@ func TestRepoStatus_String(t *testing.T) { func TestRepository_String(t *testing.T) { v := Repository{ - ID: Int64(0), - NodeID: String(""), - Owner: &User{}, - Name: String(""), - FullName: String(""), - Description: String(""), - Homepage: String(""), - CodeOfConduct: &CodeOfConduct{}, - DefaultBranch: String(""), - MasterBranch: String(""), - CreatedAt: &Timestamp{}, - PushedAt: &Timestamp{}, - UpdatedAt: &Timestamp{}, - HTMLURL: String(""), - CloneURL: String(""), - GitURL: String(""), - MirrorURL: String(""), - SSHURL: String(""), - SVNURL: String(""), - Language: String(""), - Fork: Bool(false), - ForksCount: Int(0), - NetworkCount: Int(0), - OpenIssuesCount: Int(0), - StargazersCount: Int(0), - SubscribersCount: Int(0), - WatchersCount: Int(0), - Size: Int(0), - AutoInit: Bool(false), - Parent: &Repository{}, - Source: &Repository{}, - Organization: &Organization{}, - AllowRebaseMerge: Bool(false), - AllowSquashMerge: Bool(false), - AllowMergeCommit: Bool(false), - Archived: Bool(false), - Disabled: Bool(false), - License: &License{}, - Private: Bool(false), - HasIssues: Bool(false), - HasWiki: Bool(false), - HasPages: Bool(false), - HasProjects: Bool(false), - HasDownloads: Bool(false), - LicenseTemplate: String(""), - GitignoreTemplate: String(""), - TeamID: Int64(0), - URL: String(""), - ArchiveURL: String(""), - AssigneesURL: String(""), - BlobsURL: String(""), - BranchesURL: String(""), - CollaboratorsURL: String(""), - CommentsURL: String(""), - CommitsURL: String(""), - CompareURL: String(""), - ContentsURL: String(""), - ContributorsURL: String(""), - DeploymentsURL: String(""), - DownloadsURL: String(""), - EventsURL: String(""), - ForksURL: String(""), - GitCommitsURL: String(""), - GitRefsURL: String(""), - GitTagsURL: String(""), - HooksURL: String(""), - IssueCommentURL: String(""), - IssueEventsURL: String(""), - IssuesURL: String(""), - KeysURL: String(""), - LabelsURL: String(""), - LanguagesURL: String(""), - MergesURL: String(""), - MilestonesURL: String(""), - NotificationsURL: String(""), - PullsURL: String(""), - ReleasesURL: String(""), - StargazersURL: String(""), - StatusesURL: String(""), - SubscribersURL: String(""), - SubscriptionURL: String(""), - TagsURL: String(""), - TreesURL: String(""), - TeamsURL: String(""), - } - want := `github.Repository{ID:0, NodeID:"", Owner:github.User{}, Name:"", FullName:"", Description:"", Homepage:"", CodeOfConduct:github.CodeOfConduct{}, DefaultBranch:"", MasterBranch:"", CreatedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, PushedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, UpdatedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, HTMLURL:"", CloneURL:"", GitURL:"", MirrorURL:"", SSHURL:"", SVNURL:"", Language:"", Fork:false, ForksCount:0, NetworkCount:0, OpenIssuesCount:0, StargazersCount:0, SubscribersCount:0, WatchersCount:0, Size:0, AutoInit:false, Parent:github.Repository{}, Source:github.Repository{}, Organization:github.Organization{}, AllowRebaseMerge:false, AllowSquashMerge:false, AllowMergeCommit:false, Archived:false, Disabled:false, License:github.License{}, Private:false, HasIssues:false, HasWiki:false, HasPages:false, HasProjects:false, HasDownloads:false, LicenseTemplate:"", GitignoreTemplate:"", TeamID:0, URL:"", ArchiveURL:"", AssigneesURL:"", BlobsURL:"", BranchesURL:"", CollaboratorsURL:"", CommentsURL:"", CommitsURL:"", CompareURL:"", ContentsURL:"", ContributorsURL:"", DeploymentsURL:"", DownloadsURL:"", EventsURL:"", ForksURL:"", GitCommitsURL:"", GitRefsURL:"", GitTagsURL:"", HooksURL:"", IssueCommentURL:"", IssueEventsURL:"", IssuesURL:"", KeysURL:"", LabelsURL:"", LanguagesURL:"", MergesURL:"", MilestonesURL:"", NotificationsURL:"", PullsURL:"", ReleasesURL:"", StargazersURL:"", StatusesURL:"", SubscribersURL:"", SubscriptionURL:"", TagsURL:"", TreesURL:"", TeamsURL:""}` + ID: Int64(0), + NodeID: String(""), + Owner: &User{}, + Name: String(""), + FullName: String(""), + Description: String(""), + Homepage: String(""), + CodeOfConduct: &CodeOfConduct{}, + DefaultBranch: String(""), + MasterBranch: String(""), + CreatedAt: &Timestamp{}, + PushedAt: &Timestamp{}, + UpdatedAt: &Timestamp{}, + HTMLURL: String(""), + CloneURL: String(""), + GitURL: String(""), + MirrorURL: String(""), + SSHURL: String(""), + SVNURL: String(""), + Language: String(""), + Fork: Bool(false), + ForksCount: Int(0), + NetworkCount: Int(0), + OpenIssuesCount: Int(0), + StargazersCount: Int(0), + SubscribersCount: Int(0), + WatchersCount: Int(0), + Size: Int(0), + AutoInit: Bool(false), + Parent: &Repository{}, + Source: &Repository{}, + TemplateRepository: &Repository{}, + Organization: &Organization{}, + AllowRebaseMerge: Bool(false), + AllowSquashMerge: Bool(false), + AllowMergeCommit: Bool(false), + Archived: Bool(false), + Disabled: Bool(false), + License: &License{}, + Private: Bool(false), + HasIssues: Bool(false), + HasWiki: Bool(false), + HasPages: Bool(false), + HasProjects: Bool(false), + HasDownloads: Bool(false), + IsTemplate: Bool(false), + LicenseTemplate: String(""), + GitignoreTemplate: String(""), + TeamID: Int64(0), + URL: String(""), + ArchiveURL: String(""), + AssigneesURL: String(""), + BlobsURL: String(""), + BranchesURL: String(""), + CollaboratorsURL: String(""), + CommentsURL: String(""), + CommitsURL: String(""), + CompareURL: String(""), + ContentsURL: String(""), + ContributorsURL: String(""), + DeploymentsURL: String(""), + DownloadsURL: String(""), + EventsURL: String(""), + ForksURL: String(""), + GitCommitsURL: String(""), + GitRefsURL: String(""), + GitTagsURL: String(""), + HooksURL: String(""), + IssueCommentURL: String(""), + IssueEventsURL: String(""), + IssuesURL: String(""), + KeysURL: String(""), + LabelsURL: String(""), + LanguagesURL: String(""), + MergesURL: String(""), + MilestonesURL: String(""), + NotificationsURL: String(""), + PullsURL: String(""), + ReleasesURL: String(""), + StargazersURL: String(""), + StatusesURL: String(""), + SubscribersURL: String(""), + SubscriptionURL: String(""), + TagsURL: String(""), + TreesURL: String(""), + TeamsURL: String(""), + } + want := `github.Repository{ID:0, NodeID:"", Owner:github.User{}, Name:"", FullName:"", Description:"", Homepage:"", CodeOfConduct:github.CodeOfConduct{}, DefaultBranch:"", MasterBranch:"", CreatedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, PushedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, UpdatedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, HTMLURL:"", CloneURL:"", GitURL:"", MirrorURL:"", SSHURL:"", SVNURL:"", Language:"", Fork:false, ForksCount:0, NetworkCount:0, OpenIssuesCount:0, StargazersCount:0, SubscribersCount:0, WatchersCount:0, Size:0, AutoInit:false, Parent:github.Repository{}, Source:github.Repository{}, TemplateRepository:github.Repository{}, Organization:github.Organization{}, AllowRebaseMerge:false, AllowSquashMerge:false, AllowMergeCommit:false, Archived:false, Disabled:false, License:github.License{}, Private:false, HasIssues:false, HasWiki:false, HasPages:false, HasProjects:false, HasDownloads:false, IsTemplate:false, LicenseTemplate:"", GitignoreTemplate:"", TeamID:0, URL:"", ArchiveURL:"", AssigneesURL:"", BlobsURL:"", BranchesURL:"", CollaboratorsURL:"", CommentsURL:"", CommitsURL:"", CompareURL:"", ContentsURL:"", ContributorsURL:"", DeploymentsURL:"", DownloadsURL:"", EventsURL:"", ForksURL:"", GitCommitsURL:"", GitRefsURL:"", GitTagsURL:"", HooksURL:"", IssueCommentURL:"", IssueEventsURL:"", IssuesURL:"", KeysURL:"", LabelsURL:"", LanguagesURL:"", MergesURL:"", MilestonesURL:"", NotificationsURL:"", PullsURL:"", ReleasesURL:"", StargazersURL:"", StatusesURL:"", SubscribersURL:"", SubscriptionURL:"", TagsURL:"", TreesURL:"", TeamsURL:""}` if got := v.String(); got != want { t.Errorf("Repository.String = %v, want %v", got, want) } diff --git a/github/github.go b/github/github.go index 7a82677c415..d348a7b6743 100644 --- a/github/github.go +++ b/github/github.go @@ -153,6 +153,9 @@ const ( // https://developer.github.com/v3/previews/#repository-creation-permissions mediaTypeMemberAllowedRepoCreationTypePreview = "application/vnd.github.surtur-preview+json" + + // https://developer.github.com/v3/previews/#create-and-use-repository-templates + mediaTypeRepositoryTemplatePreview = "application/vnd.github.baptiste-preview+json" ) // A Client manages communication with the GitHub API. diff --git a/github/repos.go b/github/repos.go index 5f44c6d86fc..a380f3028cd 100644 --- a/github/repos.go +++ b/github/repos.go @@ -19,45 +19,46 @@ type RepositoriesService service // Repository represents a GitHub repository. type Repository struct { - ID *int64 `json:"id,omitempty"` - NodeID *string `json:"node_id,omitempty"` - Owner *User `json:"owner,omitempty"` - Name *string `json:"name,omitempty"` - FullName *string `json:"full_name,omitempty"` - Description *string `json:"description,omitempty"` - Homepage *string `json:"homepage,omitempty"` - CodeOfConduct *CodeOfConduct `json:"code_of_conduct,omitempty"` - DefaultBranch *string `json:"default_branch,omitempty"` - MasterBranch *string `json:"master_branch,omitempty"` - CreatedAt *Timestamp `json:"created_at,omitempty"` - PushedAt *Timestamp `json:"pushed_at,omitempty"` - UpdatedAt *Timestamp `json:"updated_at,omitempty"` - HTMLURL *string `json:"html_url,omitempty"` - CloneURL *string `json:"clone_url,omitempty"` - GitURL *string `json:"git_url,omitempty"` - MirrorURL *string `json:"mirror_url,omitempty"` - SSHURL *string `json:"ssh_url,omitempty"` - SVNURL *string `json:"svn_url,omitempty"` - Language *string `json:"language,omitempty"` - Fork *bool `json:"fork,omitempty"` - ForksCount *int `json:"forks_count,omitempty"` - NetworkCount *int `json:"network_count,omitempty"` - OpenIssuesCount *int `json:"open_issues_count,omitempty"` - StargazersCount *int `json:"stargazers_count,omitempty"` - SubscribersCount *int `json:"subscribers_count,omitempty"` - WatchersCount *int `json:"watchers_count,omitempty"` - Size *int `json:"size,omitempty"` - AutoInit *bool `json:"auto_init,omitempty"` - Parent *Repository `json:"parent,omitempty"` - Source *Repository `json:"source,omitempty"` - Organization *Organization `json:"organization,omitempty"` - Permissions *map[string]bool `json:"permissions,omitempty"` - AllowRebaseMerge *bool `json:"allow_rebase_merge,omitempty"` - AllowSquashMerge *bool `json:"allow_squash_merge,omitempty"` - AllowMergeCommit *bool `json:"allow_merge_commit,omitempty"` - Topics []string `json:"topics,omitempty"` - Archived *bool `json:"archived,omitempty"` - Disabled *bool `json:"disabled,omitempty"` + ID *int64 `json:"id,omitempty"` + NodeID *string `json:"node_id,omitempty"` + Owner *User `json:"owner,omitempty"` + Name *string `json:"name,omitempty"` + FullName *string `json:"full_name,omitempty"` + Description *string `json:"description,omitempty"` + Homepage *string `json:"homepage,omitempty"` + CodeOfConduct *CodeOfConduct `json:"code_of_conduct,omitempty"` + DefaultBranch *string `json:"default_branch,omitempty"` + MasterBranch *string `json:"master_branch,omitempty"` + CreatedAt *Timestamp `json:"created_at,omitempty"` + PushedAt *Timestamp `json:"pushed_at,omitempty"` + UpdatedAt *Timestamp `json:"updated_at,omitempty"` + HTMLURL *string `json:"html_url,omitempty"` + CloneURL *string `json:"clone_url,omitempty"` + GitURL *string `json:"git_url,omitempty"` + MirrorURL *string `json:"mirror_url,omitempty"` + SSHURL *string `json:"ssh_url,omitempty"` + SVNURL *string `json:"svn_url,omitempty"` + Language *string `json:"language,omitempty"` + Fork *bool `json:"fork,omitempty"` + ForksCount *int `json:"forks_count,omitempty"` + NetworkCount *int `json:"network_count,omitempty"` + OpenIssuesCount *int `json:"open_issues_count,omitempty"` + StargazersCount *int `json:"stargazers_count,omitempty"` + SubscribersCount *int `json:"subscribers_count,omitempty"` + WatchersCount *int `json:"watchers_count,omitempty"` + Size *int `json:"size,omitempty"` + AutoInit *bool `json:"auto_init,omitempty"` + Parent *Repository `json:"parent,omitempty"` + Source *Repository `json:"source,omitempty"` + TemplateRepository *Repository `json:"template_repository,omitempty"` + Organization *Organization `json:"organization,omitempty"` + Permissions *map[string]bool `json:"permissions,omitempty"` + AllowRebaseMerge *bool `json:"allow_rebase_merge,omitempty"` + AllowSquashMerge *bool `json:"allow_squash_merge,omitempty"` + AllowMergeCommit *bool `json:"allow_merge_commit,omitempty"` + Topics []string `json:"topics,omitempty"` + Archived *bool `json:"archived,omitempty"` + Disabled *bool `json:"disabled,omitempty"` // Only provided when using RepositoriesService.Get while in preview License *License `json:"license,omitempty"` @@ -69,6 +70,7 @@ type Repository struct { HasPages *bool `json:"has_pages,omitempty"` HasProjects *bool `json:"has_projects,omitempty"` HasDownloads *bool `json:"has_downloads,omitempty"` + IsTemplate *bool `json:"is_template,omitempty"` LicenseTemplate *string `json:"license_template,omitempty"` GitignoreTemplate *string `json:"gitignore_template,omitempty"` @@ -275,6 +277,7 @@ type createRepoRequest struct { HasIssues *bool `json:"has_issues,omitempty"` HasProjects *bool `json:"has_projects,omitempty"` HasWiki *bool `json:"has_wiki,omitempty"` + IsTemplate *bool `json:"is_template,omitempty"` // Creating an organization repository. Required for non-owners. TeamID *int64 `json:"team_id,omitempty"` @@ -311,6 +314,7 @@ func (s *RepositoriesService) Create(ctx context.Context, org string, repo *Repo HasIssues: repo.HasIssues, HasProjects: repo.HasProjects, HasWiki: repo.HasWiki, + IsTemplate: repo.IsTemplate, TeamID: repo.TeamID, AutoInit: repo.AutoInit, GitignoreTemplate: repo.GitignoreTemplate, @@ -325,6 +329,38 @@ func (s *RepositoriesService) Create(ctx context.Context, org string, repo *Repo return nil, nil, err } + req.Header.Set("Accept", mediaTypeRepositoryTemplatePreview) + r := new(Repository) + resp, err := s.client.Do(ctx, req, r) + if err != nil { + return nil, resp, err + } + + return r, resp, nil +} + +// TemplateRepoRequest represents a request to create a repository from a template. +type TemplateRepoRequest struct { + // Name is required when creating a repo. + Name *string `json:"name,omitempty"` + Owner *string `json:"owner,omitempty"` + Description *string `json:"description,omitempty"` + + Private *bool `json:"private,omitempty"` +} + +// CreateFromTemplate generates a repository from a template. +// +// GitHub API docs: https://developer.github.com/v3/repos/#create-repository-using-a-repository-template +func (s *RepositoriesService) CreateFromTemplate(ctx context.Context, templateOwner, templateRepo string, templateRepoReq *TemplateRepoRequest) (*Repository, *Response, error) { + u := fmt.Sprintf("repos/%v/%v/generate", templateOwner, templateRepo) + + req, err := s.client.NewRequest("POST", u, templateRepoReq) + if err != nil { + return nil, nil, err + } + + req.Header.Set("Accept", mediaTypeRepositoryTemplatePreview) r := new(Repository) resp, err := s.client.Do(ctx, req, r) if err != nil { @@ -346,7 +382,7 @@ func (s *RepositoriesService) Get(ctx context.Context, owner, repo string) (*Rep // TODO: remove custom Accept header when the license support fully launches // https://developer.github.com/v3/licenses/#get-a-repositorys-license - acceptHeaders := []string{mediaTypeCodesOfConductPreview, mediaTypeTopicsPreview} + acceptHeaders := []string{mediaTypeCodesOfConductPreview, mediaTypeTopicsPreview, mediaTypeRepositoryTemplatePreview} req.Header.Set("Accept", strings.Join(acceptHeaders, ", ")) repository := new(Repository) @@ -409,6 +445,7 @@ func (s *RepositoriesService) Edit(ctx context.Context, owner, repo string, repo return nil, nil, err } + req.Header.Set("Accept", mediaTypeRepositoryTemplatePreview) r := new(Repository) resp, err := s.client.Do(ctx, req, r) if err != nil { diff --git a/github/repos_test.go b/github/repos_test.go index 75e09a83e4b..75ccbb0da68 100644 --- a/github/repos_test.go +++ b/github/repos_test.go @@ -253,6 +253,7 @@ func TestRepositoriesService_Create_user(t *testing.T) { json.NewDecoder(r.Body).Decode(v) testMethod(t, r, "POST") + testHeader(t, r, "Accept", mediaTypeRepositoryTemplatePreview) want := &createRepoRequest{Name: String("n")} if !reflect.DeepEqual(v, want) { t.Errorf("Request body = %+v, want %+v", v, want) @@ -314,6 +315,7 @@ func TestRepositoriesService_Create_org(t *testing.T) { json.NewDecoder(r.Body).Decode(v) testMethod(t, r, "POST") + testHeader(t, r, "Accept", mediaTypeRepositoryTemplatePreview) want := &createRepoRequest{Name: String("n")} if !reflect.DeepEqual(v, want) { t.Errorf("Request body = %+v, want %+v", v, want) @@ -333,11 +335,72 @@ func TestRepositoriesService_Create_org(t *testing.T) { } } +func TestRepositoriesService_CreateFromTemplate(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + templateRepoReq := &TemplateRepoRequest{ + Name: String("n"), + } + + mux.HandleFunc("/repos/to/tr/generate", func(w http.ResponseWriter, r *http.Request) { + v := new(TemplateRepoRequest) + json.NewDecoder(r.Body).Decode(v) + + testMethod(t, r, "POST") + testHeader(t, r, "Accept", mediaTypeRepositoryTemplatePreview) + want := &TemplateRepoRequest{Name: String("n")} + if !reflect.DeepEqual(v, want) { + t.Errorf("Request body = %+v, want %+v", v, want) + } + + fmt.Fprint(w, `{"id":1,"name":"n"}`) + }) + + ctx := context.Background() + got, _, err := client.Repositories.CreateFromTemplate(ctx, "to", "tr", templateRepoReq) + if err != nil { + t.Errorf("Repositories.CreateFromTemplate returned error: %v", err) + } + + want := &Repository{ID: Int64(1), Name: String("n")} + if !reflect.DeepEqual(got, want) { + t.Errorf("Repositories.CreateFromTemplate returned %+v, want %+v", got, want) + } + + // Test s.client.NewRequest failure + client.BaseURL.Path = "" + got, resp, err := client.Repositories.CreateFromTemplate(ctx, "to", "tr", templateRepoReq) + if got != nil { + t.Errorf("client.BaseURL.Path='' CreateFromTemplate = %#v, want nil", got) + } + if resp != nil { + t.Errorf("client.BaseURL.Path='' CreateFromTemplate resp = %#v, want nil", resp) + } + if err == nil { + t.Error("client.BaseURL.Path='' CreateFromTemplate err = nil, want error") + } + + // Test s.client.Do failure + client.BaseURL.Path = "/api-v3/" + client.rateLimits[0].Reset.Time = time.Now().Add(10 * time.Minute) + got, resp, err = client.Repositories.CreateFromTemplate(ctx, "to", "tr", templateRepoReq) + if got != nil { + t.Errorf("rate.Reset.Time > now CreateFromTemplate = %#v, want nil", got) + } + if want := http.StatusForbidden; resp == nil || resp.Response.StatusCode != want { + t.Errorf("rate.Reset.Time > now CreateFromTemplate resp = %#v, want StatusCode=%v", resp.Response, want) + } + if err == nil { + t.Error("rate.Reset.Time > now CreateFromTemplate err = nil, want error") + } +} + func TestRepositoriesService_Get(t *testing.T) { client, mux, _, teardown := setup() defer teardown() - wantAcceptHeaders := []string{mediaTypeCodesOfConductPreview, mediaTypeTopicsPreview} + wantAcceptHeaders := []string{mediaTypeCodesOfConductPreview, mediaTypeTopicsPreview, mediaTypeRepositoryTemplatePreview} mux.HandleFunc("/repos/o/r", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", ")) @@ -490,6 +553,7 @@ func TestRepositoriesService_Edit(t *testing.T) { json.NewDecoder(r.Body).Decode(v) testMethod(t, r, "PATCH") + testHeader(t, r, "Accept", mediaTypeRepositoryTemplatePreview) if !reflect.DeepEqual(v, input) { t.Errorf("Request body = %+v, want %+v", v, input) } From eb81d96cb65bd00d44fafded1e1245a0bab9bbac Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Thu, 25 Jul 2019 14:08:36 +0200 Subject: [PATCH 0030/1468] Use time.Until (#1233) --- github/github.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/github/github.go b/github/github.go index d348a7b6743..6ab801f2284 100644 --- a/github/github.go +++ b/github/github.go @@ -649,7 +649,7 @@ type RateLimitError struct { func (r *RateLimitError) Error() string { return fmt.Sprintf("%v %v: %d %v %v", r.Response.Request.Method, sanitizeURL(r.Response.Request.URL), - r.Response.StatusCode, r.Message, formatRateReset(r.Rate.Reset.Time.Sub(time.Now()))) + r.Response.StatusCode, r.Message, formatRateReset(time.Until(r.Rate.Reset.Time))) } // AcceptedError occurs when GitHub returns 202 Accepted response with an From 4c1ec01570ac97daecec8c2b62b07176700f093d Mon Sep 17 00:00:00 2001 From: Naoki Ainoya <2300438+ainoya@users.noreply.github.com> Date: Thu, 25 Jul 2019 21:15:19 +0900 Subject: [PATCH 0031/1468] Fix GetProjectCard argument name (#1239) --- github/projects.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/github/projects.go b/github/projects.go index c7a68f53d98..1e9620dfd9f 100644 --- a/github/projects.go +++ b/github/projects.go @@ -344,8 +344,8 @@ func (s *ProjectsService) ListProjectCards(ctx context.Context, columnID int64, // GetProjectCard gets a card in a column of a GitHub Project. // // GitHub API docs: https://developer.github.com/v3/projects/cards/#get-a-project-card -func (s *ProjectsService) GetProjectCard(ctx context.Context, columnID int64) (*ProjectCard, *Response, error) { - u := fmt.Sprintf("projects/columns/cards/%v", columnID) +func (s *ProjectsService) GetProjectCard(ctx context.Context, cardID int64) (*ProjectCard, *Response, error) { + u := fmt.Sprintf("projects/columns/cards/%v", cardID) req, err := s.client.NewRequest("GET", u, nil) if err != nil { return nil, nil, err From 24f172eae1a0c53c780f259d8492979900e9af2e Mon Sep 17 00:00:00 2001 From: Glenn Lewis <6598971+gmlewis@users.noreply.github.com> Date: Thu, 25 Jul 2019 08:17:48 -0400 Subject: [PATCH 0032/1468] Update AUTHORS with recent contributors --- AUTHORS | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/AUTHORS b/AUTHORS index 8a41ba02676..d38236ed45f 100644 --- a/AUTHORS +++ b/AUTHORS @@ -59,6 +59,7 @@ Chris King Chris Roche Chris Schaefer chrisforrette +Christian Muehlhaeuser Christoph Sassenberg Colin Misare Craig Peterson @@ -157,6 +158,7 @@ Maksim Zhylinski Mark Tareshawty Martin-Louis Bright Marwan Sulaiman +Masayuki Izumi Mat Geist Matt Matt Brender @@ -187,6 +189,7 @@ Pete Wagner Petr Shevtsov Pierre Carrier Piotr Zurek +Quentin Leffray Quinn Slack Rackspace US, Inc. Radek Simko @@ -223,6 +226,7 @@ Shrikrishna Singh sona-tar SoundCloud, Ltd. Sridhar Mocherla +SriVignessh Pss Stian Eikeland Tasya Aditya Rukmana Thomas Bruyelle @@ -237,6 +241,7 @@ Vlad Ungureanu Wasim Thabraze Will Maier William Bailey +William Cooke xibz Yann Malet Yannick Utard From da8b749b25d68690af6239660210ab1915b029cd Mon Sep 17 00:00:00 2001 From: Junya Kono Date: Tue, 20 Aug 2019 12:14:35 +0900 Subject: [PATCH 0033/1468] Add PullsURL to PushEventRepository (#1253) --- github/event_types.go | 1 + github/github-accessors.go | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/github/event_types.go b/github/event_types.go index 8ba922a2b74..d3e2123547d 100644 --- a/github/event_types.go +++ b/github/event_types.go @@ -707,6 +707,7 @@ type PushEventRepository struct { PushedAt *Timestamp `json:"pushed_at,omitempty"` UpdatedAt *Timestamp `json:"updated_at,omitempty"` Homepage *string `json:"homepage,omitempty"` + PullsURL *string `json:"pulls_url,omitempty"` Size *int `json:"size,omitempty"` StargazersCount *int `json:"stargazers_count,omitempty"` WatchersCount *int `json:"watchers_count,omitempty"` diff --git a/github/github-accessors.go b/github/github-accessors.go index 13e60abb843..7c89cb60d0b 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -8860,6 +8860,14 @@ func (p *PushEventRepository) GetPrivate() bool { return *p.Private } +// GetPullsURL returns the PullsURL field if it's non-nil, zero value otherwise. +func (p *PushEventRepository) GetPullsURL() string { + if p == nil || p.PullsURL == nil { + return "" + } + return *p.PullsURL +} + // GetPushedAt returns the PushedAt field if it's non-nil, zero value otherwise. func (p *PushEventRepository) GetPushedAt() Timestamp { if p == nil || p.PushedAt == nil { From 45b5e3c13c1d4b0b88e192729b0042e19840635f Mon Sep 17 00:00:00 2001 From: Szymon Kodrebski Date: Wed, 21 Aug 2019 14:11:03 +0200 Subject: [PATCH 0034/1468] Add missing `CreatedAt` field in users_keys class (#1256) Fixes #1255. --- github/github-accessors.go | 8 ++++++++ github/github-stringify_test.go | 13 +++++++------ github/users_keys.go | 11 ++++++----- 3 files changed, 21 insertions(+), 11 deletions(-) diff --git a/github/github-accessors.go b/github/github-accessors.go index 7c89cb60d0b..434cc938c62 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -4612,6 +4612,14 @@ func (i *IssueStats) GetTotalIssues() int { return *i.TotalIssues } +// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise. +func (k *Key) GetCreatedAt() Timestamp { + if k == nil || k.CreatedAt == nil { + return Timestamp{} + } + return *k.CreatedAt +} + // GetID returns the ID field if it's non-nil, zero value otherwise. func (k *Key) GetID() int64 { if k == nil || k.ID == nil { diff --git a/github/github-stringify_test.go b/github/github-stringify_test.go index c91f7b5a277..2e7b285ea0e 100644 --- a/github/github-stringify_test.go +++ b/github/github-stringify_test.go @@ -623,13 +623,14 @@ func TestIssueStats_String(t *testing.T) { func TestKey_String(t *testing.T) { v := Key{ - ID: Int64(0), - Key: String(""), - URL: String(""), - Title: String(""), - ReadOnly: Bool(false), + ID: Int64(0), + Key: String(""), + URL: String(""), + Title: String(""), + ReadOnly: Bool(false), + CreatedAt: &Timestamp{}, } - want := `github.Key{ID:0, Key:"", URL:"", Title:"", ReadOnly:false}` + want := `github.Key{ID:0, Key:"", URL:"", Title:"", ReadOnly:false, CreatedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}}` if got := v.String(); got != want { t.Errorf("Key.String = %v, want %v", got, want) } diff --git a/github/users_keys.go b/github/users_keys.go index ddc832a1ece..39a4f54d6c2 100644 --- a/github/users_keys.go +++ b/github/users_keys.go @@ -12,11 +12,12 @@ import ( // Key represents a public SSH key used to authenticate a user or deploy script. type Key struct { - ID *int64 `json:"id,omitempty"` - Key *string `json:"key,omitempty"` - URL *string `json:"url,omitempty"` - Title *string `json:"title,omitempty"` - ReadOnly *bool `json:"read_only,omitempty"` + ID *int64 `json:"id,omitempty"` + Key *string `json:"key,omitempty"` + URL *string `json:"url,omitempty"` + Title *string `json:"title,omitempty"` + ReadOnly *bool `json:"read_only,omitempty"` + CreatedAt *Timestamp `json:"created_at,omitempty"` } func (k Key) String() string { From 61d9e5b01e3f9ee20442a6ca476aec6d84beaa48 Mon Sep 17 00:00:00 2001 From: Emory Ruscus <47612504+emoryruscus@users.noreply.github.com> Date: Fri, 23 Aug 2019 21:25:00 -0400 Subject: [PATCH 0035/1468] Update apps.go (#1238) Closes #1182. --- github/apps.go | 21 ++++++++-- github/apps_test.go | 82 +++++++++++++++++++++++++++++++++++++- github/github-accessors.go | 16 ++++++++ 3 files changed, 114 insertions(+), 5 deletions(-) diff --git a/github/apps.go b/github/apps.go index f675a9abd18..5041e801280 100644 --- a/github/apps.go +++ b/github/apps.go @@ -32,8 +32,21 @@ type App struct { // InstallationToken represents an installation token. type InstallationToken struct { - Token *string `json:"token,omitempty"` - ExpiresAt *time.Time `json:"expires_at,omitempty"` + Token *string `json:"token,omitempty"` + ExpiresAt *time.Time `json:"expires_at,omitempty"` + Permissions *InstallationPermissions `json:"permissions,omitempty"` + Repositories []*Repository `json:"repositories,omitempty"` +} + +// InstallationTokenOptions allow restricting a token's access to specific repositories. +type InstallationTokenOptions struct { + // The IDs of the repositories that the installation token can access. + // Providing repository IDs restricts the access of an installation token to specific repositories. + RepositoryIDs []int64 `json:"repository_ids,omitempty"` + + // The permissions granted to the access token. + // The permissions object includes the permission names and their access type. + Permissions *InstallationPermissions `json:"permissions,omitempty"` } // InstallationPermissions lists the repository and organization permissions for an installation. @@ -194,10 +207,10 @@ func (s *AppsService) ListUserInstallations(ctx context.Context, opt *ListOption // CreateInstallationToken creates a new installation token. // // GitHub API docs: https://developer.github.com/v3/apps/#create-a-new-installation-token -func (s *AppsService) CreateInstallationToken(ctx context.Context, id int64) (*InstallationToken, *Response, error) { +func (s *AppsService) CreateInstallationToken(ctx context.Context, id int64, opt *InstallationTokenOptions) (*InstallationToken, *Response, error) { u := fmt.Sprintf("app/installations/%v/access_tokens", id) - req, err := s.client.NewRequest("POST", u, nil) + req, err := s.client.NewRequest("POST", u, opt) if err != nil { return nil, nil, err } diff --git a/github/apps_test.go b/github/apps_test.go index 8d5b27d38ce..55ef2a095ae 100644 --- a/github/apps_test.go +++ b/github/apps_test.go @@ -6,8 +6,12 @@ package github import ( + "bytes" "context" + "encoding/json" "fmt" + "io" + "io/ioutil" "net/http" "reflect" "testing" @@ -214,7 +218,54 @@ func TestAppsService_CreateInstallationToken(t *testing.T) { fmt.Fprint(w, `{"token":"t"}`) }) - token, _, err := client.Apps.CreateInstallationToken(context.Background(), 1) + token, _, err := client.Apps.CreateInstallationToken(context.Background(), 1, nil) + if err != nil { + t.Errorf("Apps.CreateInstallationToken returned error: %v", err) + } + + want := &InstallationToken{Token: String("t")} + if !reflect.DeepEqual(token, want) { + t.Errorf("Apps.CreateInstallationToken returned %+v, want %+v", token, want) + } +} + +func TestAppsService_CreateInstallationTokenWithOptions(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + installationTokenOptions := &InstallationTokenOptions{ + RepositoryIDs: []int64{1234}, + Permissions: &InstallationPermissions{ + Contents: String("write"), + Issues: String("read"), + }, + } + + // Convert InstallationTokenOptions into an io.ReadCloser object for comparison. + wantBody, err := GetReadCloser(installationTokenOptions) + if err != nil { + t.Errorf("GetReadCloser returned error: %v", err) + } + + mux.HandleFunc("/app/installations/1/access_tokens", func(w http.ResponseWriter, r *http.Request) { + // Read request body contents. + var gotBodyBytes []byte + gotBodyBytes, err = ioutil.ReadAll(r.Body) + if err != nil { + t.Errorf("ReadAll returned error: %v", err) + } + r.Body = ioutil.NopCloser(bytes.NewBuffer(gotBodyBytes)) + + if !reflect.DeepEqual(r.Body, wantBody) { + t.Errorf("request sent %+v, want %+v", r.Body, wantBody) + } + + testMethod(t, r, "POST") + testHeader(t, r, "Accept", mediaTypeIntegrationPreview) + fmt.Fprint(w, `{"token":"t"}`) + }) + + token, _, err := client.Apps.CreateInstallationToken(context.Background(), 1, installationTokenOptions) if err != nil { t.Errorf("Apps.CreateInstallationToken returned error: %v", err) } @@ -247,6 +298,7 @@ func TestAppsService_CreateAttachement(t *testing.T) { t.Errorf("CreateAttachment = %+v, want %+v", got, want) } } + func TestAppsService_FindOrganizationInstallation(t *testing.T) { client, mux, _, teardown := setup() defer teardown() @@ -330,3 +382,31 @@ func TestAppsService_FindUserInstallation(t *testing.T) { t.Errorf("Apps.FindUserInstallation returned %+v, want %+v", installation, want) } } + +// GetReadWriter converts a body interface into an io.ReadWriter object. +func GetReadWriter(body interface{}) (io.ReadWriter, error) { + var buf io.ReadWriter + if body != nil { + buf = new(bytes.Buffer) + enc := json.NewEncoder(buf) + err := enc.Encode(body) + if err != nil { + return nil, err + } + } + return buf, nil +} + +// GetReadCloser converts a body interface into an io.ReadCloser object. +func GetReadCloser(body interface{}) (io.ReadCloser, error) { + buf, err := GetReadWriter(body) + if err != nil { + return nil, err + } + + all, err := ioutil.ReadAll(buf) + if err != nil { + return nil, err + } + return ioutil.NopCloser(bytes.NewBuffer(all)), nil +} diff --git a/github/github-accessors.go b/github/github-accessors.go index 434cc938c62..03fd93f927a 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -3884,6 +3884,14 @@ func (i *InstallationToken) GetExpiresAt() time.Time { return *i.ExpiresAt } +// GetPermissions returns the Permissions field. +func (i *InstallationToken) GetPermissions() *InstallationPermissions { + if i == nil { + return nil + } + return i.Permissions +} + // GetToken returns the Token field if it's non-nil, zero value otherwise. func (i *InstallationToken) GetToken() string { if i == nil || i.Token == nil { @@ -3892,6 +3900,14 @@ func (i *InstallationToken) GetToken() string { return *i.Token } +// GetPermissions returns the Permissions field. +func (i *InstallationTokenOptions) GetPermissions() *InstallationPermissions { + if i == nil { + return nil + } + return i.Permissions +} + // GetExpiresAt returns the ExpiresAt field if it's non-nil, zero value otherwise. func (i *InteractionRestriction) GetExpiresAt() Timestamp { if i == nil || i.ExpiresAt == nil { From 2245c71a086635d02fa2d2d5cc43f4c3f7f9faac Mon Sep 17 00:00:00 2001 From: Glenn Lewis <6598971+gmlewis@users.noreply.github.com> Date: Fri, 23 Aug 2019 21:27:25 -0400 Subject: [PATCH 0036/1468] Bump major version to v28 due to #1238 --- README.md | 2 +- example/appengine/app.go | 2 +- example/basicauth/main.go | 2 +- example/commitpr/main.go | 2 +- example/migrations/main.go | 2 +- example/newrepo/main.go | 2 +- example/simple/main.go | 2 +- github/doc.go | 2 +- github/examples_test.go | 2 +- go.mod | 2 +- test/fields/fields.go | 2 +- test/integration/activity_test.go | 2 +- test/integration/authorizations_test.go | 2 +- test/integration/github_test.go | 2 +- test/integration/repos_test.go | 2 +- test/integration/users_test.go | 2 +- 16 files changed, 16 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index eb26b6f914a..66503b244ae 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ If you're interested in using the [GraphQL API v4][], the recommended library is ## Usage ## ```go -import "github.com/google/go-github/v27/github" // with go modules enabled (GO111MODULE=on or outside GOPATH) +import "github.com/google/go-github/v28/github" // with go modules enabled (GO111MODULE=on or outside GOPATH) import "github.com/google/go-github/github" // with go modules disabled ``` diff --git a/example/appengine/app.go b/example/appengine/app.go index 2f716c6c2c4..8f567496bb5 100644 --- a/example/appengine/app.go +++ b/example/appengine/app.go @@ -12,7 +12,7 @@ import ( "net/http" "os" - "github.com/google/go-github/v27/github" + "github.com/google/go-github/v28/github" "golang.org/x/oauth2" "google.golang.org/appengine" "google.golang.org/appengine/log" diff --git a/example/basicauth/main.go b/example/basicauth/main.go index d87866fb8c0..33b118ba61c 100644 --- a/example/basicauth/main.go +++ b/example/basicauth/main.go @@ -16,7 +16,7 @@ import ( "strings" "syscall" - "github.com/google/go-github/v27/github" + "github.com/google/go-github/v28/github" "golang.org/x/crypto/ssh/terminal" ) diff --git a/example/commitpr/main.go b/example/commitpr/main.go index e0c60355e28..53061841aab 100644 --- a/example/commitpr/main.go +++ b/example/commitpr/main.go @@ -31,7 +31,7 @@ import ( "strings" "time" - "github.com/google/go-github/v27/github" + "github.com/google/go-github/v28/github" "golang.org/x/oauth2" ) diff --git a/example/migrations/main.go b/example/migrations/main.go index c36ddd76afc..e0d30530758 100644 --- a/example/migrations/main.go +++ b/example/migrations/main.go @@ -12,7 +12,7 @@ import ( "context" "fmt" - "github.com/google/go-github/v27/github" + "github.com/google/go-github/v28/github" "golang.org/x/oauth2" ) diff --git a/example/newrepo/main.go b/example/newrepo/main.go index f91c5c56b40..82eccf5eedd 100644 --- a/example/newrepo/main.go +++ b/example/newrepo/main.go @@ -16,7 +16,7 @@ import ( "log" "os" - "github.com/google/go-github/v27/github" + "github.com/google/go-github/v28/github" "golang.org/x/oauth2" ) diff --git a/example/simple/main.go b/example/simple/main.go index 8b790f46a7f..b10be06b9eb 100644 --- a/example/simple/main.go +++ b/example/simple/main.go @@ -12,7 +12,7 @@ import ( "context" "fmt" - "github.com/google/go-github/v27/github" + "github.com/google/go-github/v28/github" ) // Fetch all the public organizations' membership of a user. diff --git a/github/doc.go b/github/doc.go index 1fc5634d6f2..8adfdc1d49b 100644 --- a/github/doc.go +++ b/github/doc.go @@ -8,7 +8,7 @@ Package github provides a client for using the GitHub API. Usage: - import "github.com/google/go-github/v27/github" // with go modules enabled (GO111MODULE=on or outside GOPATH) + import "github.com/google/go-github/v28/github" // with go modules enabled (GO111MODULE=on or outside GOPATH) import "github.com/google/go-github/github" // with go modules disabled Construct a new GitHub client, then use the various services on the client to diff --git a/github/examples_test.go b/github/examples_test.go index e44df67efb7..a47f927ec60 100644 --- a/github/examples_test.go +++ b/github/examples_test.go @@ -12,7 +12,7 @@ import ( "fmt" "log" - "github.com/google/go-github/v27/github" + "github.com/google/go-github/v28/github" ) func ExampleClient_Markdown() { diff --git a/go.mod b/go.mod index 14b5af851f6..372bcb70ddf 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module github.com/google/go-github/v27 +module github.com/google/go-github/v28 require ( github.com/golang/protobuf v1.2.0 // indirect diff --git a/test/fields/fields.go b/test/fields/fields.go index ef0dc2a1b11..6c7eac6b886 100644 --- a/test/fields/fields.go +++ b/test/fields/fields.go @@ -25,7 +25,7 @@ import ( "reflect" "strings" - "github.com/google/go-github/v27/github" + "github.com/google/go-github/v28/github" "golang.org/x/oauth2" ) diff --git a/test/integration/activity_test.go b/test/integration/activity_test.go index a8d508a808a..0ec78056e5a 100644 --- a/test/integration/activity_test.go +++ b/test/integration/activity_test.go @@ -11,7 +11,7 @@ import ( "context" "testing" - "github.com/google/go-github/v27/github" + "github.com/google/go-github/v28/github" ) const ( diff --git a/test/integration/authorizations_test.go b/test/integration/authorizations_test.go index ed6e39df829..f6f065d3692 100644 --- a/test/integration/authorizations_test.go +++ b/test/integration/authorizations_test.go @@ -16,7 +16,7 @@ import ( "testing" "time" - "github.com/google/go-github/v27/github" + "github.com/google/go-github/v28/github" ) const msgEnvMissing = "Skipping test because the required environment variable (%v) is not present." diff --git a/test/integration/github_test.go b/test/integration/github_test.go index d4f66c2e2c3..e68a56c44cf 100644 --- a/test/integration/github_test.go +++ b/test/integration/github_test.go @@ -14,7 +14,7 @@ import ( "net/http" "os" - "github.com/google/go-github/v27/github" + "github.com/google/go-github/v28/github" "golang.org/x/oauth2" ) diff --git a/test/integration/repos_test.go b/test/integration/repos_test.go index d98c62f8f40..c722fabdf3e 100644 --- a/test/integration/repos_test.go +++ b/test/integration/repos_test.go @@ -13,7 +13,7 @@ import ( "reflect" "testing" - "github.com/google/go-github/v27/github" + "github.com/google/go-github/v28/github" ) func TestRepositories_CRUD(t *testing.T) { diff --git a/test/integration/users_test.go b/test/integration/users_test.go index e30b84c6e3d..3d587b694a6 100644 --- a/test/integration/users_test.go +++ b/test/integration/users_test.go @@ -13,7 +13,7 @@ import ( "math/rand" "testing" - "github.com/google/go-github/v27/github" + "github.com/google/go-github/v28/github" ) func TestUsers_Get(t *testing.T) { From cc20b8df44a10cf7439649ec5a2192f06e97fe43 Mon Sep 17 00:00:00 2001 From: Glenn Lewis <6598971+gmlewis@users.noreply.github.com> Date: Fri, 23 Aug 2019 21:29:46 -0400 Subject: [PATCH 0037/1468] Update AUTHORS with recent contributors --- AUTHORS | 2 ++ 1 file changed, 2 insertions(+) diff --git a/AUTHORS b/AUTHORS index d38236ed45f..fa0f1abc935 100644 --- a/AUTHORS +++ b/AUTHORS @@ -133,6 +133,7 @@ jpbelanger-mtl Juan Basso Julien Garcia Gonzalez Julien Rostand +Junya Kono Justin Abrahms Jusung Lee jzhoucliqr @@ -228,6 +229,7 @@ SoundCloud, Ltd. Sridhar Mocherla SriVignessh Pss Stian Eikeland +Szymon Kodrebski Tasya Aditya Rukmana Thomas Bruyelle Timothée Peignier From 2e90302801c870f17b6152327d9b9a03c8eca0e2 Mon Sep 17 00:00:00 2001 From: Carlos Tadeu Panato Junior Date: Sat, 31 Aug 2019 01:37:48 +0200 Subject: [PATCH 0038/1468] Add missing fields to PullRequest: locked and rebaseable (#1269) Fixes #1264. --- github/github-accessors.go | 16 ++++++++++++++++ github/github-stringify_test.go | 4 +++- github/pulls.go | 2 ++ 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/github/github-accessors.go b/github/github-accessors.go index 03fd93f927a..02112173d33 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -7644,6 +7644,14 @@ func (p *PullRequest) GetLinks() *PRLinks { return p.Links } +// GetLocked returns the Locked field if it's non-nil, zero value otherwise. +func (p *PullRequest) GetLocked() bool { + if p == nil || p.Locked == nil { + return false + } + return *p.Locked +} + // GetMaintainerCanModify returns the MaintainerCanModify field if it's non-nil, zero value otherwise. func (p *PullRequest) GetMaintainerCanModify() bool { if p == nil || p.MaintainerCanModify == nil { @@ -7732,6 +7740,14 @@ func (p *PullRequest) GetPatchURL() string { return *p.PatchURL } +// GetRebaseable returns the Rebaseable field if it's non-nil, zero value otherwise. +func (p *PullRequest) GetRebaseable() bool { + if p == nil || p.Rebaseable == nil { + return false + } + return *p.Rebaseable +} + // GetReviewComments returns the ReviewComments field if it's non-nil, zero value otherwise. func (p *PullRequest) GetReviewComments() int { if p == nil || p.ReviewComments == nil { diff --git a/github/github-stringify_test.go b/github/github-stringify_test.go index 2e7b285ea0e..22e1aafb906 100644 --- a/github/github-stringify_test.go +++ b/github/github-stringify_test.go @@ -899,6 +899,7 @@ func TestPullRequest_String(t *testing.T) { ID: Int64(0), Number: Int(0), State: String(""), + Locked: Bool(false), Title: String(""), Body: String(""), User: &User{}, @@ -908,6 +909,7 @@ func TestPullRequest_String(t *testing.T) { MergeableState: String(""), MergedBy: &User{}, MergeCommitSHA: String(""), + Rebaseable: Bool(false), Comments: Int(0), Commits: Int(0), Additions: Int(0), @@ -934,7 +936,7 @@ func TestPullRequest_String(t *testing.T) { Base: &PullRequestBranch{}, ActiveLockReason: String(""), } - want := `github.PullRequest{ID:0, Number:0, State:"", Title:"", Body:"", User:github.User{}, Draft:false, Merged:false, Mergeable:false, MergeableState:"", MergedBy:github.User{}, MergeCommitSHA:"", Comments:0, Commits:0, Additions:0, Deletions:0, ChangedFiles:0, URL:"", HTMLURL:"", IssueURL:"", StatusesURL:"", DiffURL:"", PatchURL:"", CommitsURL:"", CommentsURL:"", ReviewCommentsURL:"", ReviewCommentURL:"", ReviewComments:0, Assignee:github.User{}, Milestone:github.Milestone{}, MaintainerCanModify:false, AuthorAssociation:"", NodeID:"", Links:github.PRLinks{}, Head:github.PullRequestBranch{}, Base:github.PullRequestBranch{}, ActiveLockReason:""}` + want := `github.PullRequest{ID:0, Number:0, State:"", Locked:false, Title:"", Body:"", User:github.User{}, Draft:false, Merged:false, Mergeable:false, MergeableState:"", MergedBy:github.User{}, MergeCommitSHA:"", Rebaseable:false, Comments:0, Commits:0, Additions:0, Deletions:0, ChangedFiles:0, URL:"", HTMLURL:"", IssueURL:"", StatusesURL:"", DiffURL:"", PatchURL:"", CommitsURL:"", CommentsURL:"", ReviewCommentsURL:"", ReviewCommentURL:"", ReviewComments:0, Assignee:github.User{}, Milestone:github.Milestone{}, MaintainerCanModify:false, AuthorAssociation:"", NodeID:"", Links:github.PRLinks{}, Head:github.PullRequestBranch{}, Base:github.PullRequestBranch{}, ActiveLockReason:""}` if got := v.String(); got != want { t.Errorf("PullRequest.String = %v, want %v", got, want) } diff --git a/github/pulls.go b/github/pulls.go index a06f97bcfd6..e022692d42f 100644 --- a/github/pulls.go +++ b/github/pulls.go @@ -24,6 +24,7 @@ type PullRequest struct { ID *int64 `json:"id,omitempty"` Number *int `json:"number,omitempty"` State *string `json:"state,omitempty"` + Locked *bool `json:"locked,omitempty"` Title *string `json:"title,omitempty"` Body *string `json:"body,omitempty"` CreatedAt *time.Time `json:"created_at,omitempty"` @@ -38,6 +39,7 @@ type PullRequest struct { MergeableState *string `json:"mergeable_state,omitempty"` MergedBy *User `json:"merged_by,omitempty"` MergeCommitSHA *string `json:"merge_commit_sha,omitempty"` + Rebaseable *bool `json:"rebaseable,omitempty"` Comments *int `json:"comments,omitempty"` Commits *int `json:"commits,omitempty"` Additions *int `json:"additions,omitempty"` From 8bb91d67e040bf62e199089cc0ec2d4ece3e56d8 Mon Sep 17 00:00:00 2001 From: Glenn Lewis <6598971+gmlewis@users.noreply.github.com> Date: Sat, 7 Sep 2019 16:14:32 -0400 Subject: [PATCH 0039/1468] Support go1.13 (#1279) Closes #1273. --- .travis.yml | 3 ++- go.mod | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index a72785e3c63..794d9d91948 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,7 +2,8 @@ language: go go: - "1.x" - - "1.11.x" + - "1.12.x" + - "1.13.x" - master matrix: diff --git a/go.mod b/go.mod index 372bcb70ddf..f6198d3c95c 100644 --- a/go.mod +++ b/go.mod @@ -9,3 +9,5 @@ require ( golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6 // indirect google.golang.org/appengine v1.1.0 ) + +go 1.13 From 6de976c8cebd78576edefd295528a12551693c14 Mon Sep 17 00:00:00 2001 From: Glenn Lewis <6598971+gmlewis@users.noreply.github.com> Date: Sat, 7 Sep 2019 16:25:43 -0400 Subject: [PATCH 0040/1468] Update .travis.yml --- .travis.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 794d9d91948..b1eff617acc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,7 +3,6 @@ language: go go: - "1.x" - "1.12.x" - - "1.13.x" - master matrix: From eaf0d7dfd98f87e7c18ecae92c0ee7d5437916be Mon Sep 17 00:00:00 2001 From: Dave Protasowski Date: Sat, 7 Sep 2019 16:36:08 -0400 Subject: [PATCH 0041/1468] Update git_refs.go (#1240) --- github/git_refs.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/github/git_refs.go b/github/git_refs.go index fe16880e7b0..b51bcbf1deb 100644 --- a/github/git_refs.go +++ b/github/git_refs.go @@ -69,7 +69,7 @@ func (s *GitService) GetRef(ctx context.Context, owner string, repo string, ref if _, ok := err.(*json.UnmarshalTypeError); ok { // Multiple refs, means there wasn't an exact match. return nil, resp, errors.New("multiple matches found for this ref") - } else if resp.StatusCode == 404 { + } else if _, ok := err.(*ErrorResponse); ok && resp.StatusCode == 404 { // No ref, there was no match for the ref return nil, resp, errors.New("no match found for this ref") } else if err != nil { From 9686ff0746200cf521ce225525b421e13b4eac1a Mon Sep 17 00:00:00 2001 From: Michael Cristina Date: Sat, 7 Sep 2019 15:40:37 -0500 Subject: [PATCH 0042/1468] Add start and end column to Annotation (#1241) --- github/checks.go | 2 ++ github/checks_test.go | 6 +++++- github/github-accessors.go | 16 ++++++++++++++++ 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/github/checks.go b/github/checks.go index 342915085e4..0c88cbb58aa 100644 --- a/github/checks.go +++ b/github/checks.go @@ -54,6 +54,8 @@ type CheckRunAnnotation struct { BlobHRef *string `json:"blob_href,omitempty"` StartLine *int `json:"start_line,omitempty"` EndLine *int `json:"end_line,omitempty"` + StartColumn *int `json:"start_column,omitempty"` + EndColumn *int `json:"end_column,omitempty"` AnnotationLevel *string `json:"annotation_level,omitempty"` Message *string `json:"message,omitempty"` Title *string `json:"title,omitempty"` diff --git a/github/checks_test.go b/github/checks_test.go index 0bdc09651d2..13f5a2ac9c7 100644 --- a/github/checks_test.go +++ b/github/checks_test.go @@ -151,6 +151,8 @@ func TestChecksService_ListCheckRunAnnotations(t *testing.T) { "blob_href": "https://github.com/octocat/Hello-World/blob/837db83be4137ca555d9a5598d0a1ea2987ecfee/README.md", "start_line": 2, "end_line": 2, + "start_column": 1, + "end_column": 5, "annotation_level": "warning", "message": "Check your spelling for 'banaas'.", "title": "Spell check", @@ -168,10 +170,12 @@ func TestChecksService_ListCheckRunAnnotations(t *testing.T) { BlobHRef: String("https://github.com/octocat/Hello-World/blob/837db83be4137ca555d9a5598d0a1ea2987ecfee/README.md"), StartLine: Int(2), EndLine: Int(2), + StartColumn: Int(1), + EndColumn: Int(5), AnnotationLevel: String("warning"), Message: String("Check your spelling for 'banaas'."), - RawDetails: String("Do you mean 'bananas' or 'banana'?"), Title: String("Spell check"), + RawDetails: String("Do you mean 'bananas' or 'banana'?"), }} if !reflect.DeepEqual(checkRunAnnotations, want) { diff --git a/github/github-accessors.go b/github/github-accessors.go index 02112173d33..4873d98472f 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -644,6 +644,14 @@ func (c *CheckRunAnnotation) GetBlobHRef() string { return *c.BlobHRef } +// GetEndColumn returns the EndColumn field if it's non-nil, zero value otherwise. +func (c *CheckRunAnnotation) GetEndColumn() int { + if c == nil || c.EndColumn == nil { + return 0 + } + return *c.EndColumn +} + // GetEndLine returns the EndLine field if it's non-nil, zero value otherwise. func (c *CheckRunAnnotation) GetEndLine() int { if c == nil || c.EndLine == nil { @@ -676,6 +684,14 @@ func (c *CheckRunAnnotation) GetRawDetails() string { return *c.RawDetails } +// GetStartColumn returns the StartColumn field if it's non-nil, zero value otherwise. +func (c *CheckRunAnnotation) GetStartColumn() int { + if c == nil || c.StartColumn == nil { + return 0 + } + return *c.StartColumn +} + // GetStartLine returns the StartLine field if it's non-nil, zero value otherwise. func (c *CheckRunAnnotation) GetStartLine() int { if c == nil || c.StartLine == nil { From c476c8213e8cc03dbaca2e439acd56cd4374dede Mon Sep 17 00:00:00 2001 From: Michael Cristina Date: Sat, 7 Sep 2019 18:55:57 -0500 Subject: [PATCH 0043/1468] Remove blob_href from check annotations (#1242) --- github/checks.go | 1 - github/checks_test.go | 4 ---- github/github-accessors.go | 8 -------- 3 files changed, 13 deletions(-) diff --git a/github/checks.go b/github/checks.go index 0c88cbb58aa..84f8403401f 100644 --- a/github/checks.go +++ b/github/checks.go @@ -51,7 +51,6 @@ type CheckRunOutput struct { // CheckRunAnnotation represents an annotation object for a CheckRun output. type CheckRunAnnotation struct { Path *string `json:"path,omitempty"` - BlobHRef *string `json:"blob_href,omitempty"` StartLine *int `json:"start_line,omitempty"` EndLine *int `json:"end_line,omitempty"` StartColumn *int `json:"start_column,omitempty"` diff --git a/github/checks_test.go b/github/checks_test.go index 13f5a2ac9c7..848c7e7d389 100644 --- a/github/checks_test.go +++ b/github/checks_test.go @@ -148,7 +148,6 @@ func TestChecksService_ListCheckRunAnnotations(t *testing.T) { }) fmt.Fprint(w, `[{ "path": "README.md", - "blob_href": "https://github.com/octocat/Hello-World/blob/837db83be4137ca555d9a5598d0a1ea2987ecfee/README.md", "start_line": 2, "end_line": 2, "start_column": 1, @@ -167,7 +166,6 @@ func TestChecksService_ListCheckRunAnnotations(t *testing.T) { want := []*CheckRunAnnotation{{ Path: String("README.md"), - BlobHRef: String("https://github.com/octocat/Hello-World/blob/837db83be4137ca555d9a5598d0a1ea2987ecfee/README.md"), StartLine: Int(2), EndLine: Int(2), StartColumn: Int(1), @@ -506,7 +504,6 @@ func Test_CheckRunMarshal(t *testing.T) { Annotations: []*CheckRunAnnotation{ { AnnotationLevel: String("a"), - BlobHRef: String("b"), EndLine: Int(1), Message: String("m"), Path: String("p"), @@ -598,7 +595,6 @@ func Test_CheckRunMarshal(t *testing.T) { "annotations": [ { "path": "p", - "blob_href": "b", "start_line": 1, "end_line": 1, "annotation_level": "a", diff --git a/github/github-accessors.go b/github/github-accessors.go index 4873d98472f..96b12bb1fef 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -636,14 +636,6 @@ func (c *CheckRunAnnotation) GetAnnotationLevel() string { return *c.AnnotationLevel } -// GetBlobHRef returns the BlobHRef field if it's non-nil, zero value otherwise. -func (c *CheckRunAnnotation) GetBlobHRef() string { - if c == nil || c.BlobHRef == nil { - return "" - } - return *c.BlobHRef -} - // GetEndColumn returns the EndColumn field if it's non-nil, zero value otherwise. func (c *CheckRunAnnotation) GetEndColumn() int { if c == nil || c.EndColumn == nil { From 51df1a01f93ea12e1cde997e86a94527144171ae Mon Sep 17 00:00:00 2001 From: Dmitry Savintsev Date: Sun, 8 Sep 2019 02:03:16 +0200 Subject: [PATCH 0044/1468] Fix failure in closing PRs (#1251) Fix an error in PullRequestsService.Edit when closing PRs due to 'base' field being present together with State = 'closed'. In this case the GitHub API v2.17.5 responds with error: 'Cannot change base branch of closed pull request'. Fixes #1250. --- github/pulls.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/github/pulls.go b/github/pulls.go index e022692d42f..9dc7d2db736 100644 --- a/github/pulls.go +++ b/github/pulls.go @@ -344,7 +344,10 @@ func (s *PullRequestsService) Edit(ctx context.Context, owner string, repo strin State: pull.State, MaintainerCanModify: pull.MaintainerCanModify, } - if pull.Base != nil { + // avoid updating the base branch when closing the Pull Request + // - otherwise the GitHub API server returns a "Validation Failed" error: + // "Cannot change base branch of closed pull request". + if pull.Base != nil && pull.GetState() != "closed" { update.Base = pull.Base.Ref } From 183e92fa7670fe3bf1b5680d9f80a9f065b87daf Mon Sep 17 00:00:00 2001 From: Chris Raborg Date: Sat, 7 Sep 2019 20:05:49 -0400 Subject: [PATCH 0045/1468] Add sort, direction parameters to Repositories.ListByOrg (#1258) --- github/repos.go | 8 ++++++++ github/repos_test.go | 5 ++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/github/repos.go b/github/repos.go index a380f3028cd..0ced6b96b53 100644 --- a/github/repos.go +++ b/github/repos.go @@ -201,6 +201,14 @@ type RepositoryListByOrgOptions struct { // forks, sources, member. Default is "all". Type string `url:"type,omitempty"` + // How to sort the repository list. Can be one of created, updated, pushed, + // full_name. Default is "created". + Sort string `url:"sort,omitempty"` + + // Direction in which to sort repositories. Can be one of asc or desc. + // Default when using full_name: asc; otherwise desc. + Direction string `url:"direction,omitempty"` + ListOptions } diff --git a/github/repos_test.go b/github/repos_test.go index 75ccbb0da68..a7667616a2b 100644 --- a/github/repos_test.go +++ b/github/repos_test.go @@ -147,7 +147,10 @@ func TestRepositoriesService_ListByOrg(t *testing.T) { }) ctx := context.Background() - opt := &RepositoryListByOrgOptions{"forks", ListOptions{Page: 2}} + opt := &RepositoryListByOrgOptions{ + Type: "forks", + ListOptions: ListOptions{Page: 2}, + } got, _, err := client.Repositories.ListByOrg(ctx, "o", opt) if err != nil { t.Errorf("Repositories.ListByOrg returned error: %v", err) From 85279f51b0485d71a0e58ac5181f8e668f80a44b Mon Sep 17 00:00:00 2001 From: Emory Ruscus <47612504+emoryruscus@users.noreply.github.com> Date: Sat, 7 Sep 2019 20:06:59 -0400 Subject: [PATCH 0046/1468] Fix 'Reqest' -> 'Request' (add back the 'u'). (#1262) --- github/github-accessors.go | 16 ++++++++-------- github/pulls.go | 6 +++--- github/pulls_test.go | 2 +- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/github/github-accessors.go b/github/github-accessors.go index 96b12bb1fef..f437f71ccac 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -7476,14 +7476,6 @@ func (p *PublicEvent) GetSender() *User { return p.Sender } -// GetExpectedHeadSHA returns the ExpectedHeadSHA field if it's non-nil, zero value otherwise. -func (p *PullReqestBranchUpdateOptions) GetExpectedHeadSHA() string { - if p == nil || p.ExpectedHeadSHA == nil { - return "" - } - return *p.ExpectedHeadSHA -} - // GetActiveLockReason returns the ActiveLockReason field if it's non-nil, zero value otherwise. func (p *PullRequest) GetActiveLockReason() string { if p == nil || p.ActiveLockReason == nil { @@ -7868,6 +7860,14 @@ func (p *PullRequestBranch) GetUser() *User { return p.User } +// GetExpectedHeadSHA returns the ExpectedHeadSHA field if it's non-nil, zero value otherwise. +func (p *PullRequestBranchUpdateOptions) GetExpectedHeadSHA() string { + if p == nil || p.ExpectedHeadSHA == nil { + return "" + } + return *p.ExpectedHeadSHA +} + // GetMessage returns the Message field if it's non-nil, zero value otherwise. func (p *PullRequestBranchUpdateResponse) GetMessage() string { if p == nil || p.Message == nil { diff --git a/github/pulls.go b/github/pulls.go index 9dc7d2db736..83ca9e55a0b 100644 --- a/github/pulls.go +++ b/github/pulls.go @@ -273,9 +273,9 @@ func (s *PullRequestsService) Create(ctx context.Context, owner string, repo str return p, resp, nil } -// PullReqestBranchUpdateOptions specifies the optional parameters to the +// PullRequestBranchUpdateOptions specifies the optional parameters to the // PullRequestsService.UpdateBranch method. -type PullReqestBranchUpdateOptions struct { +type PullRequestBranchUpdateOptions struct { // ExpectedHeadSHA specifies the most recent commit on the pull request's branch. // Default value is the SHA of the pull request's current HEAD ref. ExpectedHeadSHA *string `json:"expected_head_sha,omitempty"` @@ -296,7 +296,7 @@ type PullRequestBranchUpdateResponse struct { // in a successful request. // // GitHub API docs: https://developer.github.com/v3/pulls/#update-a-pull-request-branch -func (s *PullRequestsService) UpdateBranch(ctx context.Context, owner, repo string, number int, opts *PullReqestBranchUpdateOptions) (*PullRequestBranchUpdateResponse, *Response, error) { +func (s *PullRequestsService) UpdateBranch(ctx context.Context, owner, repo string, number int, opts *PullRequestBranchUpdateOptions) (*PullRequestBranchUpdateResponse, *Response, error) { u := fmt.Sprintf("repos/%v/%v/pulls/%d/update-branch", owner, repo, number) req, err := s.client.NewRequest("PUT", u, opts) diff --git a/github/pulls_test.go b/github/pulls_test.go index 09d60e3a3e4..65647d65300 100644 --- a/github/pulls_test.go +++ b/github/pulls_test.go @@ -348,7 +348,7 @@ func TestPullRequestsService_UpdateBranch(t *testing.T) { }`) }) - opts := &PullReqestBranchUpdateOptions{ + opts := &PullRequestBranchUpdateOptions{ ExpectedHeadSHA: String("s"), } From 9ee92864bda904cef6d83b83dd878efee8797bd4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francisco=20Guimar=C3=A3es?= Date: Sat, 7 Sep 2019 21:29:31 -0300 Subject: [PATCH 0047/1468] Fix BranchCommit.Protected (#1274) --- github/github-accessors.go | 4 ++-- github/repos_commits.go | 2 +- github/repos_commits_test.go | 13 +++++++++++-- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/github/github-accessors.go b/github/github-accessors.go index f437f71ccac..f471ce5ade8 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -501,9 +501,9 @@ func (b *BranchCommit) GetName() string { } // GetProtected returns the Protected field if it's non-nil, zero value otherwise. -func (b *BranchCommit) GetProtected() string { +func (b *BranchCommit) GetProtected() bool { if b == nil || b.Protected == nil { - return "" + return false } return *b.Protected } diff --git a/github/repos_commits.go b/github/repos_commits.go index 95096923432..f28ae9c6abe 100644 --- a/github/repos_commits.go +++ b/github/repos_commits.go @@ -119,7 +119,7 @@ type CommitsListOptions struct { type BranchCommit struct { Name *string `json:"name,omitempty"` Commit *Commit `json:"commit,omitempty"` - Protected *string `json:"protected,omitempty"` + Protected *bool `json:"protected,omitempty"` } // ListCommits lists the commits of a repository. diff --git a/github/repos_commits_test.go b/github/repos_commits_test.go index feed2b95d04..54a60147856 100644 --- a/github/repos_commits_test.go +++ b/github/repos_commits_test.go @@ -367,7 +367,7 @@ func TestRepositoriesService_ListBranchesHeadCommit(t *testing.T) { 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"}]`) + fmt.Fprintf(w, `[{"name": "b","commit":{"sha":"2e90302801c870f17b6152327d9b9a03c8eca0e2","url":"https://api.github.com/repos/google/go-github/commits/2e90302801c870f17b6152327d9b9a03c8eca0e2"},"protected":true}]`) }) branches, _, err := client.Repositories.ListBranchesHeadCommit(context.Background(), "o", "r", "s") @@ -375,7 +375,16 @@ func TestRepositoriesService_ListBranchesHeadCommit(t *testing.T) { t.Errorf("Repositories.ListBranchesHeadCommit returned error: %v", err) } - want := []*BranchCommit{{Name: String("b")}} + want := []*BranchCommit{ + { + Name: String("b"), + Commit: &Commit{ + SHA: String("2e90302801c870f17b6152327d9b9a03c8eca0e2"), + URL: String("https://api.github.com/repos/google/go-github/commits/2e90302801c870f17b6152327d9b9a03c8eca0e2"), + }, + Protected: Bool(true), + }, + } if !reflect.DeepEqual(branches, want) { t.Errorf("Repositories.ListBranchesHeadCommit returned %+v, want %+v", branches, want) } From 512a8219bf28c87249674b405cc367610f3b9459 Mon Sep 17 00:00:00 2001 From: Matt Gaunt Date: Mon, 9 Sep 2019 17:21:02 -0700 Subject: [PATCH 0048/1468] Add ListOptions to ListMigrations (#1278) Fixes #1277. --- github/migrations.go | 8 ++++++-- github/migrations_test.go | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/github/migrations.go b/github/migrations.go index 90cc1fae85f..ef0095e0664 100644 --- a/github/migrations.go +++ b/github/migrations.go @@ -103,9 +103,13 @@ func (s *MigrationService) StartMigration(ctx context.Context, org string, repos // ListMigrations lists the most recent migrations. // -// GitHub API docs: https://developer.github.com/v3/migration/migrations/#get-a-list-of-migrations -func (s *MigrationService) ListMigrations(ctx context.Context, org string) ([]*Migration, *Response, error) { +// GitHub API docs: https://developer.github.com/v3/migrations/orgs/#get-a-list-of-organization-migrations +func (s *MigrationService) ListMigrations(ctx context.Context, org string, opts *ListOptions) ([]*Migration, *Response, error) { u := fmt.Sprintf("orgs/%v/migrations", org) + u, err := addOptions(u, opts) + if err != nil { + return nil, nil, err + } req, err := s.client.NewRequest("GET", u, nil) if err != nil { diff --git a/github/migrations_test.go b/github/migrations_test.go index 687f89a353b..7ef6ac80e0a 100644 --- a/github/migrations_test.go +++ b/github/migrations_test.go @@ -51,7 +51,7 @@ func TestMigrationService_ListMigrations(t *testing.T) { w.Write([]byte(fmt.Sprintf("[%s]", migrationJSON))) }) - got, _, err := client.Migrations.ListMigrations(context.Background(), "o") + got, _, err := client.Migrations.ListMigrations(context.Background(), "o", &ListOptions{Page: 1, PerPage: 2}) if err != nil { t.Errorf("ListMigrations returned error: %v", err) } From e389f8689a34832ce0eeb91177a7f6e64aacacdb Mon Sep 17 00:00:00 2001 From: Shota Terashita Date: Tue, 10 Sep 2019 09:23:22 +0900 Subject: [PATCH 0049/1468] Add support for BranchListOptions (#1272) --- github/github-accessors.go | 8 ++++++++ github/repos.go | 14 +++++++++++++- github/repos_test.go | 5 ++++- 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/github/github-accessors.go b/github/github-accessors.go index f471ce5ade8..9e5a3a6bff4 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -508,6 +508,14 @@ func (b *BranchCommit) GetProtected() bool { return *b.Protected } +// GetProtected returns the Protected field if it's non-nil, zero value otherwise. +func (b *BranchListOptions) GetProtected() bool { + if b == nil || b.Protected == nil { + return false + } + return *b.Protected +} + // GetApp returns the App field. func (c *CheckRun) GetApp() *App { if c == nil { diff --git a/github/repos.go b/github/repos.go index 0ced6b96b53..37a09d5b8ab 100644 --- a/github/repos.go +++ b/github/repos.go @@ -125,6 +125,18 @@ func (r Repository) String() string { return Stringify(r) } +// BranchListOptions specifies the optional parameters to the +// RepositoriesService.ListBranches method. +type BranchListOptions struct { + // Setting to true returns only protected branches. + // When set to false, only unprotected branches are returned. + // Omitting this parameter returns all branches. + // Default: nil + Protected *bool `url:"protected,omitempty"` + + ListOptions +} + // RepositoryListOptions specifies the optional parameters to the // RepositoriesService.List method. type RepositoryListOptions struct { @@ -822,7 +834,7 @@ type SignaturesProtectedBranch struct { // ListBranches lists branches for the specified repository. // // GitHub API docs: https://developer.github.com/v3/repos/#list-branches -func (s *RepositoriesService) ListBranches(ctx context.Context, owner string, repo string, opt *ListOptions) ([]*Branch, *Response, error) { +func (s *RepositoriesService) ListBranches(ctx context.Context, owner string, repo string, opt *BranchListOptions) ([]*Branch, *Response, error) { u := fmt.Sprintf("repos/%v/%v/branches", owner, repo) u, err := addOptions(u, opt) if err != nil { diff --git a/github/repos_test.go b/github/repos_test.go index a7667616a2b..5ed6682c9fe 100644 --- a/github/repos_test.go +++ b/github/repos_test.go @@ -806,7 +806,10 @@ func TestRepositoriesService_ListBranches(t *testing.T) { fmt.Fprint(w, `[{"name":"master", "commit" : {"sha" : "a57781", "url" : "https://api.github.com/repos/o/r/commits/a57781"}}]`) }) - opt := &ListOptions{Page: 2} + opt := &BranchListOptions{ + Protected: nil, + ListOptions: ListOptions{Page: 2}, + } branches, _, err := client.Repositories.ListBranches(context.Background(), "o", "r", opt) if err != nil { t.Errorf("Repositories.ListBranches returned error: %v", err) From a01ea50f2fc0ce93dad509f31ed1b279cc07b424 Mon Sep 17 00:00:00 2001 From: Daoq Date: Wed, 18 Sep 2019 08:18:10 +0800 Subject: [PATCH 0050/1468] Add default enterprise suffix when creating an enterprise method (#958) (#1165) Fixes #958. --- github/github.go | 15 +++++++++++--- github/github_test.go | 46 +++++++++++++++++++++++++++++++++++++++---- 2 files changed, 54 insertions(+), 7 deletions(-) diff --git a/github/github.go b/github/github.go index 6ab801f2284..0580271c5eb 100644 --- a/github/github.go +++ b/github/github.go @@ -300,13 +300,16 @@ func NewClient(httpClient *http.Client) *Client { } // NewEnterpriseClient returns a new GitHub API client with provided -// base URL and upload URL (often the same URL). -// If either URL does not have a trailing slash, one is added automatically. -// If a nil httpClient is provided, a new http.Client will be used. +// base URL and upload URL (often the same URL and is your GitHub Enterprise hostname). +// If either URL does not have the suffix "/api/v3/", it will be added automatically. +// If a nil httpClient is provided, http.DefaultClient will be used. // // Note that NewEnterpriseClient is a convenience helper only; // its behavior is equivalent to using NewClient, followed by setting // the BaseURL and UploadURL fields. +// +// Another important thing is that by default, the GitHub Enterprise URL format +// should be http(s)://[hostname]/api/v3 or you will always receive the 406 status code. func NewEnterpriseClient(baseURL, uploadURL string, httpClient *http.Client) (*Client, error) { baseEndpoint, err := url.Parse(baseURL) if err != nil { @@ -315,6 +318,9 @@ func NewEnterpriseClient(baseURL, uploadURL string, httpClient *http.Client) (*C if !strings.HasSuffix(baseEndpoint.Path, "/") { baseEndpoint.Path += "/" } + if !strings.HasSuffix(baseEndpoint.Path, "/api/v3/") { + baseEndpoint.Path += "api/v3/" + } uploadEndpoint, err := url.Parse(uploadURL) if err != nil { @@ -323,6 +329,9 @@ func NewEnterpriseClient(baseURL, uploadURL string, httpClient *http.Client) (*C if !strings.HasSuffix(uploadEndpoint.Path, "/") { uploadEndpoint.Path += "/" } + if !strings.HasSuffix(uploadEndpoint.Path, "/api/v3/") { + uploadEndpoint.Path += "api/v3/" + } c := NewClient(httpClient) c.BaseURL = baseEndpoint diff --git a/github/github_test.go b/github/github_test.go index 8dd75e4d7e6..9dfac059f3f 100644 --- a/github/github_test.go +++ b/github/github_test.go @@ -180,8 +180,8 @@ func TestNewClient(t *testing.T) { } func TestNewEnterpriseClient(t *testing.T) { - baseURL := "https://custom-url/" - uploadURL := "https://custom-upload-url/" + baseURL := "https://custom-url/api/v3/" + uploadURL := "https://custom-upload-url/api/v3/" c, err := NewEnterpriseClient(baseURL, uploadURL, nil) if err != nil { t.Fatalf("NewEnterpriseClient returned unexpected error: %v", err) @@ -196,8 +196,8 @@ func TestNewEnterpriseClient(t *testing.T) { } func TestNewEnterpriseClient_addsTrailingSlashToURLs(t *testing.T) { - baseURL := "https://custom-url" - uploadURL := "https://custom-upload-url" + baseURL := "https://custom-url/api/v3" + uploadURL := "https://custom-upload-url/api/v3" formattedBaseURL := baseURL + "/" formattedUploadURL := uploadURL + "/" @@ -214,6 +214,44 @@ func TestNewEnterpriseClient_addsTrailingSlashToURLs(t *testing.T) { } } +func TestNewEnterpriseClient_addsEnterpriseSuffixToURLs(t *testing.T) { + baseURL := "https://custom-url/" + uploadURL := "https://custom-upload-url/" + formattedBaseURL := baseURL + "api/v3/" + formattedUploadURL := uploadURL + "api/v3/" + + c, err := NewEnterpriseClient(baseURL, uploadURL, nil) + if err != nil { + t.Fatalf("NewEnterpriseClient returned unexpected error: %v", err) + } + + if got, want := c.BaseURL.String(), formattedBaseURL; got != want { + t.Errorf("NewClient BaseURL is %v, want %v", got, want) + } + if got, want := c.UploadURL.String(), formattedUploadURL; got != want { + t.Errorf("NewClient UploadURL is %v, want %v", got, want) + } +} + +func TestNewEnterpriseClient_addsEnterpriseSuffixAndTrailingSlashToURLs(t *testing.T) { + baseURL := "https://custom-url" + uploadURL := "https://custom-upload-url" + formattedBaseURL := baseURL + "/api/v3/" + formattedUploadURL := uploadURL + "/api/v3/" + + c, err := NewEnterpriseClient(baseURL, uploadURL, nil) + if err != nil { + t.Fatalf("NewEnterpriseClient returned unexpected error: %v", err) + } + + if got, want := c.BaseURL.String(), formattedBaseURL; got != want { + t.Errorf("NewClient BaseURL is %v, want %v", got, want) + } + if got, want := c.UploadURL.String(), formattedUploadURL; got != want { + t.Errorf("NewClient UploadURL is %v, want %v", got, want) + } +} + // Ensure that length of Client.rateLimits is the same as number of fields in RateLimits struct. func TestClient_rateLimits(t *testing.T) { if got, want := len(Client{}.rateLimits), reflect.TypeOf(RateLimits{}).NumField(); got != want { From 740806ae9dd43b6f68f872c299eedee17bcfa717 Mon Sep 17 00:00:00 2001 From: Quang Le Hong Date: Sun, 6 Oct 2019 20:59:32 +0700 Subject: [PATCH 0051/1468] Add document for query of search functions (#1300) * Add document for search query * Add more detail of using search query --- github/search.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/github/search.go b/github/search.go index 24156f31831..13cc4c844d8 100644 --- a/github/search.go +++ b/github/search.go @@ -24,6 +24,11 @@ import ( // will search for such issues, sorting by creation date in ascending order // (i.e., oldest first). // +// If query includes multiple conditions, it MUST NOT include "+" as the condition separator. +// You have to use " " as the separator instead. +// For example, querying with "language:c++" and "leveldb", then query should be +// "language:c++ leveldb" but not "language:c+++leveldb". +// // GitHub API docs: https://developer.github.com/v3/search/ type SearchService service From a291ecb5d81071fafe9bd24508e308923dcd6451 Mon Sep 17 00:00:00 2001 From: thomaslanghorst <32587398+thomaslanghorst@users.noreply.github.com> Date: Sun, 13 Oct 2019 22:00:17 +0200 Subject: [PATCH 0052/1468] added test for JSON marshalling for Reviewers - relates to (#55) (#1309) --- github/pulls_reviews_test.go | 82 ++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) diff --git a/github/pulls_reviews_test.go b/github/pulls_reviews_test.go index 3b78bc9e8f4..25aaca1c013 100644 --- a/github/pulls_reviews_test.go +++ b/github/pulls_reviews_test.go @@ -14,6 +14,88 @@ import ( "testing" ) +func TestReviewers_marshall(t *testing.T) { + testJSONMarshal(t, &Reviewers{}, "{}") + + u := &Reviewers{ + Users: []*User{{ + Login: String("l"), + ID: Int64(1), + AvatarURL: String("a"), + GravatarID: String("g"), + Name: String("n"), + Company: String("c"), + Blog: String("b"), + Location: String("l"), + Email: String("e"), + Hireable: Bool(true), + PublicRepos: Int(1), + Followers: Int(1), + Following: Int(1), + CreatedAt: &Timestamp{referenceTime}, + URL: String("u"), + }}, + Teams: []*Team{{ + ID: Int64(1), + NodeID: String("node"), + Name: String("n"), + Description: String("d"), + URL: String("u"), + Slug: String("s"), + Permission: String("p"), + Privacy: String("priv"), + MembersCount: Int(1), + ReposCount: Int(1), + Organization: nil, + MembersURL: String("m"), + RepositoriesURL: String("r"), + Parent: nil, + LDAPDN: String("l"), + }}, + } + + want := `{ + "users" : [ + { + "login": "l", + "id": 1, + "avatar_url": "a", + "gravatar_id": "g", + "name": "n", + "company": "c", + "blog": "b", + "location": "l", + "email": "e", + "hireable": true, + "public_repos": 1, + "followers": 1, + "following": 1, + "created_at": ` + referenceTimeStr + `, + "url": "u" + } + ], + "teams" : [ + { + "id": 1, + "node_id": "node", + "name": "n", + "description": "d", + "url": "u", + "slug": "s", + "permission": "p", + "privacy": "priv", + "members_count": 1, + "repos_count": 1, + "members_url": "m", + "repositories_url": "r", + "ldap_dn": "l" + } + ] + }` + + testJSONMarshal(t, u, want) +} + func TestPullRequestsService_ListReviews(t *testing.T) { client, mux, _, teardown := setup() defer teardown() From 6b2a6456a7a093a3da8fc0f474afb4d1c71c1885 Mon Sep 17 00:00:00 2001 From: Will Norris Date: Mon, 14 Oct 2019 16:01:01 -0700 Subject: [PATCH 0053/1468] add experimental scrape package This package adds a very experimental client for accessing GitHub data via screen scraping. It is exempt from any stability promise that would otherwise be implied by the go-github version number. --- .codecov.yml | 2 + example/scrape/main.go | 61 ++++++++++++++++++++ go.mod | 7 ++- go.sum | 11 ++++ scrape/README.md | 4 ++ scrape/apps.go | 125 +++++++++++++++++++++++++++++++++++++++++ scrape/forms.go | 98 ++++++++++++++++++++++++++++++++ scrape/scrape.go | 111 ++++++++++++++++++++++++++++++++++++ 8 files changed, 416 insertions(+), 3 deletions(-) create mode 100644 example/scrape/main.go create mode 100644 scrape/README.md create mode 100644 scrape/apps.go create mode 100644 scrape/forms.go create mode 100644 scrape/scrape.go diff --git a/.codecov.yml b/.codecov.yml index 746db53608d..0f63adb3a6c 100644 --- a/.codecov.yml +++ b/.codecov.yml @@ -1,3 +1,5 @@ ignore: # ignore auto-generated code - "github/github-accessors.go" + # ignore experimental scrape package + - "scrape" diff --git a/example/scrape/main.go b/example/scrape/main.go new file mode 100644 index 00000000000..599c8502452 --- /dev/null +++ b/example/scrape/main.go @@ -0,0 +1,61 @@ +// The scrape tool demonstrates use of the github.com/google/go-github/scrape +// package to fetch data from GitHub. The tool lists whether third-party app +// restrictions are enabled for an organization, and lists information about +// OAuth apps requested for the org. +package main + +import ( + "bufio" + "flag" + "fmt" + "log" + "os" + "strings" + + "github.com/google/go-github/v28/scrape" +) + +var ( + username = flag.String("username", "", "github auth: username") + password = flag.String("password", "", "github auth: password") + otpseed = flag.String("otpseed", "", "github auth: otp seed") + org = flag.String("org", "", "github org to get data for") +) + +func main() { + flag.Parse() + + // prompt for password and otpseed in case the user didn't want to specify as flags + reader := bufio.NewReader(os.Stdin) + if *password == "" { + fmt.Print("password: ") + *password, _ = reader.ReadString('\n') + *password = strings.TrimSpace(*password) + } + if *otpseed == "" { + fmt.Print("OTP seed: ") + *otpseed, _ = reader.ReadString('\n') + *otpseed = strings.TrimSpace(*otpseed) + } + + client := scrape.NewClient() + + if err := client.Authenticate(*username, *password, *otpseed); err != nil { + log.Fatal(err) + } + + enabled, err := client.AppRestrictionsEnabled(*org) + if err != nil { + log.Fatal(err) + } + fmt.Printf("App restrictions enabled for %q: %t\n", *org, enabled) + + apps, err := client.ListOAuthApps(*org) + if err != nil { + log.Fatal(err) + } + fmt.Printf("OAuth apps for %q: \n", *org) + for _, app := range apps { + fmt.Printf("\t%+v\n", app) + } +} diff --git a/go.mod b/go.mod index f6198d3c95c..4ede5e07ba0 100644 --- a/go.mod +++ b/go.mod @@ -1,12 +1,13 @@ module github.com/google/go-github/v28 require ( - github.com/golang/protobuf v1.2.0 // indirect + github.com/PuerkitoBio/goquery v1.5.0 + github.com/golang/protobuf v1.3.2 // indirect github.com/google/go-querystring v1.0.0 + github.com/xlzd/gotp v0.0.0-20181030022105-c8557ba2c119 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 - golang.org/x/net v0.0.0-20190311183353-d8887717615a // indirect + golang.org/x/net v0.0.0-20190311183353-d8887717615a golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be - golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6 // indirect google.golang.org/appengine v1.1.0 ) diff --git a/go.sum b/go.sum index 927256d3d86..2b7de29fa32 100644 --- a/go.sum +++ b/go.sum @@ -1,9 +1,20 @@ +github.com/PuerkitoBio/goquery v1.5.0 h1:uGvmFXOA73IKluu/F84Xd1tt/z07GYm8X49XKHP7EJk= +github.com/PuerkitoBio/goquery v1.5.0/go.mod h1:qD2PgZ9lccMbQlc7eEOjaeRlFQON7xY8kdmcsrnKqMg= +github.com/andybalholm/cascadia v1.0.0 h1:hOCXnnZ5A+3eVDX8pvgl4kofXv2ELss0bKcqRySc45o= +github.com/andybalholm/cascadia v1.0.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y= github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/google/go-github v17.0.0+incompatible h1:N0LgJ1j65A7kfXrZnUDaYCs/Sf4rEjNlfyDHW9dolSY= github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= +github.com/xlzd/gotp v0.0.0-20181030022105-c8557ba2c119 h1:YyPWX3jLOtYKulBR6AScGIs74lLrJcgeKRwcbAuQOG4= +github.com/xlzd/gotp v0.0.0-20181030022105-c8557ba2c119/go.mod h1:/nuTSlK+okRfR/vnIPqR89fFKonnWPiZymN5ydRJkX8= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be h1:vEDujvNQGv4jgYKudGeI/+DAX4Jffq6hpD55MmoEvKs= diff --git a/scrape/README.md b/scrape/README.md new file mode 100644 index 00000000000..bb3c0b56c5c --- /dev/null +++ b/scrape/README.md @@ -0,0 +1,4 @@ +The scrape package provides an experimental client for accessing additional +GitHub data via screen scraping. See [GoDoc][] for details. + +[GoDoc]: https://godoc.org/github.com/google/go-github/scrape diff --git a/scrape/apps.go b/scrape/apps.go new file mode 100644 index 00000000000..6c8bc7fa791 --- /dev/null +++ b/scrape/apps.go @@ -0,0 +1,125 @@ +// Copyright 2013 The go-github AUTHORS. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// apps.go contains functions for accessing data about applications installed +// on a GitHub organization. + +package scrape + +import ( + "errors" + "fmt" + "net/http" + "strconv" + "strings" + + "github.com/PuerkitoBio/goquery" +) + +// AppRestrictionsEnabled returns whether the specified organization has +// restricted third-party application access. +func (c *Client) AppRestrictionsEnabled(org string) (bool, error) { + u := fmt.Sprintf("https://github.com/organizations/%s/settings/oauth_application_policy", org) + resp, err := c.Client.Get(u) + if err != nil { + return false, fmt.Errorf("error fetching url %q: %v", u, err) + } + if resp.StatusCode == http.StatusNotFound { + return false, fmt.Errorf("unable to fetch URL %q", u) + } + + doc, err := goquery.NewDocumentFromResponse(resp) + if err != nil { + return false, fmt.Errorf("error parsing response: %v", err) + } + + s := doc.Find(".oauth-application-whitelist svg").First() + if s.Length() == 0 { + return false, errors.New("unable to find expected markup") + } + + if s.HasClass("octicon-check") { + return true, nil + } + if s.HasClass("octicon-alert") { + return false, nil + } + + return false, errors.New("unable to find expected markup") +} + +// ListOAuthApps lists the reviewed OAuth Applications for the +// specified organization (whether approved or denied). +func (c *Client) ListOAuthApps(org string) ([]OAuthApp, error) { + u := fmt.Sprintf("https://github.com/organizations/%s/settings/oauth_application_policy", org) + resp, err := c.Client.Get(u) + if err != nil { + return nil, fmt.Errorf("error fetching url %q: %v", u, err) + } + if resp.StatusCode == http.StatusNotFound { + return nil, fmt.Errorf("unable to fetch URL %q", u) + } + + doc, err := goquery.NewDocumentFromResponse(resp) + if err != nil { + return nil, fmt.Errorf("error parsing response: %v", err) + } + + var apps []OAuthApp + doc.Find(".oauth-application-whitelist ul > li").Each(func(i int, s *goquery.Selection) { + var app OAuthApp + app.Name = s.Find(".request-info strong").First().Text() + app.Description = s.Find(".request-info .application-description").Text() + + if editURL, ok := s.Find(".request-indicator a.edit-link").Attr("href"); ok { + app.ID = intFromLastPathSegment(editURL) + } + + if r := s.Find(".request-indicator .requestor"); r.Length() > 0 { + app.State = OAuthAppRequested + app.RequestedBy = r.Text() + if editURL, ok := s.Find(".request-indicator a").Last().Attr("href"); ok { + app.ID = intFromLastPathSegment(editURL) + } + } else if r := s.Find(".request-indicator .approved-request"); r.Length() > 0 { + app.State = OAuthAppApproved + } else if r := s.Find(".request-indicator .denied-request"); r.Length() > 0 { + app.State = OAuthAppDenied + } + apps = append(apps, app) + }) + + return apps, nil +} + +func intFromLastPathSegment(s string) int { + seg := strings.Split(s, "/") + if len(seg) > 0 { + i, _ := strconv.Atoi(seg[len(seg)-1]) + return i + } + return 0 +} + +// OAuthAppReviewState indicates the current state of a requested OAuth Application. +type OAuthAppReviewState int + +const ( + // OAuthAppRequested indicates access has been requested, but not reviewed + OAuthAppRequested OAuthAppReviewState = iota + 1 + // OAuthAppApproved indicates access has been approved + OAuthAppApproved + // OAuthAppDenied indicates access has been denied + OAuthAppDenied +) + +// OAuthApp represents an OAuth application that has been reviewed for access to organization data. +type OAuthApp struct { + ID int + Name string + Description string + State OAuthAppReviewState + RequestedBy string +} diff --git a/scrape/forms.go b/scrape/forms.go new file mode 100644 index 00000000000..8b576f981e3 --- /dev/null +++ b/scrape/forms.go @@ -0,0 +1,98 @@ +// Copyright 2013 The go-github AUTHORS. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// forms.go contains logic for parsing and submitting HTML forms. None of this +// is specific to go-github in any way, and could easily be pulled out into a +// general purpose scraping library in the future. + +package scrape + +import ( + "fmt" + "net/http" + "net/url" + + "github.com/PuerkitoBio/goquery" + "golang.org/x/net/html" +) + +// Form represents the basic elements of an HTML Form. +type Form struct { + // Action is the URL where the form will be submitted + Action string + // Method is the HTTP method to use when submitting the form + Method string + // Values contains form values to be submitted + Values url.Values +} + +// ParseForms parses and returns all form elements beneath node. Form values +// include all nested input elements within the form (textarea is not currently +// supported). +// +// In the future, we might want to allow a custom selector to be passed in to +// further restrict what forms will be returned. +func ParseForms(node *html.Node) (forms []Form) { + if node == nil { + return nil + } + + doc := goquery.NewDocumentFromNode(node) + doc.Find("form").Each(func(_ int, s *goquery.Selection) { + form := Form{Values: url.Values{}} + form.Action, _ = s.Attr("action") + form.Method, _ = s.Attr("method") + + s.Find("input").Each(func(_ int, s *goquery.Selection) { + name, _ := s.Attr("name") + value, _ := s.Attr("value") + if name != "" { + form.Values.Add(name, value) + } + }) + forms = append(forms, form) + }) + + return forms +} + +// FetchAndSubmitForm will fetch the page at urlStr, then parse and submit the first form found. +// setValues will be called with the parsed form values, allowing the caller to set any custom +// form values. Form submission will always use the POST method, regardless of the value of the +// method attribute in the form. The response from submitting the parsed form is returned. +func FetchAndSubmitForm(client *http.Client, urlStr string, setValues func(url.Values)) (*http.Response, error) { + resp, err := client.Get(urlStr) + if err != nil { + return nil, fmt.Errorf("error fetching url %q: %v", urlStr, err) + } + + defer resp.Body.Close() + root, err := html.Parse(resp.Body) + if err != nil { + return nil, fmt.Errorf("error parsing response: %v", err) + } + + forms := ParseForms(root) + if len(forms) == 0 { + return nil, fmt.Errorf("no forms found at %q", urlStr) + } + form := forms[0] + + actionURL, err := url.Parse(form.Action) + if err != nil { + return nil, fmt.Errorf("error parsing form action URL %q: %v", form.Action, err) + } + actionURL = resp.Request.URL.ResolveReference(actionURL) + + // allow caller to fill out the form + setValues(form.Values) + + resp, err = client.PostForm(actionURL.String(), form.Values) + if err != nil { + return nil, fmt.Errorf("error posting form: %v", err) + } + + return resp, nil +} diff --git a/scrape/scrape.go b/scrape/scrape.go new file mode 100644 index 00000000000..7bd994db42d --- /dev/null +++ b/scrape/scrape.go @@ -0,0 +1,111 @@ +// Copyright 2013 The go-github AUTHORS. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package scrape provides a client for interacting with GitHub using screen +// scraping. +// +// This is intended to be used as a supplement to the standard go-github +// library to access data that is not currently exposed by either the official +// REST or GraphQL APIs. +// +// Because of the nature of screen scraping, this package should be treated as +// HIGHLY EXPERIMENTAL, and potentially unstable. We make no promises relating +// to compatibility or stability of the exported API. Even though this package +// is distributed as part of the go-github library, it is explicitly exempt +// from any stability promises that my be implied by the library version +// number. +package scrape + +import ( + "bytes" + "encoding/gob" + "log" + "net/http" + "net/http/cookiejar" + "net/url" + "strings" + + "github.com/xlzd/gotp" + "golang.org/x/net/publicsuffix" +) + +// Client is a GitHub scraping client. +type Client struct { + *http.Client +} + +// NewClient constructs a new Client. +func NewClient() *Client { + jar, err := cookiejar.New(&cookiejar.Options{PublicSuffixList: publicsuffix.List}) + if err != nil { + log.Fatalf("error creating cookiejar: %v", err) + } + return &Client{ + Client: &http.Client{Jar: jar}, + } +} + +// SaveCookies returns an encoded form of the github.com cookies set on this +// client. If Authenticate() has been called, this should include the +// github.com session cookie. These cookies can be loaded onto a new client by +// calling LoadCookies. +// +// GitHub session cookies are bearer tokens that are not tied to any particular +// client, so should be treated with the same sensitivity as the account +// credentials. +func (c *Client) SaveCookies() ([]byte, error) { + u, _ := url.Parse("https://github.com/") + cookies := c.Client.Jar.Cookies(u) + + var b bytes.Buffer + err := gob.NewEncoder(&b).Encode(cookies) + return b.Bytes(), err +} + +// LoadCookies loads the provided cookies for github.com. +func (c *Client) LoadCookies(v []byte) error { + var cookies []*http.Cookie + r := bytes.NewReader(v) + err := gob.NewDecoder(r).Decode(&cookies) + if err != nil { + return err + } + + u, _ := url.Parse("https://github.com/") + c.Client.Jar.SetCookies(u, cookies) + return nil +} + +// Authenticate client to GitHub with the provided username, password, and if +// two-factor auth is enabled for the account, otpseed. +// +// otpseed is the OTP Secret provided from GitHub as part of two-factor +// application enrollment. When registering the application, click the "enter +// this text code" link on the QR Code page to see the raw OTP Secret. +func (c *Client) Authenticate(username, password, otpseed string) error { + setPassword := func(values url.Values) { + values.Set("login", username) + values.Set("password", password) + } + _, err := FetchAndSubmitForm(c.Client, "https://github.com/login", setPassword) + if err != nil { + return err + } + + if otpseed == "" { + return nil + } + + setOTP := func(values url.Values) { + otp := gotp.NewDefaultTOTP(strings.ToUpper(otpseed)).Now() + values.Set("otp", otp) + } + _, err = FetchAndSubmitForm(c.Client, "https://github.com/sessions/two-factor", setOTP) + if err != nil { + return err + } + + return nil +} From 982fe2db3e34ab144728f8d99e7ba30bad5a0066 Mon Sep 17 00:00:00 2001 From: Will Norris Date: Tue, 15 Oct 2019 15:09:37 +0000 Subject: [PATCH 0054/1468] define a new go module for the scrape package --- .travis.yml | 1 + go.mod | 4 +--- go.sum | 13 ------------- {example/scrape => scrape/example}/main.go | 2 +- scrape/go.mod | 9 +++++++++ scrape/go.sum | 13 +++++++++++++ 6 files changed, 25 insertions(+), 17 deletions(-) rename {example/scrape => scrape/example}/main.go (97%) create mode 100644 scrape/go.mod create mode 100644 scrape/go.sum diff --git a/.travis.yml b/.travis.yml index b1eff617acc..5d5a597fc9b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -25,6 +25,7 @@ script: - go vet ./... - go test -v -race -coverprofile=coverage.txt -covermode=atomic ./... - go test -v -tags=integration -run=^$ ./test/integration # Check that integration test builds successfully, but don't run any of the tests (they hit live GitHub API). + - cd scrape && go test ./... # explicitly run scrape tests, since it is in a separate module after_success: - bash <(curl -s https://codecov.io/bash) diff --git a/go.mod b/go.mod index 4ede5e07ba0..23ce41ca4bb 100644 --- a/go.mod +++ b/go.mod @@ -1,12 +1,10 @@ module github.com/google/go-github/v28 require ( - github.com/PuerkitoBio/goquery v1.5.0 github.com/golang/protobuf v1.3.2 // indirect github.com/google/go-querystring v1.0.0 - github.com/xlzd/gotp v0.0.0-20181030022105-c8557ba2c119 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 - golang.org/x/net v0.0.0-20190311183353-d8887717615a + golang.org/x/net v0.0.0-20190311183353-d8887717615a // indirect golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be google.golang.org/appengine v1.1.0 ) diff --git a/go.sum b/go.sum index 2b7de29fa32..dbab13e8b82 100644 --- a/go.sum +++ b/go.sum @@ -1,26 +1,13 @@ -github.com/PuerkitoBio/goquery v1.5.0 h1:uGvmFXOA73IKluu/F84Xd1tt/z07GYm8X49XKHP7EJk= -github.com/PuerkitoBio/goquery v1.5.0/go.mod h1:qD2PgZ9lccMbQlc7eEOjaeRlFQON7xY8kdmcsrnKqMg= -github.com/andybalholm/cascadia v1.0.0 h1:hOCXnnZ5A+3eVDX8pvgl4kofXv2ELss0bKcqRySc45o= -github.com/andybalholm/cascadia v1.0.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y= -github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/google/go-github v17.0.0+incompatible h1:N0LgJ1j65A7kfXrZnUDaYCs/Sf4rEjNlfyDHW9dolSY= github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= -github.com/xlzd/gotp v0.0.0-20181030022105-c8557ba2c119 h1:YyPWX3jLOtYKulBR6AScGIs74lLrJcgeKRwcbAuQOG4= -github.com/xlzd/gotp v0.0.0-20181030022105-c8557ba2c119/go.mod h1:/nuTSlK+okRfR/vnIPqR89fFKonnWPiZymN5ydRJkX8= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be h1:vEDujvNQGv4jgYKudGeI/+DAX4Jffq6hpD55MmoEvKs= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6 h1:bjcUS9ztw9kFmmIxJInhon/0Is3p+EHBKNgquIzo1OI= -golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= diff --git a/example/scrape/main.go b/scrape/example/main.go similarity index 97% rename from example/scrape/main.go rename to scrape/example/main.go index 599c8502452..4b5b53b299a 100644 --- a/example/scrape/main.go +++ b/scrape/example/main.go @@ -12,7 +12,7 @@ import ( "os" "strings" - "github.com/google/go-github/v28/scrape" + "github.com/google/go-github/scrape" ) var ( diff --git a/scrape/go.mod b/scrape/go.mod new file mode 100644 index 00000000000..2795ea23e33 --- /dev/null +++ b/scrape/go.mod @@ -0,0 +1,9 @@ +module github.com/google/go-github/scrape + +go 1.13 + +require ( + github.com/PuerkitoBio/goquery v1.5.0 + github.com/xlzd/gotp v0.0.0-20181030022105-c8557ba2c119 + golang.org/x/net v0.0.0-20191014212845-da9a3fd4c582 +) diff --git a/scrape/go.sum b/scrape/go.sum new file mode 100644 index 00000000000..8283fc33948 --- /dev/null +++ b/scrape/go.sum @@ -0,0 +1,13 @@ +github.com/PuerkitoBio/goquery v1.5.0 h1:uGvmFXOA73IKluu/F84Xd1tt/z07GYm8X49XKHP7EJk= +github.com/PuerkitoBio/goquery v1.5.0/go.mod h1:qD2PgZ9lccMbQlc7eEOjaeRlFQON7xY8kdmcsrnKqMg= +github.com/andybalholm/cascadia v1.0.0 h1:hOCXnnZ5A+3eVDX8pvgl4kofXv2ELss0bKcqRySc45o= +github.com/andybalholm/cascadia v1.0.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y= +github.com/xlzd/gotp v0.0.0-20181030022105-c8557ba2c119 h1:YyPWX3jLOtYKulBR6AScGIs74lLrJcgeKRwcbAuQOG4= +github.com/xlzd/gotp v0.0.0-20181030022105-c8557ba2c119/go.mod h1:/nuTSlK+okRfR/vnIPqR89fFKonnWPiZymN5ydRJkX8= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20191014212845-da9a3fd4c582 h1:p9xBe/w/OzkeYVKm234g55gMdD1nSIooTir5kV11kfA= +golang.org/x/net v0.0.0-20191014212845-da9a3fd4c582/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= From 3b6d4147caaa2f411a300f7ce147d30c47bf523c Mon Sep 17 00:00:00 2001 From: Will Norris Date: Tue, 15 Oct 2019 13:26:21 -0700 Subject: [PATCH 0055/1468] scrape: add convenience Get method also extract the GitHub baseURL which will make testing easier, and allow overriding the underlying http.RoundTripper used by the client, which is needed in some environments. --- scrape/apps.go | 28 +++----------------- scrape/example/main.go | 2 +- scrape/scrape.go | 59 +++++++++++++++++++++++++++++++++++------- 3 files changed, 55 insertions(+), 34 deletions(-) diff --git a/scrape/apps.go b/scrape/apps.go index 6c8bc7fa791..cfe989621b2 100644 --- a/scrape/apps.go +++ b/scrape/apps.go @@ -10,8 +10,6 @@ package scrape import ( "errors" - "fmt" - "net/http" "strconv" "strings" @@ -21,18 +19,9 @@ import ( // AppRestrictionsEnabled returns whether the specified organization has // restricted third-party application access. func (c *Client) AppRestrictionsEnabled(org string) (bool, error) { - u := fmt.Sprintf("https://github.com/organizations/%s/settings/oauth_application_policy", org) - resp, err := c.Client.Get(u) + doc, err := c.Get("/organizations/%s/settings/oauth_application_policy", org) if err != nil { - return false, fmt.Errorf("error fetching url %q: %v", u, err) - } - if resp.StatusCode == http.StatusNotFound { - return false, fmt.Errorf("unable to fetch URL %q", u) - } - - doc, err := goquery.NewDocumentFromResponse(resp) - if err != nil { - return false, fmt.Errorf("error parsing response: %v", err) + return false, err } s := doc.Find(".oauth-application-whitelist svg").First() @@ -53,18 +42,9 @@ func (c *Client) AppRestrictionsEnabled(org string) (bool, error) { // ListOAuthApps lists the reviewed OAuth Applications for the // specified organization (whether approved or denied). func (c *Client) ListOAuthApps(org string) ([]OAuthApp, error) { - u := fmt.Sprintf("https://github.com/organizations/%s/settings/oauth_application_policy", org) - resp, err := c.Client.Get(u) - if err != nil { - return nil, fmt.Errorf("error fetching url %q: %v", u, err) - } - if resp.StatusCode == http.StatusNotFound { - return nil, fmt.Errorf("unable to fetch URL %q", u) - } - - doc, err := goquery.NewDocumentFromResponse(resp) + doc, err := c.Get("/organizations/%s/settings/oauth_application_policy", org) if err != nil { - return nil, fmt.Errorf("error parsing response: %v", err) + return nil, err } var apps []OAuthApp diff --git a/scrape/example/main.go b/scrape/example/main.go index 4b5b53b299a..a55b88eb366 100644 --- a/scrape/example/main.go +++ b/scrape/example/main.go @@ -38,7 +38,7 @@ func main() { *otpseed = strings.TrimSpace(*otpseed) } - client := scrape.NewClient() + client := scrape.NewClient(nil) if err := client.Authenticate(*username, *password, *otpseed); err != nil { log.Fatal(err) diff --git a/scrape/scrape.go b/scrape/scrape.go index 7bd994db42d..baf732e5d7d 100644 --- a/scrape/scrape.go +++ b/scrape/scrape.go @@ -21,29 +21,43 @@ package scrape import ( "bytes" "encoding/gob" + "fmt" "log" "net/http" "net/http/cookiejar" "net/url" "strings" + "github.com/PuerkitoBio/goquery" "github.com/xlzd/gotp" "golang.org/x/net/publicsuffix" ) +var defaultBaseURL = "https://github.com/" + // Client is a GitHub scraping client. type Client struct { *http.Client + + // base URL for github.com pages. Exposed primarily for testing. Also + // used for saving and restoring cookies on the Client. + baseURL *url.URL } -// NewClient constructs a new Client. -func NewClient() *Client { +// NewClient constructs a new Client. If transport is nil, a default transport is used. +func NewClient(transport http.RoundTripper) *Client { jar, err := cookiejar.New(&cookiejar.Options{PublicSuffixList: publicsuffix.List}) if err != nil { log.Fatalf("error creating cookiejar: %v", err) } + baseURL, _ := url.Parse(defaultBaseURL) + return &Client{ - Client: &http.Client{Jar: jar}, + Client: &http.Client{ + Transport: transport, + Jar: jar, + }, + baseURL: baseURL, } } @@ -56,8 +70,7 @@ func NewClient() *Client { // client, so should be treated with the same sensitivity as the account // credentials. func (c *Client) SaveCookies() ([]byte, error) { - u, _ := url.Parse("https://github.com/") - cookies := c.Client.Jar.Cookies(u) + cookies := c.Client.Jar.Cookies(c.baseURL) var b bytes.Buffer err := gob.NewEncoder(&b).Encode(cookies) @@ -73,11 +86,33 @@ func (c *Client) LoadCookies(v []byte) error { return err } - u, _ := url.Parse("https://github.com/") - c.Client.Jar.SetCookies(u, cookies) + c.Client.Jar.SetCookies(c.baseURL, cookies) return nil } +// Get fetches a urlStr (a GitHub URL relative to the client's baseURL), and +// returns the parsed response document. +func (c *Client) Get(urlStr string, a ...interface{}) (*goquery.Document, error) { + u, err := c.baseURL.Parse(fmt.Sprintf(urlStr, a...)) + if err != nil { + return nil, fmt.Errorf("error parsing URL: %q: %v", urlStr, err) + } + resp, err := c.Client.Get(u.String()) + if err != nil { + return nil, fmt.Errorf("error fetching url %q: %v", u, err) + } + if resp.StatusCode == http.StatusNotFound { + return nil, fmt.Errorf("received %v response fetching URL %q", resp.StatusCode, u) + } + + doc, err := goquery.NewDocumentFromResponse(resp) + if err != nil { + return nil, fmt.Errorf("error parsing response: %v", err) + } + + return doc, nil +} + // Authenticate client to GitHub with the provided username, password, and if // two-factor auth is enabled for the account, otpseed. // @@ -89,10 +124,13 @@ func (c *Client) Authenticate(username, password, otpseed string) error { values.Set("login", username) values.Set("password", password) } - _, err := FetchAndSubmitForm(c.Client, "https://github.com/login", setPassword) + resp, err := FetchAndSubmitForm(c.Client, "https://github.com/login", setPassword) if err != nil { return err } + if resp.StatusCode != http.StatusOK { + return fmt.Errorf("received %v response submitting login form", resp.StatusCode) + } if otpseed == "" { return nil @@ -102,10 +140,13 @@ func (c *Client) Authenticate(username, password, otpseed string) error { otp := gotp.NewDefaultTOTP(strings.ToUpper(otpseed)).Now() values.Set("otp", otp) } - _, err = FetchAndSubmitForm(c.Client, "https://github.com/sessions/two-factor", setOTP) + resp, err = FetchAndSubmitForm(c.Client, "https://github.com/sessions/two-factor", setOTP) if err != nil { return err } + if resp.StatusCode != http.StatusOK { + return fmt.Errorf("received %v response submitting otp form", resp.StatusCode) + } return nil } From 944b567545fa137d6ca44324dceb5032641fc542 Mon Sep 17 00:00:00 2001 From: Will Norris Date: Tue, 15 Oct 2019 15:15:43 -0700 Subject: [PATCH 0056/1468] scrape: add tests for initial set of functions --- scrape/apps_test.go | 86 +++++++++++++ scrape/forms_test.go | 78 ++++++++++++ scrape/go.mod | 1 + scrape/go.sum | 2 + scrape/scrape_test.go | 33 +++++ .../access-restrictions-disabled.html | 39 ++++++ .../testdata/access-restrictions-enabled.html | 117 ++++++++++++++++++ 7 files changed, 356 insertions(+) create mode 100644 scrape/apps_test.go create mode 100644 scrape/forms_test.go create mode 100644 scrape/scrape_test.go create mode 100644 scrape/testdata/access-restrictions-disabled.html create mode 100644 scrape/testdata/access-restrictions-enabled.html diff --git a/scrape/apps_test.go b/scrape/apps_test.go new file mode 100644 index 00000000000..2f8435ad197 --- /dev/null +++ b/scrape/apps_test.go @@ -0,0 +1,86 @@ +package scrape + +import ( + "net/http" + "testing" + + "github.com/google/go-cmp/cmp" +) + +func Test_AppRestrictionsEnabled(t *testing.T) { + tests := []struct { + description string + testFile string + org string + want bool + }{ + { + description: "return true for enabled orgs", + testFile: "access-restrictions-enabled.html", + want: true, + }, + { + description: "return false for disabled orgs", + testFile: "access-restrictions-disabled.html", + want: false, + }, + } + + for _, tt := range tests { + t.Run(tt.description, func(t *testing.T) { + client, mux, cleanup := setup() + defer cleanup() + + mux.HandleFunc("/organizations/o/settings/oauth_application_policy", func(w http.ResponseWriter, r *http.Request) { + copyTestFile(w, tt.testFile) + }) + + got, err := client.AppRestrictionsEnabled("o") + if err != nil { + t.Errorf("AppRestrictionsEnabled returned err: %v", err) + } + if want := tt.want; got != want { + t.Errorf("AppRestrictionsEnabled returned %t, want %t", got, want) + } + + }) + } +} + +func Test_ListOAuthApps(t *testing.T) { + client, mux, cleanup := setup() + defer cleanup() + + mux.HandleFunc("/organizations/e/settings/oauth_application_policy", func(w http.ResponseWriter, r *http.Request) { + copyTestFile(w, "access-restrictions-enabled.html") + }) + + got, err := client.ListOAuthApps("e") + if err != nil { + t.Errorf("ListOAuthApps(e) returned err: %v", err) + } + want := []OAuthApp{ + { + ID: 22222, + Name: "Coveralls", + Description: "Test coverage history and statistics.", + State: OAuthAppRequested, + RequestedBy: "willnorris", + }, + { + ID: 530107, + Name: "Google Cloud Platform", + State: OAuthAppApproved, + }, + { + ID: 231424, + Name: "GitKraken", + Description: "An intuitive, cross-platform Git client that doesn't suck, built by @axosoft and made with @nodegit & @ElectronJS.", + State: OAuthAppDenied, + }, + } + if !cmp.Equal(got, want) { + t.Errorf("ListOAuthApps(o) returned %v, want %v", got, want) + } + +} diff --git a/scrape/forms_test.go b/scrape/forms_test.go new file mode 100644 index 00000000000..fcd74b9a894 --- /dev/null +++ b/scrape/forms_test.go @@ -0,0 +1,78 @@ +package scrape + +import ( + "fmt" + "net/http" + "net/url" + "strings" + "testing" + + "github.com/google/go-cmp/cmp" + "golang.org/x/net/html" +) + +func Test_ParseForms(t *testing.T) { + tests := []struct { + description string + html string + forms []Form + }{ + {"no forms", ``, nil}, + {"empty form", `
`, []Form{{Values: url.Values{}}}}, + { + "single form with one value", + `
`, + []Form{{Action: "a", Method: "m", Values: url.Values{"n1": {"v1"}}}}, + }, + { + "two forms", + ` +
+
+ `, + []Form{ + {Action: "a1", Method: "m1", Values: url.Values{"n1": {"v1"}}}, + {Action: "a2", Method: "m2", Values: url.Values{"n2": {"v2"}}}, + }, + }, + } + + for _, tt := range tests { + t.Run(tt.description, func(t *testing.T) { + node, err := html.Parse(strings.NewReader(tt.html)) + if err != nil { + t.Errorf("error parsing html: %v", err) + } + if got, want := ParseForms(node), tt.forms; !cmp.Equal(got, want) { + t.Errorf("ParseForms(%q) returned %+v, want %+v", tt.html, got, want) + } + }) + } +} + +func Test_FetchAndSumbitForm(t *testing.T) { + client, mux, cleanup := setup() + defer cleanup() + var submitted bool + + mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { + fmt.Fprint(w, `
+ + +
`) + }) + mux.HandleFunc("/submit", func(w http.ResponseWriter, r *http.Request) { + r.ParseForm() + want := url.Values{"hidden": {"h"}, "name": {"n"}} + if got := r.Form; !cmp.Equal(got, want) { + t.Errorf("submitted form contained values %v, want %v", got, want) + } + submitted = true + }) + + setValues := func(values url.Values) { values.Set("name", "n") } + FetchAndSubmitForm(client.Client, client.baseURL.String()+"/", setValues) + if !submitted { + t.Error("form was never submitted") + } +} diff --git a/scrape/go.mod b/scrape/go.mod index 2795ea23e33..aa575d7a32e 100644 --- a/scrape/go.mod +++ b/scrape/go.mod @@ -4,6 +4,7 @@ go 1.13 require ( github.com/PuerkitoBio/goquery v1.5.0 + github.com/google/go-cmp v0.3.1 github.com/xlzd/gotp v0.0.0-20181030022105-c8557ba2c119 golang.org/x/net v0.0.0-20191014212845-da9a3fd4c582 ) diff --git a/scrape/go.sum b/scrape/go.sum index 8283fc33948..1894f0bd7f0 100644 --- a/scrape/go.sum +++ b/scrape/go.sum @@ -2,6 +2,8 @@ github.com/PuerkitoBio/goquery v1.5.0 h1:uGvmFXOA73IKluu/F84Xd1tt/z07GYm8X49XKHP github.com/PuerkitoBio/goquery v1.5.0/go.mod h1:qD2PgZ9lccMbQlc7eEOjaeRlFQON7xY8kdmcsrnKqMg= github.com/andybalholm/cascadia v1.0.0 h1:hOCXnnZ5A+3eVDX8pvgl4kofXv2ELss0bKcqRySc45o= github.com/andybalholm/cascadia v1.0.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y= +github.com/google/go-cmp v0.3.1 h1:Xye71clBPdm5HgqGwUkwhbynsUJZhDbS20FvLhQ2izg= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/xlzd/gotp v0.0.0-20181030022105-c8557ba2c119 h1:YyPWX3jLOtYKulBR6AScGIs74lLrJcgeKRwcbAuQOG4= github.com/xlzd/gotp v0.0.0-20181030022105-c8557ba2c119/go.mod h1:/nuTSlK+okRfR/vnIPqR89fFKonnWPiZymN5ydRJkX8= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= diff --git a/scrape/scrape_test.go b/scrape/scrape_test.go new file mode 100644 index 00000000000..74e867b6417 --- /dev/null +++ b/scrape/scrape_test.go @@ -0,0 +1,33 @@ +package scrape + +import ( + "io" + "net/http" + "net/http/httptest" + "net/url" + "os" +) + +// setup a test HTTP server along with a scrape.Client that is configured to +// talk to that test server. Tests should register handlers on the mux which +// provide mock responses for the GitHub pages being tested. +func setup() (client *Client, mux *http.ServeMux, cleanup func()) { + mux = http.NewServeMux() + server := httptest.NewServer(mux) + + client = NewClient(nil) + client.baseURL, _ = url.Parse(server.URL + "/") + + return client, mux, server.Close +} + +func copyTestFile(w io.Writer, filename string) error { + f, err := os.Open("testdata/" + filename) + if err != nil { + return err + } + defer f.Close() + + _, err = io.Copy(w, f) + return err +} diff --git a/scrape/testdata/access-restrictions-disabled.html b/scrape/testdata/access-restrictions-disabled.html new file mode 100644 index 00000000000..97e8133927c --- /dev/null +++ b/scrape/testdata/access-restrictions-disabled.html @@ -0,0 +1,39 @@ + + + + +
+
+ +
+ +
+ +
+ +
+

Third-party application access policy

+
+

+ Policy: No restrictions +

+

+ All applications authorized by organization members have access to google-test’s data. +

+ Setup application access restrictions +

+ + When authorized, applications can act on behalf of organization members. Your access policy determines which applications can access data in your organization. Read more about third-party access and organizations. +

+
+
+ +
+
+
+ +
+
+ + diff --git a/scrape/testdata/access-restrictions-enabled.html b/scrape/testdata/access-restrictions-enabled.html new file mode 100644 index 00000000000..39ef4b4cde2 --- /dev/null +++ b/scrape/testdata/access-restrictions-enabled.html @@ -0,0 +1,117 @@ + + + + +
+
+ + + +
+ +
+ +
+ +
+

Third-party application access policy

+
+

+ Policy: Access restricted +

+

+ Only approved applications can access data in this organization. Applications owned by google-test always have access. +

+ +
+ + + Remove restrictions + + +
+ +

Are you sure?

+
+ +
+ You’re about to remove all third-party application restrictions. Please read this carefully. +
+
+

Removing third-party application restrictions will immediately give member authorized applications access to private data in the google-test organization.

+

Please be sure you want to do this.

+
+ + +
+
+
    +
  • +
    + Approval requested by willnorris — + Review +
    + + + Coveralls Test coverage history and statistics. + +
  • +
  • + + + Approved + + + + + Google Cloud Platform + +
  • +
  • + + + Denied + + + + + GitKraken An intuitive, cross-platform Git client that doesn't suck, built by @axosoft and made with @nodegit & @ElectronJS. + +
  • +
+

+ + When authorized, applications can act on behalf of organization members. Your access policy determines which applications can access data in your organization. Read more about third-party access and organizations. +

+
+
+ +
+
+
+ +
+
+ + From d40042531e938716fb801877b99dade5e93f02f3 Mon Sep 17 00:00:00 2001 From: Will Norris Date: Tue, 15 Oct 2019 16:13:00 -0700 Subject: [PATCH 0057/1468] scrape: don't export the generic form functions there's no need for these to be part of the exported API, they're just an implementation detail. --- scrape/forms.go | 16 ++++++++-------- scrape/forms_test.go | 14 +++++++------- scrape/scrape.go | 4 ++-- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/scrape/forms.go b/scrape/forms.go index 8b576f981e3..ee559395eb6 100644 --- a/scrape/forms.go +++ b/scrape/forms.go @@ -18,8 +18,8 @@ import ( "golang.org/x/net/html" ) -// Form represents the basic elements of an HTML Form. -type Form struct { +// htmlForm represents the basic elements of an HTML Form. +type htmlForm struct { // Action is the URL where the form will be submitted Action string // Method is the HTTP method to use when submitting the form @@ -28,20 +28,20 @@ type Form struct { Values url.Values } -// ParseForms parses and returns all form elements beneath node. Form values +// parseForms parses and returns all form elements beneath node. Form values // include all nested input elements within the form (textarea is not currently // supported). // // In the future, we might want to allow a custom selector to be passed in to // further restrict what forms will be returned. -func ParseForms(node *html.Node) (forms []Form) { +func parseForms(node *html.Node) (forms []htmlForm) { if node == nil { return nil } doc := goquery.NewDocumentFromNode(node) doc.Find("form").Each(func(_ int, s *goquery.Selection) { - form := Form{Values: url.Values{}} + form := htmlForm{Values: url.Values{}} form.Action, _ = s.Attr("action") form.Method, _ = s.Attr("method") @@ -58,11 +58,11 @@ func ParseForms(node *html.Node) (forms []Form) { return forms } -// FetchAndSubmitForm will fetch the page at urlStr, then parse and submit the first form found. +// fetchAndSubmitForm will fetch the page at urlStr, then parse and submit the first form found. // setValues will be called with the parsed form values, allowing the caller to set any custom // form values. Form submission will always use the POST method, regardless of the value of the // method attribute in the form. The response from submitting the parsed form is returned. -func FetchAndSubmitForm(client *http.Client, urlStr string, setValues func(url.Values)) (*http.Response, error) { +func fetchAndSubmitForm(client *http.Client, urlStr string, setValues func(url.Values)) (*http.Response, error) { resp, err := client.Get(urlStr) if err != nil { return nil, fmt.Errorf("error fetching url %q: %v", urlStr, err) @@ -74,7 +74,7 @@ func FetchAndSubmitForm(client *http.Client, urlStr string, setValues func(url.V return nil, fmt.Errorf("error parsing response: %v", err) } - forms := ParseForms(root) + forms := parseForms(root) if len(forms) == 0 { return nil, fmt.Errorf("no forms found at %q", urlStr) } diff --git a/scrape/forms_test.go b/scrape/forms_test.go index fcd74b9a894..f45010cf9bc 100644 --- a/scrape/forms_test.go +++ b/scrape/forms_test.go @@ -15,14 +15,14 @@ func Test_ParseForms(t *testing.T) { tests := []struct { description string html string - forms []Form + forms []htmlForm }{ {"no forms", ``, nil}, - {"empty form", `
`, []Form{{Values: url.Values{}}}}, + {"empty form", `
`, []htmlForm{{Values: url.Values{}}}}, { "single form with one value", `
`, - []Form{{Action: "a", Method: "m", Values: url.Values{"n1": {"v1"}}}}, + []htmlForm{{Action: "a", Method: "m", Values: url.Values{"n1": {"v1"}}}}, }, { "two forms", @@ -30,7 +30,7 @@ func Test_ParseForms(t *testing.T) {
`, - []Form{ + []htmlForm{ {Action: "a1", Method: "m1", Values: url.Values{"n1": {"v1"}}}, {Action: "a2", Method: "m2", Values: url.Values{"n2": {"v2"}}}, }, @@ -43,8 +43,8 @@ func Test_ParseForms(t *testing.T) { if err != nil { t.Errorf("error parsing html: %v", err) } - if got, want := ParseForms(node), tt.forms; !cmp.Equal(got, want) { - t.Errorf("ParseForms(%q) returned %+v, want %+v", tt.html, got, want) + if got, want := parseForms(node), tt.forms; !cmp.Equal(got, want) { + t.Errorf("parseForms(%q) returned %+v, want %+v", tt.html, got, want) } }) } @@ -71,7 +71,7 @@ func Test_FetchAndSumbitForm(t *testing.T) { }) setValues := func(values url.Values) { values.Set("name", "n") } - FetchAndSubmitForm(client.Client, client.baseURL.String()+"/", setValues) + fetchAndSubmitForm(client.Client, client.baseURL.String()+"/", setValues) if !submitted { t.Error("form was never submitted") } diff --git a/scrape/scrape.go b/scrape/scrape.go index baf732e5d7d..a512784c9f0 100644 --- a/scrape/scrape.go +++ b/scrape/scrape.go @@ -124,7 +124,7 @@ func (c *Client) Authenticate(username, password, otpseed string) error { values.Set("login", username) values.Set("password", password) } - resp, err := FetchAndSubmitForm(c.Client, "https://github.com/login", setPassword) + resp, err := fetchAndSubmitForm(c.Client, "https://github.com/login", setPassword) if err != nil { return err } @@ -140,7 +140,7 @@ func (c *Client) Authenticate(username, password, otpseed string) error { otp := gotp.NewDefaultTOTP(strings.ToUpper(otpseed)).Now() values.Set("otp", otp) } - resp, err = FetchAndSubmitForm(c.Client, "https://github.com/sessions/two-factor", setOTP) + resp, err = fetchAndSubmitForm(c.Client, "https://github.com/sessions/two-factor", setOTP) if err != nil { return err } From b5d726b0e8bf09681c200438acb8ba1473466a72 Mon Sep 17 00:00:00 2001 From: Will Norris Date: Tue, 15 Oct 2019 16:15:07 -0700 Subject: [PATCH 0058/1468] scrape: don't export client.get (for now) --- scrape/apps.go | 4 ++-- scrape/scrape.go | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/scrape/apps.go b/scrape/apps.go index cfe989621b2..0c52bad834d 100644 --- a/scrape/apps.go +++ b/scrape/apps.go @@ -19,7 +19,7 @@ import ( // AppRestrictionsEnabled returns whether the specified organization has // restricted third-party application access. func (c *Client) AppRestrictionsEnabled(org string) (bool, error) { - doc, err := c.Get("/organizations/%s/settings/oauth_application_policy", org) + doc, err := c.get("/organizations/%s/settings/oauth_application_policy", org) if err != nil { return false, err } @@ -42,7 +42,7 @@ func (c *Client) AppRestrictionsEnabled(org string) (bool, error) { // ListOAuthApps lists the reviewed OAuth Applications for the // specified organization (whether approved or denied). func (c *Client) ListOAuthApps(org string) ([]OAuthApp, error) { - doc, err := c.Get("/organizations/%s/settings/oauth_application_policy", org) + doc, err := c.get("/organizations/%s/settings/oauth_application_policy", org) if err != nil { return nil, err } diff --git a/scrape/scrape.go b/scrape/scrape.go index a512784c9f0..aa2b86e45ad 100644 --- a/scrape/scrape.go +++ b/scrape/scrape.go @@ -90,9 +90,9 @@ func (c *Client) LoadCookies(v []byte) error { return nil } -// Get fetches a urlStr (a GitHub URL relative to the client's baseURL), and +// get fetches a urlStr (a GitHub URL relative to the client's baseURL), and // returns the parsed response document. -func (c *Client) Get(urlStr string, a ...interface{}) (*goquery.Document, error) { +func (c *Client) get(urlStr string, a ...interface{}) (*goquery.Document, error) { u, err := c.baseURL.Parse(fmt.Sprintf(urlStr, a...)) if err != nil { return nil, fmt.Errorf("error parsing URL: %q: %v", urlStr, err) From f6d1c2f4e7399ed441685e1c6e49caa2de034a70 Mon Sep 17 00:00:00 2001 From: Will Norris Date: Tue, 15 Oct 2019 16:26:28 -0700 Subject: [PATCH 0059/1468] scrape: expand readme docs --- scrape/README.md | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/scrape/README.md b/scrape/README.md index bb3c0b56c5c..c01b3e990a6 100644 --- a/scrape/README.md +++ b/scrape/README.md @@ -1,4 +1,26 @@ +[![GoDoc](https://godoc.org/github.com/google/go-github/github/scrape?status.svg)](https://godoc.org/github.com/google/go-github/github/scrape) + The scrape package provides an experimental client for accessing additional -GitHub data via screen scraping. See [GoDoc][] for details. +GitHub data via screen scraping. It is designed to be a client of last resort +for data that cannot be retrieved via the REST or GraphQL APIs. + +# What should be added here + +**Add only what you need.** Whereas the main go-github library attempts to +implement the entire GitHub REST API, there is little point in trying to do that +here. Certainly, feel free to contribution patches to get data you actually +need, but I'd rather not try and provide exhaustive coverage of all GitHub data +here. + +**Add only what can't be accessed elsewhere.** If the data can be retrieved +through the REST or GraphQL API, use the appropriate libraries for that. + +**Prefer read-only access.** For now, I'm only focusing on reading data. It +might be that writing works fine as well, but it is of course much riskier. + +# How to add methods -[GoDoc]: https://godoc.org/github.com/google/go-github/scrape +See [apps.go](apps.go) for examples of methods that access data. Basically, +fetch the contents of the page using `client.get`, and then use goquery to dig +into the markup on the page. Prefer selectors that grab semantic ID or class +names, as they are more likely to be stable. From 34c5b5692fd774458d103a8690699bc239a66c11 Mon Sep 17 00:00:00 2001 From: Will Norris Date: Tue, 15 Oct 2019 18:23:22 -0700 Subject: [PATCH 0060/1468] scrape: define testdata directory in package var this allows overriding the directory in some environments --- scrape/scrape_test.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/scrape/scrape_test.go b/scrape/scrape_test.go index 74e867b6417..bb6965b4e40 100644 --- a/scrape/scrape_test.go +++ b/scrape/scrape_test.go @@ -21,8 +21,10 @@ func setup() (client *Client, mux *http.ServeMux, cleanup func()) { return client, mux, server.Close } +var testDataDir = "testdata/" + func copyTestFile(w io.Writer, filename string) error { - f, err := os.Open("testdata/" + filename) + f, err := os.Open(testDataDir + filename) if err != nil { return err } From 4d3a39f251d44cb4960bb6d0f62fbb3e417de888 Mon Sep 17 00:00:00 2001 From: Will Norris Date: Tue, 15 Oct 2019 19:11:19 -0700 Subject: [PATCH 0061/1468] scrape: move example into a named directory --- scrape/example/{ => scrape}/main.go | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename scrape/example/{ => scrape}/main.go (100%) diff --git a/scrape/example/main.go b/scrape/example/scrape/main.go similarity index 100% rename from scrape/example/main.go rename to scrape/example/scrape/main.go From 44d2127eaf49d830100908b6a9451f35d9fbca63 Mon Sep 17 00:00:00 2001 From: Will Norris Date: Tue, 15 Oct 2019 19:14:22 -0700 Subject: [PATCH 0062/1468] scrape: fix godoc link in README also revert change to extract test data directory into variable; it turns out that wasn't necessary. --- scrape/README.md | 2 +- scrape/scrape_test.go | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/scrape/README.md b/scrape/README.md index c01b3e990a6..8785f4f8056 100644 --- a/scrape/README.md +++ b/scrape/README.md @@ -1,4 +1,4 @@ -[![GoDoc](https://godoc.org/github.com/google/go-github/github/scrape?status.svg)](https://godoc.org/github.com/google/go-github/github/scrape) +[![GoDoc](https://godoc.org/github.com/google/go-github/scrape?status.svg)](https://godoc.org/github.com/google/go-github/github/scrape) The scrape package provides an experimental client for accessing additional GitHub data via screen scraping. It is designed to be a client of last resort diff --git a/scrape/scrape_test.go b/scrape/scrape_test.go index bb6965b4e40..74e867b6417 100644 --- a/scrape/scrape_test.go +++ b/scrape/scrape_test.go @@ -21,10 +21,8 @@ func setup() (client *Client, mux *http.ServeMux, cleanup func()) { return client, mux, server.Close } -var testDataDir = "testdata/" - func copyTestFile(w io.Writer, filename string) error { - f, err := os.Open(testDataDir + filename) + f, err := os.Open("testdata/" + filename) if err != nil { return err } From 7fa3d9ab09b888759ea099ec74a1b5b0a2a89a62 Mon Sep 17 00:00:00 2001 From: Will Norris Date: Tue, 15 Oct 2019 19:16:14 -0700 Subject: [PATCH 0063/1468] scrape: fix godoc link in README --- scrape/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scrape/README.md b/scrape/README.md index 8785f4f8056..5d6180da051 100644 --- a/scrape/README.md +++ b/scrape/README.md @@ -1,4 +1,4 @@ -[![GoDoc](https://godoc.org/github.com/google/go-github/scrape?status.svg)](https://godoc.org/github.com/google/go-github/github/scrape) +[![GoDoc](https://godoc.org/github.com/google/go-github/scrape?status.svg)](https://godoc.org/github.com/google/go-github/scrape) The scrape package provides an experimental client for accessing additional GitHub data via screen scraping. It is designed to be a client of last resort From 0fad29b185370011778ede8fc39a5462f844da65 Mon Sep 17 00:00:00 2001 From: Will Norris Date: Wed, 16 Oct 2019 08:24:00 -0700 Subject: [PATCH 0064/1468] scrape: use goquery.NewDocumentFromReader goquery.NewDocumentFromResponse is deprecated --- scrape/scrape.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scrape/scrape.go b/scrape/scrape.go index aa2b86e45ad..c3be9af106e 100644 --- a/scrape/scrape.go +++ b/scrape/scrape.go @@ -105,7 +105,8 @@ func (c *Client) get(urlStr string, a ...interface{}) (*goquery.Document, error) return nil, fmt.Errorf("received %v response fetching URL %q", resp.StatusCode, u) } - doc, err := goquery.NewDocumentFromResponse(resp) + defer resp.Body.Close() + doc, err := goquery.NewDocumentFromReader(resp.Body) if err != nil { return nil, fmt.Errorf("error parsing response: %v", err) } From 2a36cb4db36a9bb4922db2b6a6dd36bb50cb23df Mon Sep 17 00:00:00 2001 From: SriVignessh Pss Date: Fri, 25 Oct 2019 16:34:45 -0700 Subject: [PATCH 0065/1468] Support List GitHub App installations for organization (#1320) --- github/github-accessors.go | 8 ++++++ github/orgs.go | 34 ++++++++++++++++++++++ github/orgs_test.go | 58 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 100 insertions(+) diff --git a/github/github-accessors.go b/github/github-accessors.go index 9e5a3a6bff4..77942e74f3f 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -6380,6 +6380,14 @@ func (o *OrganizationEvent) GetSender() *User { return o.Sender } +// GetTotalCount returns the TotalCount field if it's non-nil, zero value otherwise. +func (o *OrganizationInstallations) GetTotalCount() int { + if o == nil || o.TotalCount == nil { + return 0 + } + return *o.TotalCount +} + // GetAction returns the Action field if it's non-nil, zero value otherwise. func (o *OrgBlockEvent) GetAction() string { if o == nil || o.Action == nil { diff --git a/github/orgs.go b/github/orgs.go index e1aa20db0b1..8fffdc752f1 100644 --- a/github/orgs.go +++ b/github/orgs.go @@ -70,6 +70,12 @@ type Organization struct { ReposURL *string `json:"repos_url,omitempty"` } +// OrganizationInstallations represents GitHub app installations for an organization. +type OrganizationInstallations struct { + TotalCount *int `json:"total_count,omitempty"` + Installations []*Installation `json:"installations,omitempty"` +} + func (o Organization) String() string { return Stringify(o) } @@ -213,3 +219,31 @@ func (s *OrganizationsService) Edit(ctx context.Context, name string, org *Organ return o, resp, nil } + +// List installations for an organization. +// +// GitHub API docs: https://developer.github.com/v3/orgs/#list-installations-for-an-organization +func (s *OrganizationsService) ListInstallations(ctx context.Context, org string, opt *ListOptions) (*OrganizationInstallations, *Response, error) { + u := fmt.Sprintf("orgs/%v/installations", org) + + 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. + req.Header.Set("Accept", mediaTypeIntegrationPreview) + + result := new(OrganizationInstallations) + resp, err := s.client.Do(ctx, req, result) + if err != nil { + return nil, resp, err + } + + return result, resp, nil +} diff --git a/github/orgs_test.go b/github/orgs_test.go index 3b938fc993b..9383bf11c3e 100644 --- a/github/orgs_test.go +++ b/github/orgs_test.go @@ -172,3 +172,61 @@ func TestOrganizationsService_Edit_invalidOrg(t *testing.T) { _, _, err := client.Organizations.Edit(context.Background(), "%", nil) testURLParseError(t, err) } + +func TestOrganizationsService_ListInstallations(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/orgs/o/installations", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + testHeader(t, r, "Accept", mediaTypeIntegrationPreview) + fmt.Fprint(w, `{"total_count": 1, "installations": [{ "id": 1, "app_id": 5}]}`) + }) + + apps, _, err := client.Organizations.ListInstallations(context.Background(), "o", nil) + if err != nil { + t.Errorf("Organizations.ListInstallations returned error: %v", err) + } + + want := &OrganizationInstallations{TotalCount: Int(1), Installations: []*Installation{{ID: Int64(1), AppID: Int64(5)}}} + if !reflect.DeepEqual(apps, want) { + t.Errorf("Organizations.ListInstallations returned %+v, want %+v", apps, want) + } +} + +func TestOrganizationsService_ListInstallations_invalidOrg(t *testing.T) { + client, _, _, teardown := setup() + defer teardown() + + _, _, err := client.Organizations.ListInstallations(context.Background(), "%", nil) + testURLParseError(t, err) + +} + +func TestOrganizationsService_ListInstallations_withListOptions(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/orgs/o/installations", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + testHeader(t, r, "Accept", mediaTypeIntegrationPreview) + testFormValues(t, r, values{"page": "2"}) + fmt.Fprint(w, `{"total_count": 2, "installations": [{ "id": 2, "app_id": 10}]}`) + }) + + apps, _, err := client.Organizations.ListInstallations(context.Background(), "o", &ListOptions{Page: 2}) + if err != nil { + t.Errorf("Organizations.ListInstallations returned error: %v", err) + } + + want := &OrganizationInstallations{TotalCount: Int(2), Installations: []*Installation{{ID: Int64(2), AppID: Int64(10)}}} + if !reflect.DeepEqual(apps, want) { + t.Errorf("Organizations.ListInstallations returned %+v, want %+v", apps, want) + } + + // Test ListOptions failure + _, _, err = client.Organizations.ListInstallations(context.Background(), "%", &ListOptions{}) + if err == nil { + t.Error("Organizations.ListInstallations returned error: nil") + } +} From 126ad634ea71baa1e2f4dddcb4ed708d60e7cbf0 Mon Sep 17 00:00:00 2001 From: oleorhagen Date: Tue, 29 Oct 2019 01:08:22 +0100 Subject: [PATCH 0066/1468] Fix spelling (#1323) --- github/event_types.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/github/event_types.go b/github/event_types.go index d3e2123547d..049751aa4f9 100644 --- a/github/event_types.go +++ b/github/event_types.go @@ -738,7 +738,7 @@ type PushEventRepoOwner struct { } // ReleaseEvent is triggered when a release is published, unpublished, created, -// edited, deleted, or prerelased. +// edited, deleted, or prereleased. // The Webhook event name is "release". // // GitHub API docs: https://developer.github.com/v3/activity/events/types/#releaseevent From e9c3f8894b82c69644e0b645aebf9f0571c4c4f3 Mon Sep 17 00:00:00 2001 From: thomaslanghorst <32587398+thomaslanghorst@users.noreply.github.com> Date: Tue, 29 Oct 2019 14:33:15 +0100 Subject: [PATCH 0067/1468] Add test for JSON marshaling for Reaction and Reactions - relates to (#55) (#1324) --- github/reactions_test.go | 47 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/github/reactions_test.go b/github/reactions_test.go index e1baec3f92d..ef1660d9af7 100644 --- a/github/reactions_test.go +++ b/github/reactions_test.go @@ -12,6 +12,53 @@ import ( "testing" ) +func TestReaction_Marshal(t *testing.T) { + testJSONMarshal(t, &Reaction{}, "{}") + + r := &Reaction{ + ID: Int64(1), + User: nil, + NodeID: String("n"), + Content: String("+1"), + } + + want := `{ + "id": 1, + "node_id": "n", + "content": "+1" + }` + + testJSONMarshal(t, r, want) +} + +func TestReactions_Marshal(t *testing.T) { + testJSONMarshal(t, &Reactions{}, "{}") + + r := &Reactions{ + TotalCount: Int(1), + PlusOne: Int(1), + MinusOne: Int(1), + Laugh: Int(1), + Confused: Int(1), + Heart: Int(1), + Hooray: Int(1), + URL: String("u"), + } + + want := `{ + "total_count": 1, + "+1": 1, + "-1": 1, + "laugh": 1, + "confused": 1, + "heart": 1, + "hooray": 1, + "url": "u" + }` + + testJSONMarshal(t, r, want) +} + func TestReactionsService_ListCommentReactions(t *testing.T) { client, mux, _, teardown := setup() defer teardown() From c020c3ffe3ed6b1a9e95430384f4e8e3005c43bf Mon Sep 17 00:00:00 2001 From: Will Norris Date: Mon, 4 Nov 2019 09:50:18 +0000 Subject: [PATCH 0068/1468] fix golint warnings - update docs to match exported func names - no need to export func in example code --- example/simple/main.go | 4 ++-- github/apps.go | 2 +- github/orgs.go | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/example/simple/main.go b/example/simple/main.go index b10be06b9eb..8bab9603635 100644 --- a/example/simple/main.go +++ b/example/simple/main.go @@ -17,7 +17,7 @@ import ( // Fetch all the public organizations' membership of a user. // -func FetchOrganizations(username string) ([]*github.Organization, error) { +func fetchOrganizations(username string) ([]*github.Organization, error) { client := github.NewClient(nil) orgs, _, err := client.Organizations.List(context.Background(), username, nil) return orgs, err @@ -28,7 +28,7 @@ func main() { fmt.Print("Enter GitHub username: ") fmt.Scanf("%s", &username) - organizations, err := FetchOrganizations(username) + organizations, err := fetchOrganizations(username) if err != nil { fmt.Printf("Error: %v\n", err) return diff --git a/github/apps.go b/github/apps.go index 5041e801280..a546a70cdae 100644 --- a/github/apps.go +++ b/github/apps.go @@ -227,7 +227,7 @@ func (s *AppsService) CreateInstallationToken(ctx context.Context, id int64, opt return t, resp, nil } -// Create a new attachment on user comment containing a url. +// CreateAttachment creates a new attachment on user comment containing a url. // // GitHub API docs: https://developer.github.com/v3/apps/#create-a-content-attachment func (s *AppsService) CreateAttachment(ctx context.Context, contentReferenceID int64, title, body string) (*Attachment, *Response, error) { diff --git a/github/orgs.go b/github/orgs.go index 8fffdc752f1..0a19491356f 100644 --- a/github/orgs.go +++ b/github/orgs.go @@ -220,7 +220,7 @@ func (s *OrganizationsService) Edit(ctx context.Context, name string, org *Organ return o, resp, nil } -// List installations for an organization. +// ListInstallations lists installations for an organization. // // GitHub API docs: https://developer.github.com/v3/orgs/#list-installations-for-an-organization func (s *OrganizationsService) ListInstallations(ctx context.Context, org string, opt *ListOptions) (*OrganizationInstallations, *Response, error) { From 7930f87c566a2d67d5d5048939e7a87deb8b4bb2 Mon Sep 17 00:00:00 2001 From: Will Norris Date: Thu, 7 Nov 2019 11:12:28 -0800 Subject: [PATCH 0069/1468] add missing fields for per-seat payment plans --- github/orgs.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/github/orgs.go b/github/orgs.go index 0a19491356f..5012c6c9f1c 100644 --- a/github/orgs.go +++ b/github/orgs.go @@ -86,6 +86,8 @@ type Plan struct { Space *int `json:"space,omitempty"` Collaborators *int `json:"collaborators,omitempty"` PrivateRepos *int `json:"private_repos,omitempty"` + FilledSeats *int `json:"filled_seats,omitempty"` + Seats *int `json:"seats,omitempty"` } func (p Plan) String() string { From e555eab49ce89ce3c3a186d04651cda1c454ec19 Mon Sep 17 00:00:00 2001 From: Will Norris Date: Thu, 7 Nov 2019 16:53:07 -0800 Subject: [PATCH 0070/1468] run go generate for newly added fields --- github/github-accessors.go | 16 ++++++++++++++++ github/github-stringify_test.go | 4 +++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/github/github-accessors.go b/github/github-accessors.go index 77942e74f3f..17018a3f2bf 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -6732,6 +6732,14 @@ func (p *Plan) GetCollaborators() int { return *p.Collaborators } +// GetFilledSeats returns the FilledSeats field if it's non-nil, zero value otherwise. +func (p *Plan) GetFilledSeats() int { + if p == nil || p.FilledSeats == nil { + return 0 + } + return *p.FilledSeats +} + // GetName returns the Name field if it's non-nil, zero value otherwise. func (p *Plan) GetName() string { if p == nil || p.Name == nil { @@ -6748,6 +6756,14 @@ func (p *Plan) GetPrivateRepos() int { return *p.PrivateRepos } +// GetSeats returns the Seats field if it's non-nil, zero value otherwise. +func (p *Plan) GetSeats() int { + if p == nil || p.Seats == nil { + return 0 + } + return *p.Seats +} + // GetSpace returns the Space field if it's non-nil, zero value otherwise. func (p *Plan) GetSpace() int { if p == nil || p.Space == nil { diff --git a/github/github-stringify_test.go b/github/github-stringify_test.go index 22e1aafb906..f7e6d2b448b 100644 --- a/github/github-stringify_test.go +++ b/github/github-stringify_test.go @@ -852,8 +852,10 @@ func TestPlan_String(t *testing.T) { Space: Int(0), Collaborators: Int(0), PrivateRepos: Int(0), + FilledSeats: Int(0), + Seats: Int(0), } - want := `github.Plan{Name:"", Space:0, Collaborators:0, PrivateRepos:0}` + want := `github.Plan{Name:"", Space:0, Collaborators:0, PrivateRepos:0, FilledSeats:0, Seats:0}` if got := v.String(); got != want { t.Errorf("Plan.String = %v, want %v", got, want) } From 116c54501eb6a3499965042c34234b9fa907aa7f Mon Sep 17 00:00:00 2001 From: Will Norris Date: Wed, 13 Nov 2019 01:25:40 -0800 Subject: [PATCH 0071/1468] scrape: add payment information method --- scrape/payment.go | 51 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 scrape/payment.go diff --git a/scrape/payment.go b/scrape/payment.go new file mode 100644 index 00000000000..fff9a7531fd --- /dev/null +++ b/scrape/payment.go @@ -0,0 +1,51 @@ +// Copyright 2013 The go-github AUTHORS. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// apps.go contains functions for accessing data about applications installed +// on a GitHub organization. + +package scrape + +import ( + "strings" + + "github.com/PuerkitoBio/goquery" +) + +// OrgPaymentInformation returns payment information for the specified org. +func (c *Client) OrgPaymentInformation(org string) (PaymentInformation, error) { + var info PaymentInformation + + doc, err := c.get("/organizations/%s/settings/billing/payment_information", org) + if err != nil { + return info, err + } + + doc.Find("main h4.mb-1").Each(func(i int, s *goquery.Selection) { + name := strings.TrimSpace(strings.ToLower(s.Text())) + value := strings.Join(strings.Fields(strings.TrimSpace(s.NextFiltered("p").Text())), " ") + + switch name { + case "payment method": + info.PaymentMethod = value + case "last payment": + info.LastPayment = value + case "coupon": + info.Coupon = value + case "extra information": + info.ExtraInformation = value + } + }) + + return info, nil +} + +// PaymentInformation for an organization on a paid plan. +type PaymentInformation struct { + PaymentMethod string + LastPayment string + Coupon string + ExtraInformation string +} From 19a41cc0d7a8b22c18bcc13b3e4a6474368c497d Mon Sep 17 00:00:00 2001 From: Will Norris Date: Thu, 14 Nov 2019 14:08:27 -0800 Subject: [PATCH 0072/1468] switch to GitHub Actions for CI (#1332) this gives us more flexibility with bringing our own build runners, has nicer integration for test logs, and avoids some of the auth problems with Travis. --- .github/workflows/tests.yml | 69 +++++++++++++++++++++++++++++++++++++ .travis.yml | 31 ----------------- README.md | 6 +++- 3 files changed, 74 insertions(+), 32 deletions(-) create mode 100644 .github/workflows/tests.yml delete mode 100644 .travis.yml diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml new file mode 100644 index 00000000000..d89f367e715 --- /dev/null +++ b/.github/workflows/tests.yml @@ -0,0 +1,69 @@ +on: [push, pull_request] +name: tests +env: + GO111MODULE: on + +jobs: + linux: + strategy: + matrix: + go-version: [1.x, 1.12.x] + runs-on: ubuntu-latest + + steps: + - uses: actions/setup-go@v1 + with: + go-version: ${{ matrix.go-version }} + - uses: actions/checkout@v1 + + - name: Cache go modules + uses: actions/cache@preview + with: + path: ~/go/pkg/mod + key: ${{ runner.os }}-go-${{ hashFiles('go.sum') }} + restore-keys: ${{ runner.os }}-go- + + - name: Run go fmt + run: diff -u <(echo -n) <(gofmt -d -s .) + + - name: Ensure go generate produces a zero diff + run: go generate -x ./... && git diff --exit-code; code=$?; git checkout -- .; (exit $code) + + - name: Run go vet + run: go vet ./... + + - name: Run go test + run: go test -v -race -coverprofile=coverage.txt -covermode=atomic ./... + + - name: Ensure integration tests build + # don't actually run tests since they hit live GitHub API + run: go test -v -tags=integration -run=^$ ./test/integration + + - name: Run scrape tests + run: cd scrape && go test ./... + + - name: Upload coverage to Codecov + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + run: bash <(curl -s https://codecov.io/bash) + + # On Windows, just run the local tests. Don't bother with checking gofmt, go + # vet, or uploading results to Codecov + windows: + strategy: + matrix: + go-version: [1.x, 1.12.x] + runs-on: windows-latest + + steps: + - uses: actions/setup-go@v1 + with: + go-version: ${{ matrix.go-version }} + - uses: actions/checkout@v1 + - name: Cache go modules + uses: actions/cache@preview + with: + path: ~/go/pkg/mod + key: ${{ runner.os }}-go-${{ hashFiles('go.sum') }} + restore-keys: ${{ runner.os }}-go- + - run: go test ./... diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 5d5a597fc9b..00000000000 --- a/.travis.yml +++ /dev/null @@ -1,31 +0,0 @@ -language: go - -go: - - "1.x" - - "1.12.x" - - master - -matrix: - allow_failures: - - go: master - fast_finish: true - -cache: - directories: - - $HOME/.cache/go-build - - $HOME/gopath/pkg/mod - -env: - global: - - GO111MODULE=on - -script: - - diff -u <(echo -n) <(gofmt -d -s .) - - go generate -x ./... && git diff --exit-code; code=$?; git checkout -- .; (exit $code) # Check that go generate ./... produces a zero diff; clean up any changes afterwards. - - go vet ./... - - go test -v -race -coverprofile=coverage.txt -covermode=atomic ./... - - go test -v -tags=integration -run=^$ ./test/integration # Check that integration test builds successfully, but don't run any of the tests (they hit live GitHub API). - - cd scrape && go test ./... # explicitly run scrape tests, since it is in a separate module - -after_success: - - bash <(curl -s https://codecov.io/bash) diff --git a/README.md b/README.md index 66503b244ae..c6f5792454c 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,10 @@ # go-github # -[![GoDoc](https://godoc.org/github.com/google/go-github/github?status.svg)](https://godoc.org/github.com/google/go-github/github) [![Build Status](https://travis-ci.org/google/go-github.svg?branch=master)](https://travis-ci.org/google/go-github) [![Test Coverage](https://codecov.io/gh/google/go-github/branch/master/graph/badge.svg)](https://codecov.io/gh/google/go-github) [![Discuss at go-github@googlegroups.com](https://img.shields.io/badge/discuss-go--github%40googlegroups.com-blue.svg)](https://groups.google.com/group/go-github) [![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/796/badge)](https://bestpractices.coreinfrastructure.org/projects/796) +[![GoDoc](https://godoc.org/github.com/google/go-github/github?status.svg)](https://godoc.org/github.com/google/go-github/github) +[![Test Status](https://github.com/google/go-github/workflows/tests/badge.svg)](https://github.com/google/go-github/actions?query=workflow%3Atests) +[![Test Coverage](https://codecov.io/gh/google/go-github/branch/master/graph/badge.svg)](https://codecov.io/gh/google/go-github) +[![Discuss at go-github@googlegroups.com](https://img.shields.io/badge/discuss-go--github%40googlegroups.com-blue.svg)](https://groups.google.com/group/go-github) +[![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/796/badge)](https://bestpractices.coreinfrastructure.org/projects/796) go-github is a Go client library for accessing the [GitHub API v3][]. From 2399959c878412d614a8c73addc9b81e2598a0c4 Mon Sep 17 00:00:00 2001 From: thomaslanghorst <32587398+thomaslanghorst@users.noreply.github.com> Date: Tue, 19 Nov 2019 03:08:06 +0100 Subject: [PATCH 0073/1468] Add test for JSON marshaling of Commit (#1333) --- github/git_commits_test.go | 100 +++++++++++++++++++++++++++++++++++++ 1 file changed, 100 insertions(+) diff --git a/github/git_commits_test.go b/github/git_commits_test.go index f316f01e0fd..6e858baf65a 100644 --- a/github/git_commits_test.go +++ b/github/git_commits_test.go @@ -18,6 +18,106 @@ import ( "golang.org/x/crypto/openpgp" ) +func TestCommit_Marshal(t *testing.T) { + testJSONMarshal(t, &Commit{}, "{}") + + u := &Commit{ + SHA: String("s"), + Author: &CommitAuthor{ + Date: &referenceTime, + Name: String("n"), + Email: String("e"), + Login: String("u"), + }, + Committer: &CommitAuthor{ + Date: &referenceTime, + Name: String("n"), + Email: String("e"), + Login: String("u"), + }, + Message: String("m"), + Tree: &Tree{ + SHA: String("s"), + Entries: []TreeEntry{{ + SHA: String("s"), + Path: String("p"), + Mode: String("m"), + Type: String("t"), + Size: Int(1), + Content: String("c"), + URL: String("u"), + }}, + Truncated: Bool(false), + }, + Parents: nil, + Stats: &CommitStats{ + Additions: Int(1), + Deletions: Int(1), + Total: Int(1), + }, + HTMLURL: String("h"), + URL: String("u"), + Verification: &SignatureVerification{ + Verified: Bool(false), + Reason: String("r"), + Signature: String("s"), + Payload: String("p"), + }, + NodeID: String("n"), + CommentCount: Int(1), + SigningKey: &openpgp.Entity{}, + } + + want := `{ + "sha": "s", + "author": { + "date": ` + referenceTimeStr + `, + "name": "n", + "email": "e", + "username": "u" + }, + "committer": { + "date": ` + referenceTimeStr + `, + "name": "n", + "email": "e", + "username": "u" + }, + "message": "m", + "tree": { + "sha": "s", + "tree": [ + { + "sha": "s", + "path": "p", + "mode": "m", + "type": "t", + "size": 1, + "content": "c", + "url": "u" + } + ], + "truncated": false + }, + "stats": { + "additions": 1, + "deletions": 1, + "total": 1 + }, + "html_url": "h", + "url": "u", + "verification": { + "verified": false, + "reason": "r", + "signature": "s", + "payload": "p" + }, + "node_id": "n", + "comment_count": 1 + }` + + testJSONMarshal(t, u, want) +} + func TestGitService_GetCommit(t *testing.T) { client, mux, _, teardown := setup() defer teardown() From ebb45fa87e76c46a5b7afb5ddc5cc93101885061 Mon Sep 17 00:00:00 2001 From: Suhaib Mujahid Date: Thu, 21 Nov 2019 18:59:59 -0500 Subject: [PATCH 0074/1468] Fix links to GitHub API docs (#1338) --- github/apps.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/github/apps.go b/github/apps.go index a546a70cdae..913464f62fb 100644 --- a/github/apps.go +++ b/github/apps.go @@ -145,7 +145,7 @@ func (s *AppsService) Get(ctx context.Context, appSlug string) (*App, *Response, // ListInstallations lists the installations that the current GitHub App has. // -// GitHub API docs: https://developer.github.com/v3/apps/#find-installations +// GitHub API docs: https://developer.github.com/v3/apps/#list-installations func (s *AppsService) ListInstallations(ctx context.Context, opt *ListOptions) ([]*Installation, *Response, error) { u, err := addOptions("app/installations", opt) if err != nil { @@ -252,14 +252,14 @@ func (s *AppsService) CreateAttachment(ctx context.Context, contentReferenceID i // FindOrganizationInstallation finds the organization's installation information. // -// GitHub API docs: https://developer.github.com/v3/apps/#find-organization-installation +// GitHub API docs: https://developer.github.com/v3/apps/#get-an-organization-installation func (s *AppsService) FindOrganizationInstallation(ctx context.Context, org string) (*Installation, *Response, error) { return s.getInstallation(ctx, fmt.Sprintf("orgs/%v/installation", org)) } // FindRepositoryInstallation finds the repository's installation information. // -// GitHub API docs: https://developer.github.com/v3/apps/#find-repository-installation +// GitHub API docs: https://developer.github.com/v3/apps/#get-a-repository-installation func (s *AppsService) FindRepositoryInstallation(ctx context.Context, owner, repo string) (*Installation, *Response, error) { return s.getInstallation(ctx, fmt.Sprintf("repos/%v/%v/installation", owner, repo)) } @@ -273,7 +273,7 @@ func (s *AppsService) FindRepositoryInstallationByID(ctx context.Context, id int // FindUserInstallation finds the user's installation information. // -// GitHub API docs: https://developer.github.com/v3/apps/#find-repository-installation +// GitHub API docs: https://developer.github.com/v3/apps/#get-a-user-installation func (s *AppsService) FindUserInstallation(ctx context.Context, user string) (*Installation, *Response, error) { return s.getInstallation(ctx, fmt.Sprintf("users/%v/installation", user)) } From 04a52c26bbdd106ed23331c4d61fde482ffb9413 Mon Sep 17 00:00:00 2001 From: Billy Lynch Date: Tue, 19 Nov 2019 10:50:34 -0500 Subject: [PATCH 0075/1468] Add App Manifest support. This adds support for creating GitHub Apps programmatically. See https://developer.github.com/apps/building-github-apps/creating-github-apps-from-a-manifest for more details. CreateApp was added to scrape, since it is effectively emulating the POST the UI makes, and doesn't actually interact with api.github.com. Fixes #1334. --- github/apps_manifest.go | 53 ++++++++++++++++++ github/apps_manifest_test.go | 53 ++++++++++++++++++ github/github-accessors.go | 104 +++++++++++++++++++++++++++++++++++ scrape/apps.go | 41 ++++++++++++++ scrape/apps_test.go | 19 +++++++ scrape/go.mod | 1 + scrape/go.sum | 10 ++++ 7 files changed, 281 insertions(+) create mode 100644 github/apps_manifest.go create mode 100644 github/apps_manifest_test.go diff --git a/github/apps_manifest.go b/github/apps_manifest.go new file mode 100644 index 00000000000..8d6ab3c8c45 --- /dev/null +++ b/github/apps_manifest.go @@ -0,0 +1,53 @@ +// Copyright 2019 The go-github AUTHORS. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package github + +import ( + "context" + "fmt" +) + +const ( + mediaTypeAppManifestPreview = "application/vnd.github.fury-preview+json" +) + +// AppConfig describes the configuration of a GitHub App. +type AppConfig struct { + ID *int64 `json:"id,omitempty"` + NodeID *string `json:"node_id,omitempty"` + Owner *User `json:"owner,omitempty"` + Name *string `json:"name,omitempty"` + Description *string `json:"description,omitempty"` + ExternalURL *string `json:"external_url,omitempty"` + HTMLURL *string `json:"html_url,omitempty"` + CreatedAt *Timestamp `json:"created_at,omitempty"` + UpdatedAt *Timestamp `json:"updated_at,omitempty"` + ClientID *string `json:"client_id,omitempty"` + ClientSecret *string `json:"client_secret,omitempty"` + WebhookSecret *string `json:"webhook_secret,omitempty"` + PEM *string `json:"pem,omitempty"` +} + +// CompleteAppManifest completes the App manifest handshake flow for the given +// code. +// +// GitHub API docs: https://developer.github.com/apps/building-github-apps/creating-github-apps-from-a-manifest/#3-you-exchange-the-temporary-code-to-retrieve-the-app-configuration +func (s *AppsService) CompleteAppManifest(ctx context.Context, code string) (*AppConfig, *Response, error) { + u := fmt.Sprintf("app-manifests/%s/conversions", code) + req, err := s.client.NewRequest("POST", u, nil) + if err != nil { + return nil, nil, err + } + req.Header.Set("Accept", mediaTypeAppManifestPreview) + + cfg := new(AppConfig) + resp, err := s.client.Do(ctx, req, cfg) + if err != nil { + return nil, resp, err + } + + return cfg, resp, nil +} diff --git a/github/apps_manifest_test.go b/github/apps_manifest_test.go new file mode 100644 index 00000000000..92a2be9d8d6 --- /dev/null +++ b/github/apps_manifest_test.go @@ -0,0 +1,53 @@ +// Copyright 2019 The go-github AUTHORS. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package github + +import ( + "context" + "fmt" + "net/http" + "reflect" + "testing" +) + +const ( + manifestJSON = `{ + "id": 1, + "client_id": "a" , + "client_secret": "b", + "webhook_secret": "c", + "pem": "key" +} +` +) + +func TestGetConfig(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/app-manifests/code/conversions", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "POST") + testHeader(t, r, "Accept", mediaTypeAppManifestPreview) + fmt.Fprint(w, manifestJSON) + }) + + cfg, _, err := client.Apps.CompleteAppManifest(context.Background(), "code") + if err != nil { + t.Errorf("AppManifest.GetConfig returned error: %v", err) + } + + want := &AppConfig{ + ID: Int64(1), + ClientID: String("a"), + ClientSecret: String("b"), + WebhookSecret: String("c"), + PEM: String("key"), + } + + if !reflect.DeepEqual(cfg, want) { + t.Errorf("GetConfig returned %+v, want %+v", cfg, want) + } +} diff --git a/github/github-accessors.go b/github/github-accessors.go index 17018a3f2bf..8aaeb247e6e 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -188,6 +188,110 @@ func (a *App) GetUpdatedAt() Timestamp { return *a.UpdatedAt } +// GetClientID returns the ClientID field if it's non-nil, zero value otherwise. +func (a *AppConfig) GetClientID() string { + if a == nil || a.ClientID == nil { + return "" + } + return *a.ClientID +} + +// GetClientSecret returns the ClientSecret field if it's non-nil, zero value otherwise. +func (a *AppConfig) GetClientSecret() string { + if a == nil || a.ClientSecret == nil { + return "" + } + return *a.ClientSecret +} + +// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise. +func (a *AppConfig) GetCreatedAt() Timestamp { + if a == nil || a.CreatedAt == nil { + return Timestamp{} + } + return *a.CreatedAt +} + +// GetDescription returns the Description field if it's non-nil, zero value otherwise. +func (a *AppConfig) GetDescription() string { + if a == nil || a.Description == nil { + return "" + } + return *a.Description +} + +// GetExternalURL returns the ExternalURL field if it's non-nil, zero value otherwise. +func (a *AppConfig) GetExternalURL() string { + if a == nil || a.ExternalURL == nil { + return "" + } + return *a.ExternalURL +} + +// GetHTMLURL returns the HTMLURL field if it's non-nil, zero value otherwise. +func (a *AppConfig) GetHTMLURL() string { + if a == nil || a.HTMLURL == nil { + return "" + } + return *a.HTMLURL +} + +// GetID returns the ID field if it's non-nil, zero value otherwise. +func (a *AppConfig) GetID() int64 { + if a == nil || a.ID == nil { + return 0 + } + return *a.ID +} + +// GetName returns the Name field if it's non-nil, zero value otherwise. +func (a *AppConfig) GetName() string { + if a == nil || a.Name == nil { + return "" + } + return *a.Name +} + +// GetNodeID returns the NodeID field if it's non-nil, zero value otherwise. +func (a *AppConfig) GetNodeID() string { + if a == nil || a.NodeID == nil { + return "" + } + return *a.NodeID +} + +// GetOwner returns the Owner field. +func (a *AppConfig) GetOwner() *User { + if a == nil { + return nil + } + return a.Owner +} + +// GetPEM returns the PEM field if it's non-nil, zero value otherwise. +func (a *AppConfig) GetPEM() string { + if a == nil || a.PEM == nil { + return "" + } + return *a.PEM +} + +// GetUpdatedAt returns the UpdatedAt field if it's non-nil, zero value otherwise. +func (a *AppConfig) GetUpdatedAt() Timestamp { + if a == nil || a.UpdatedAt == nil { + return Timestamp{} + } + return *a.UpdatedAt +} + +// GetWebhookSecret returns the WebhookSecret field if it's non-nil, zero value otherwise. +func (a *AppConfig) GetWebhookSecret() string { + if a == nil || a.WebhookSecret == nil { + return "" + } + return *a.WebhookSecret +} + // GetBody returns the Body field if it's non-nil, zero value otherwise. func (a *Attachment) GetBody() string { if a == nil || a.Body == nil { diff --git a/scrape/apps.go b/scrape/apps.go index 0c52bad834d..eb2f9005df7 100644 --- a/scrape/apps.go +++ b/scrape/apps.go @@ -9,11 +9,15 @@ package scrape import ( + "bytes" + "encoding/json" "errors" + "net/http" "strconv" "strings" "github.com/PuerkitoBio/goquery" + "github.com/google/go-github/v28/github" ) // AppRestrictionsEnabled returns whether the specified organization has @@ -103,3 +107,40 @@ type OAuthApp struct { State OAuthAppReviewState RequestedBy string } + +// AppManifest represents a GitHub App manifest, used for preconfiguring +// GitHub App configuration. +type AppManifest struct { + // The name of the GitHub App. + Name *string `json:"name,omitempty"` + //Required. The homepage of your GitHub App. + URL *string `json:"url,omitempty"` + // Required. The configuration of the GitHub App's webhook. + HookAttributes map[string]string `json:"hook_attributes,omitempty"` + // The full URL to redirect to after the person installs the GitHub App. + RedirectURL *string `json:"redirect_url,omitempty"` + // A description of the GitHub App. + Description *string `json:"description,omitempty"` + // Set to true when your GitHub App is available to the public or false when + // it is only accessible to the owner of the app. + Public *bool `json:"public,omitempty"` + // The list of events the GitHub App subscribes to. + DefaultEvents []string `json:"default_events,omitempty"` + // The set of permissions needed by the GitHub App. + DefaultPermissions *github.InstallationPermissions `json:"default_permissions,omitempty"` +} + +// CreateApp creates a new GitHub App with the given manifest configuration. +func (c *Client) CreateApp(m *AppManifest) (*http.Response, error) { + u, err := c.baseURL.Parse("/settings/apps/new") + if err != nil { + return nil, err + } + + body, err := json.Marshal(map[string]*AppManifest{"manifest": m}) + if err != nil { + return nil, err + } + + return c.Client.Post(u.String(), "json", bytes.NewReader(body)) +} diff --git a/scrape/apps_test.go b/scrape/apps_test.go index 2f8435ad197..b895b667c8f 100644 --- a/scrape/apps_test.go +++ b/scrape/apps_test.go @@ -5,6 +5,7 @@ import ( "testing" "github.com/google/go-cmp/cmp" + "github.com/google/go-github/v28/github" ) func Test_AppRestrictionsEnabled(t *testing.T) { @@ -84,3 +85,21 @@ func Test_ListOAuthApps(t *testing.T) { } } + +func Test_CreateApp(t *testing.T) { + client, mux, cleanup := setup() + defer cleanup() + + mux.HandleFunc("/apps/settings/new", func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusCreated) + }) + + if _, err := client.CreateApp(&AppManifest{ + URL: github.String("https://example.com"), + HookAttributes: map[string]string{ + "url": "https://example.com/hook", + }, + }); err != nil { + t.Fatalf("CreateApp: %v", err) + } +} diff --git a/scrape/go.mod b/scrape/go.mod index aa575d7a32e..f936c07d389 100644 --- a/scrape/go.mod +++ b/scrape/go.mod @@ -5,6 +5,7 @@ go 1.13 require ( github.com/PuerkitoBio/goquery v1.5.0 github.com/google/go-cmp v0.3.1 + github.com/google/go-github/v28 v28.1.1 github.com/xlzd/gotp v0.0.0-20181030022105-c8557ba2c119 golang.org/x/net v0.0.0-20191014212845-da9a3fd4c582 ) diff --git a/scrape/go.sum b/scrape/go.sum index 1894f0bd7f0..7f226791a92 100644 --- a/scrape/go.sum +++ b/scrape/go.sum @@ -2,14 +2,24 @@ github.com/PuerkitoBio/goquery v1.5.0 h1:uGvmFXOA73IKluu/F84Xd1tt/z07GYm8X49XKHP github.com/PuerkitoBio/goquery v1.5.0/go.mod h1:qD2PgZ9lccMbQlc7eEOjaeRlFQON7xY8kdmcsrnKqMg= github.com/andybalholm/cascadia v1.0.0 h1:hOCXnnZ5A+3eVDX8pvgl4kofXv2ELss0bKcqRySc45o= github.com/andybalholm/cascadia v1.0.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/google/go-cmp v0.3.1 h1:Xye71clBPdm5HgqGwUkwhbynsUJZhDbS20FvLhQ2izg= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-github/v28 v28.1.1 h1:kORf5ekX5qwXO2mGzXXOjMe/g6ap8ahVe0sBEulhSxo= +github.com/google/go-github/v28 v28.1.1/go.mod h1:bsqJWQX05omyWVmc00nEUql9mhQyv38lDZ8kPZcQVoM= +github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk= +github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/xlzd/gotp v0.0.0-20181030022105-c8557ba2c119 h1:YyPWX3jLOtYKulBR6AScGIs74lLrJcgeKRwcbAuQOG4= github.com/xlzd/gotp v0.0.0-20181030022105-c8557ba2c119/go.mod h1:/nuTSlK+okRfR/vnIPqR89fFKonnWPiZymN5ydRJkX8= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20191014212845-da9a3fd4c582 h1:p9xBe/w/OzkeYVKm234g55gMdD1nSIooTir5kV11kfA= golang.org/x/net v0.0.0-20191014212845-da9a3fd4c582/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= From 2afdb44c18e0d1ac44018a1b5e41e142af9eaea6 Mon Sep 17 00:00:00 2001 From: 413x Date: Thu, 5 Dec 2019 14:04:21 +0200 Subject: [PATCH 0076/1468] Have run search on "mediaTypePagesPreview" and removed it from everywhere, also have removed it from tests, not sure if tests are actual anymore (#1299) --- github/github.go | 3 --- github/repos_pages.go | 11 +---------- github/repos_pages_test.go | 6 +----- 3 files changed, 2 insertions(+), 18 deletions(-) diff --git a/github/github.go b/github/github.go index 0580271c5eb..6bec7be946b 100644 --- a/github/github.go +++ b/github/github.go @@ -67,9 +67,6 @@ const ( // https://developer.github.com/changes/2016-05-23-timeline-preview-api/ mediaTypeTimelinePreview = "application/vnd.github.mockingbird-preview+json" - // https://developer.github.com/changes/2016-07-06-github-pages-preiew-api/ - mediaTypePagesPreview = "application/vnd.github.mister-fantastic-preview+json" - // https://developer.github.com/changes/2016-09-14-projects-api/ mediaTypeProjectsPreview = "application/vnd.github.inertia-preview+json" diff --git a/github/repos_pages.go b/github/repos_pages.go index 28674130d6a..7eb32a9df00 100644 --- a/github/repos_pages.go +++ b/github/repos_pages.go @@ -8,7 +8,6 @@ package github import ( "context" "fmt" - "strings" ) // Pages represents a GitHub Pages site configuration. @@ -54,9 +53,7 @@ func (s *RepositoriesService) EnablePages(ctx context.Context, owner, repo strin return nil, nil, err } - // TODO: remove custom Accept header when this API fully launches. - acceptHeaders := []string{mediaTypeEnablePagesAPIPreview, mediaTypePagesPreview} - req.Header.Set("Accept", strings.Join(acceptHeaders, ", ")) + req.Header.Set("Accept", mediaTypeEnablePagesAPIPreview) enable := new(Pages) resp, err := s.client.Do(ctx, req, enable) @@ -93,9 +90,6 @@ func (s *RepositoriesService) GetPagesInfo(ctx context.Context, owner, repo stri return nil, nil, err } - // TODO: remove custom Accept header when this API fully launches. - req.Header.Set("Accept", mediaTypePagesPreview) - site := new(Pages) resp, err := s.client.Do(ctx, req, site) if err != nil { @@ -177,9 +171,6 @@ func (s *RepositoriesService) RequestPageBuild(ctx context.Context, owner, repo return nil, nil, err } - // TODO: remove custom Accept header when this API fully launches. - req.Header.Set("Accept", mediaTypePagesPreview) - build := new(PagesBuild) resp, err := s.client.Do(ctx, req, build) if err != nil { diff --git a/github/repos_pages_test.go b/github/repos_pages_test.go index 62d42470b0e..ec77f717a69 100644 --- a/github/repos_pages_test.go +++ b/github/repos_pages_test.go @@ -10,7 +10,6 @@ import ( "fmt" "net/http" "reflect" - "strings" "testing" ) @@ -20,8 +19,7 @@ func TestRepositoriesService_EnablePages(t *testing.T) { mux.HandleFunc("/repos/o/r/pages", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "POST") - wantAcceptHeaders := []string{mediaTypeEnablePagesAPIPreview, mediaTypePagesPreview} - testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", ")) + testHeader(t, r, "Accept", mediaTypeEnablePagesAPIPreview) fmt.Fprint(w, `{"url":"u","status":"s","cname":"c","custom_404":false,"html_url":"h", "source": {"branch":"master", "path":"/"}}`) }) @@ -58,7 +56,6 @@ func TestRepositoriesService_GetPagesInfo(t *testing.T) { mux.HandleFunc("/repos/o/r/pages", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") - testHeader(t, r, "Accept", mediaTypePagesPreview) fmt.Fprint(w, `{"url":"u","status":"s","cname":"c","custom_404":false,"html_url":"h"}`) }) @@ -157,7 +154,6 @@ func TestRepositoriesService_RequestPageBuild(t *testing.T) { mux.HandleFunc("/repos/o/r/pages/builds", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "POST") - testHeader(t, r, "Accept", mediaTypePagesPreview) fmt.Fprint(w, `{"url":"u","status":"s"}`) }) From 920353c264a6c321c57a6e3559aeb2f4a79ff01f Mon Sep 17 00:00:00 2001 From: Glen Mailer Date: Thu, 5 Dec 2019 12:34:18 +0000 Subject: [PATCH 0077/1468] Mark dismissal_restrictions optional in responses (#1288) The API will omit this field when dismissal restrictions are not in place, the response struct has been updated to reflect this. Also corrected the code and tests for DisableDismissalRestrictions Fixes #1287 --- github/github-accessors.go | 8 ++++ github/repos.go | 8 ++-- github/repos_test.go | 83 +++++++++++++++++++++++++++++++++----- 3 files changed, 84 insertions(+), 15 deletions(-) diff --git a/github/github-accessors.go b/github/github-accessors.go index 8aaeb247e6e..5e29613a17f 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -8548,6 +8548,14 @@ func (p *PullRequestReviewRequest) GetNodeID() string { return *p.NodeID } +// GetDismissalRestrictions returns the DismissalRestrictions field. +func (p *PullRequestReviewsEnforcement) GetDismissalRestrictions() *DismissalRestrictions { + if p == nil { + return nil + } + return p.DismissalRestrictions +} + // GetDismissalRestrictionsRequest returns the DismissalRestrictionsRequest field. func (p *PullRequestReviewsEnforcementRequest) GetDismissalRestrictionsRequest() *DismissalRestrictionsRequest { if p == nil { diff --git a/github/repos.go b/github/repos.go index 37a09d5b8ab..1960e0a773b 100644 --- a/github/repos.go +++ b/github/repos.go @@ -736,7 +736,7 @@ type RequiredStatusChecksRequest struct { // PullRequestReviewsEnforcement represents the pull request reviews enforcement of a protected branch. type PullRequestReviewsEnforcement struct { // Specifies which users and teams can dismiss pull request reviews. - DismissalRestrictions DismissalRestrictions `json:"dismissal_restrictions"` + DismissalRestrictions *DismissalRestrictions `json:"dismissal_restrictions,omitempty"` // Specifies if approved reviews are dismissed automatically, when a new commit is pushed. DismissStaleReviews bool `json:"dismiss_stale_reviews"` // RequireCodeOwnerReviews specifies if an approved review is required in pull requests including files with a designated code owner. @@ -1134,9 +1134,9 @@ func (s *RepositoriesService) UpdatePullRequestReviewEnforcement(ctx context.Con func (s *RepositoriesService) DisableDismissalRestrictions(ctx context.Context, owner, repo, branch string) (*PullRequestReviewsEnforcement, *Response, error) { u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/required_pull_request_reviews", owner, repo, branch) - data := struct { - R []interface{} `json:"dismissal_restrictions"` - }{[]interface{}{}} + data := new(struct { + DismissalRestrictionsRequest `json:"dismissal_restrictions"` + }) req, err := s.client.NewRequest("PATCH", u, data) if err != nil { diff --git a/github/repos_test.go b/github/repos_test.go index 5ed6682c9fe..d0fdc563d3d 100644 --- a/github/repos_test.go +++ b/github/repos_test.go @@ -907,7 +907,7 @@ func TestRepositoriesService_GetBranchProtection(t *testing.T) { }, RequiredPullRequestReviews: &PullRequestReviewsEnforcement{ DismissStaleReviews: true, - DismissalRestrictions: DismissalRestrictions{ + DismissalRestrictions: &DismissalRestrictions{ Users: []*User{ {Login: String("u"), ID: Int64(3)}, }, @@ -936,6 +936,70 @@ func TestRepositoriesService_GetBranchProtection(t *testing.T) { } } +func TestRepositoriesService_GetBranchProtection_noDismissalRestrictions(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/repos/o/r/branches/b/protection", func(w http.ResponseWriter, r *http.Request) { + + testMethod(t, r, "GET") + // TODO: remove custom Accept header when this API fully launches + testHeader(t, r, "Accept", mediaTypeRequiredApprovingReviewsPreview) + fmt.Fprintf(w, `{ + "required_status_checks":{ + "strict":true, + "contexts":["continuous-integration"] + }, + "required_pull_request_reviews":{ + "dismiss_stale_reviews":true, + "require_code_owner_reviews":true, + "required_approving_review_count":1 + }, + "enforce_admins":{ + "url":"/repos/o/r/branches/b/protection/enforce_admins", + "enabled":true + }, + "restrictions":{ + "users":[{"id":1,"login":"u"}], + "teams":[{"id":2,"slug":"t"}] + } + }`) + }) + + protection, _, err := client.Repositories.GetBranchProtection(context.Background(), "o", "r", "b") + if err != nil { + t.Errorf("Repositories.GetBranchProtection returned error: %v", err) + } + + want := &Protection{ + RequiredStatusChecks: &RequiredStatusChecks{ + Strict: true, + Contexts: []string{"continuous-integration"}, + }, + RequiredPullRequestReviews: &PullRequestReviewsEnforcement{ + DismissStaleReviews: true, + DismissalRestrictions: nil, + RequireCodeOwnerReviews: true, + RequiredApprovingReviewCount: 1, + }, + EnforceAdmins: &AdminEnforcement{ + URL: String("/repos/o/r/branches/b/protection/enforce_admins"), + Enabled: true, + }, + Restrictions: &BranchRestrictions{ + Users: []*User{ + {Login: String("u"), ID: Int64(1)}, + }, + Teams: []*Team{ + {Slug: String("t"), ID: Int64(2)}, + }, + }, + } + if !reflect.DeepEqual(protection, want) { + t.Errorf("Repositories.GetBranchProtection returned %+v, want %+v", protection, want) + } +} + func TestRepositoriesService_UpdateBranchProtection(t *testing.T) { client, mux, _, teardown := setup() defer teardown() @@ -1007,7 +1071,7 @@ func TestRepositoriesService_UpdateBranchProtection(t *testing.T) { }, RequiredPullRequestReviews: &PullRequestReviewsEnforcement{ DismissStaleReviews: true, - DismissalRestrictions: DismissalRestrictions{ + DismissalRestrictions: &DismissalRestrictions{ Users: []*User{ {Login: String("uu"), ID: Int64(3)}, }, @@ -1201,7 +1265,7 @@ func TestRepositoriesService_GetPullRequestReviewEnforcement(t *testing.T) { want := &PullRequestReviewsEnforcement{ DismissStaleReviews: true, - DismissalRestrictions: DismissalRestrictions{ + DismissalRestrictions: &DismissalRestrictions{ Users: []*User{ {Login: String("u"), ID: Int64(1)}, }, @@ -1257,7 +1321,7 @@ func TestRepositoriesService_UpdatePullRequestReviewEnforcement(t *testing.T) { want := &PullRequestReviewsEnforcement{ DismissStaleReviews: true, - DismissalRestrictions: DismissalRestrictions{ + DismissalRestrictions: &DismissalRestrictions{ Users: []*User{ {Login: String("u"), ID: Int64(1)}, }, @@ -1281,8 +1345,8 @@ func TestRepositoriesService_DisableDismissalRestrictions(t *testing.T) { testMethod(t, r, "PATCH") // TODO: remove custom Accept header when this API fully launches testHeader(t, r, "Accept", mediaTypeRequiredApprovingReviewsPreview) - testBody(t, r, `{"dismissal_restrictions":[]}`+"\n") - fmt.Fprintf(w, `{"dismissal_restrictions":{"users":[],"teams":[]},"dismiss_stale_reviews":true,"require_code_owner_reviews":true,"required_approving_review_count":1}`) + testBody(t, r, `{"dismissal_restrictions":{}}`+"\n") + fmt.Fprintf(w, `{"dismiss_stale_reviews":true,"require_code_owner_reviews":true,"required_approving_review_count":1}`) }) enforcement, _, err := client.Repositories.DisableDismissalRestrictions(context.Background(), "o", "r", "b") @@ -1291,11 +1355,8 @@ func TestRepositoriesService_DisableDismissalRestrictions(t *testing.T) { } want := &PullRequestReviewsEnforcement{ - DismissStaleReviews: true, - DismissalRestrictions: DismissalRestrictions{ - Users: []*User{}, - Teams: []*Team{}, - }, + DismissStaleReviews: true, + DismissalRestrictions: nil, RequireCodeOwnerReviews: true, RequiredApprovingReviewCount: 1, } From 2b5cb2d7cd9304349e265f4d3ff682a3b285928f Mon Sep 17 00:00:00 2001 From: lucmski <47478603+lucmski@users.noreply.github.com> Date: Thu, 5 Dec 2019 13:36:59 +0100 Subject: [PATCH 0078/1468] Add search topics (#1285) Fixes #1284. --- example/topics/main.go | 40 ++++++++++++++++ github/github-accessors.go | 96 ++++++++++++++++++++++++++++++++++++++ github/search.go | 35 ++++++++++++++ github/search_test.go | 31 ++++++++++++ 4 files changed, 202 insertions(+) create mode 100644 example/topics/main.go diff --git a/example/topics/main.go b/example/topics/main.go new file mode 100644 index 00000000000..96098efe14f --- /dev/null +++ b/example/topics/main.go @@ -0,0 +1,40 @@ +// Copyright 2019 The go-github AUTHORS. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// The simple command demonstrates a simple functionality which +// prompts the user for a GitHub topic and lists all the public +// organization memberships of the specified topic. +package main + +import ( + "context" + "fmt" + + "github.com/google/go-github/v28/github" +) + +// Fetch all the public organizations' membership of a user. +// +func FetchTopics(topic string) (*github.TopicsSearchResult, error) { + client := github.NewClient(nil) + topics, _, err := client.Search.Topics(context.Background(), topic, nil) + return topics, err +} + +func main() { + var topic string + fmt.Print("Enter GitHub topic: ") + fmt.Scanf("%s", &topic) + + topics, err := FetchTopics(topic) + if err != nil { + fmt.Printf("Error: %v\n", err) + return + } + + for _, topic := range topics.Topics { + fmt.Println(*topic.Name) + } +} diff --git a/github/github-accessors.go b/github/github-accessors.go index 5e29613a17f..b528504b50d 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -12052,6 +12052,102 @@ func (t *Timeline) GetURL() string { return *t.URL } +// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise. +func (t *TopicResult) GetCreatedAt() Timestamp { + if t == nil || t.CreatedAt == nil { + return Timestamp{} + } + return *t.CreatedAt +} + +// GetCreatedBy returns the CreatedBy field if it's non-nil, zero value otherwise. +func (t *TopicResult) GetCreatedBy() string { + if t == nil || t.CreatedBy == nil { + return "" + } + return *t.CreatedBy +} + +// GetCurated returns the Curated field if it's non-nil, zero value otherwise. +func (t *TopicResult) GetCurated() bool { + if t == nil || t.Curated == nil { + return false + } + return *t.Curated +} + +// GetDescription returns the Description field if it's non-nil, zero value otherwise. +func (t *TopicResult) GetDescription() string { + if t == nil || t.Description == nil { + return "" + } + return *t.Description +} + +// GetDisplayName returns the DisplayName field if it's non-nil, zero value otherwise. +func (t *TopicResult) GetDisplayName() string { + if t == nil || t.DisplayName == nil { + return "" + } + return *t.DisplayName +} + +// GetFeatured returns the Featured field if it's non-nil, zero value otherwise. +func (t *TopicResult) GetFeatured() bool { + if t == nil || t.Featured == nil { + return false + } + return *t.Featured +} + +// GetName returns the Name field if it's non-nil, zero value otherwise. +func (t *TopicResult) GetName() string { + if t == nil || t.Name == nil { + return "" + } + return *t.Name +} + +// GetScore returns the Score field. +func (t *TopicResult) GetScore() *float64 { + if t == nil { + return nil + } + return t.Score +} + +// GetShortDescription returns the ShortDescription field if it's non-nil, zero value otherwise. +func (t *TopicResult) GetShortDescription() string { + if t == nil || t.ShortDescription == nil { + return "" + } + return *t.ShortDescription +} + +// GetUpdatedAt returns the UpdatedAt field if it's non-nil, zero value otherwise. +func (t *TopicResult) GetUpdatedAt() string { + if t == nil || t.UpdatedAt == nil { + return "" + } + return *t.UpdatedAt +} + +// GetIncompleteResults returns the IncompleteResults field if it's non-nil, zero value otherwise. +func (t *TopicsSearchResult) GetIncompleteResults() bool { + if t == nil || t.IncompleteResults == nil { + return false + } + return *t.IncompleteResults +} + +// GetTotal returns the Total field if it's non-nil, zero value otherwise. +func (t *TopicsSearchResult) GetTotal() int { + if t == nil || t.Total == nil { + return 0 + } + return *t.Total +} + // GetCount returns the Count field if it's non-nil, zero value otherwise. func (t *TrafficClones) GetCount() int { if t == nil || t.Count == nil { diff --git a/github/search.go b/github/search.go index 13cc4c844d8..4e66ba1c3e8 100644 --- a/github/search.go +++ b/github/search.go @@ -76,6 +76,37 @@ func (s *SearchService) Repositories(ctx context.Context, query string, opt *Sea return result, resp, err } +// TopicsSearchResult represents the result of a topics search. +type TopicsSearchResult struct { + Total *int `json:"total_count,omitempty"` + IncompleteResults *bool `json:"incomplete_results,omitempty"` + Topics []*TopicResult `json:"items,omitempty"` +} + +type TopicResult struct { + Name *string `json:"name,omitempty"` + DisplayName *string `json:"display_name,omitempty"` + ShortDescription *string `json:"short_description,omitempty"` + Description *string `json:"description,omitempty"` + CreatedBy *string `json:"created_by,omitempty"` + CreatedAt *Timestamp `json:"created_at,omitempty"` + UpdatedAt *string `json:"updated_at,omitempty"` + Featured *bool `json:"featured,omitempty"` + Curated *bool `json:"curated,omitempty"` + Score *float64 `json:"score,omitempty"` +} + +// Topics finds topics via various criteria. Results are sorted by best match. +// Please see https://help.github.com/en/articles/searching-topics for more +// information about search qualifiers. +// +// GitHub API docs: https://developer.github.com/v3/search/#search-topics +func (s *SearchService) Topics(ctx context.Context, query string, opt *SearchOptions) (*TopicsSearchResult, *Response, error) { + result := new(TopicsSearchResult) + resp, err := s.search(ctx, "topics", &searchParameters{Query: query}, opt, result) + return result, resp, err +} + // CommitsSearchResult represents the result of a commits search. type CommitsSearchResult struct { Total *int `json:"total_count,omitempty"` @@ -245,6 +276,10 @@ func (s *SearchService) search(ctx context.Context, searchType string, parameter // Accept header for search commits preview endpoint // TODO: remove custom Accept header when this API fully launches. req.Header.Set("Accept", mediaTypeCommitSearchPreview) + case searchType == "topics": + // Accept header for search repositories based on topics preview endpoint + // TODO: remove custom Accept header when this API fully launches. + req.Header.Set("Accept", mediaTypeTopicsPreview) case searchType == "repositories": // Accept header for search repositories based on topics preview endpoint // TODO: remove custom Accept header when this API fully launches. diff --git a/github/search_test.go b/github/search_test.go index 4b686884e37..7b60756914b 100644 --- a/github/search_test.go +++ b/github/search_test.go @@ -47,6 +47,37 @@ func TestSearchService_Repositories(t *testing.T) { } } +func TestSearchService_Topics(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/search/topics", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + testFormValues(t, r, values{ + "q": "blah", + "page": "2", + "per_page": "2", + }) + + fmt.Fprint(w, `{"total_count": 4, "incomplete_results": false, "items": [{"name":"blah"},{"name":"blahblah"}]}`) + }) + + opts := &SearchOptions{ListOptions: ListOptions{Page: 2, PerPage: 2}} + result, _, err := client.Search.Topics(context.Background(), "blah", opts) + if err != nil { + t.Errorf("Search.Topics returned error: %v", err) + } + + want := &TopicsSearchResult{ + Total: Int(4), + IncompleteResults: Bool(false), + Topics: []*TopicResult{{Name: String("blah")}, {Name: String("blahblah")}}, + } + if !reflect.DeepEqual(result, want) { + t.Errorf("Search.Topics returned %+v, want %+v", result, want) + } +} + func TestSearchService_Commits(t *testing.T) { client, mux, _, teardown := setup() defer teardown() From b94682aa918294e3c0df9abe1a585b0f115d3387 Mon Sep 17 00:00:00 2001 From: Takayuki WATANABE Date: Thu, 5 Dec 2019 12:37:48 +0000 Subject: [PATCH 0079/1468] Add list and create projects for users (#1295) --- github/github-accessors.go | 8 +++++ github/users_projects.go | 68 +++++++++++++++++++++++++++++++++++ github/users_projects_test.go | 68 +++++++++++++++++++++++++++++++++++ 3 files changed, 144 insertions(+) create mode 100644 github/users_projects.go create mode 100644 github/users_projects_test.go diff --git a/github/github-accessors.go b/github/github-accessors.go index b528504b50d..2035e706069 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -2092,6 +2092,14 @@ func (c *CreateOrgInvitationOptions) GetRole() string { return *c.Role } +// GetBody returns the Body field if it's non-nil, zero value otherwise. +func (c *CreateUserProjectOptions) GetBody() string { + if c == nil || c.Body == nil { + return "" + } + return *c.Body +} + // GetInstallation returns the Installation field. func (d *DeleteEvent) GetInstallation() *Installation { if d == nil { diff --git a/github/users_projects.go b/github/users_projects.go new file mode 100644 index 00000000000..bd2ca75e1f0 --- /dev/null +++ b/github/users_projects.go @@ -0,0 +1,68 @@ +// Copyright 2019 The go-github AUTHORS. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package github + +import ( + "context" + "fmt" +) + +// ListProjects lists the projects for the specified user. +// +// GitHub API docs: https://developer.github.com/v3/projects/#list-user-projects +func (s *UsersService) ListProjects(ctx context.Context, user string, opt *ProjectListOptions) ([]*Project, *Response, error) { + u := fmt.Sprintf("users/%v/projects", user) + 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. + req.Header.Set("Accept", mediaTypeProjectsPreview) + + var projects []*Project + resp, err := s.client.Do(ctx, req, &projects) + if err != nil { + return nil, resp, err + } + + return projects, resp, nil +} + +// CreateUserProjectOptions specifies the parameters to the UsersService.CreateProject method. +type CreateUserProjectOptions struct { + // The name of the project. (Required.) + Name string `json:"name"` + // The description of the project. (Optional.) + Body *string `json:"body,omitempty"` +} + +// CreateProject creates a GitHub Project for the current user. +// +// GitHub API docs: https://developer.github.com/v3/projects/#create-a-user-project +func (s *UsersService) CreateProject(ctx context.Context, opt *CreateUserProjectOptions) (*Project, *Response, error) { + u := "users/projects" + req, err := s.client.NewRequest("POST", u, opt) + if err != nil { + return nil, nil, err + } + + // TODO: remove custom Accept header when this API fully launches. + req.Header.Set("Accept", mediaTypeProjectsPreview) + + project := &Project{} + resp, err := s.client.Do(ctx, req, project) + if err != nil { + return nil, resp, err + } + + return project, resp, nil +} diff --git a/github/users_projects_test.go b/github/users_projects_test.go new file mode 100644 index 00000000000..b186fbf07f7 --- /dev/null +++ b/github/users_projects_test.go @@ -0,0 +1,68 @@ +// Copyright 2019 The go-github AUTHORS. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package github + +import ( + "context" + "encoding/json" + "fmt" + "net/http" + "reflect" + "testing" +) + +func TestUsersService_ListProjects(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/users/u/projects", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + testHeader(t, r, "Accept", mediaTypeProjectsPreview) + testFormValues(t, r, values{"state": "open", "page": "2"}) + fmt.Fprint(w, `[{"id":1}]`) + }) + + opt := &ProjectListOptions{State: "open", ListOptions: ListOptions{Page: 2}} + projects, _, err := client.Users.ListProjects(context.Background(), "u", opt) + if err != nil { + t.Errorf("Users.ListProjects returned error: %v", err) + } + + want := []*Project{{ID: Int64(1)}} + if !reflect.DeepEqual(projects, want) { + t.Errorf("Users.ListProjects returned %+v, want %+v", projects, want) + } +} + +func TestUsersService_CreateProject(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + input := &CreateUserProjectOptions{Name: "Project Name", Body: String("Project body.")} + + mux.HandleFunc("/users/projects", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "POST") + testHeader(t, r, "Accept", mediaTypeProjectsPreview) + + v := &CreateUserProjectOptions{} + json.NewDecoder(r.Body).Decode(v) + if !reflect.DeepEqual(v, input) { + t.Errorf("Request body = %+v, want %+v", v, input) + } + + fmt.Fprint(w, `{"id":1}`) + }) + + project, _, err := client.Users.CreateProject(context.Background(), input) + if err != nil { + t.Errorf("Users.CreateProject returned error: %v", err) + } + + want := &Project{ID: Int64(1)} + if !reflect.DeepEqual(project, want) { + t.Errorf("Users.CreateProject returned %+v, want %+v", project, want) + } +} From ded42c195534bb308e1e62141ef809723faae456 Mon Sep 17 00:00:00 2001 From: Joshua Bezaleel Abednego Date: Thu, 5 Dec 2019 19:38:59 +0700 Subject: [PATCH 0080/1468] Remove mediaTypeTeamSyncPreview header (#1304) Fixes #1296. --- github/github.go | 3 --- github/teams.go | 9 --------- github/teams_test.go | 3 --- 3 files changed, 15 deletions(-) diff --git a/github/github.go b/github/github.go index 6bec7be946b..f5398325747 100644 --- a/github/github.go +++ b/github/github.go @@ -145,9 +145,6 @@ const ( // https://developer.github.com/changes/2019-04-11-pulls-branches-for-commit/ mediaTypeListPullsOrBranchesForCommitPreview = "application/vnd.github.groot-preview+json" - // https://developer.github.com/changes/2019-06-12-team-sync/ - mediaTypeTeamSyncPreview = "application/vnd.github.team-sync-preview+json" - // https://developer.github.com/v3/previews/#repository-creation-permissions mediaTypeMemberAllowedRepoCreationTypePreview = "application/vnd.github.surtur-preview+json" diff --git a/github/teams.go b/github/teams.go index b4953e63871..7f00b986e62 100644 --- a/github/teams.go +++ b/github/teams.go @@ -504,9 +504,6 @@ func (s *TeamsService) ListIDPGroupsInOrganization(ctx context.Context, org stri return nil, nil, err } - // TODO: remove custom Accept header when this API fully launches. - req.Header.Set("Accept", mediaTypeTeamSyncPreview) - groups := new(IDPGroupList) resp, err := s.client.Do(ctx, req, groups) if err != nil { @@ -526,9 +523,6 @@ func (s *TeamsService) ListIDPGroupsForTeam(ctx context.Context, teamID string) return nil, nil, err } - // TODO: remove custom Accept header when this API fully launches. - req.Header.Set("Accept", mediaTypeTeamSyncPreview) - groups := new(IDPGroupList) resp, err := s.client.Do(ctx, req, groups) if err != nil { @@ -549,9 +543,6 @@ func (s *TeamsService) CreateOrUpdateIDPGroupConnections(ctx context.Context, te return nil, nil, err } - // TODO: remove custom Accept header when this API fully launches. - req.Header.Set("Accept", mediaTypeTeamSyncPreview) - groups := new(IDPGroupList) resp, err := s.client.Do(ctx, req, groups) if err != nil { diff --git a/github/teams_test.go b/github/teams_test.go index 6210bb596ae..97dc325d556 100644 --- a/github/teams_test.go +++ b/github/teams_test.go @@ -608,7 +608,6 @@ func TestTeamsService_ListIDPGroupsInOrganization(t *testing.T) { mux.HandleFunc("/orgs/o/team-sync/groups", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") - testHeader(t, r, "Accept", mediaTypeTeamSyncPreview) testFormValues(t, r, values{ "page": "2", }) @@ -641,7 +640,6 @@ func TestTeamsService_ListIDPGroupsForTeam(t *testing.T) { mux.HandleFunc("/teams/1/team-sync/group-mappings", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") - testHeader(t, r, "Accept", mediaTypeTeamSyncPreview) fmt.Fprint(w, `{"groups": [{"group_id": "1", "group_name": "n", "group_description": "d"}]}`) }) @@ -670,7 +668,6 @@ func TestTeamsService_CreateOrUpdateIDPGroupConnections(t *testing.T) { mux.HandleFunc("/teams/1/team-sync/group-mappings", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "PATCH") - testHeader(t, r, "Accept", mediaTypeTeamSyncPreview) fmt.Fprint(w, `{"groups": [{"group_id": "1", "group_name": "n", "group_description": "d"}]}`) }) From 1ceaa95a5d70f22e95f3212dec0c346d38591d73 Mon Sep 17 00:00:00 2001 From: Taketoshi Fujiwara Date: Thu, 5 Dec 2019 21:40:22 +0900 Subject: [PATCH 0081/1468] Make IssueListCommentsOptions consistent with GitHub API (#1340) Fixes #1339. --- github/github-accessors.go | 24 ++++++++++++++++++++++++ github/issues_comments.go | 6 +++--- github/issues_comments_test.go | 7 ++++--- 3 files changed, 31 insertions(+), 6 deletions(-) diff --git a/github/github-accessors.go b/github/github-accessors.go index 2035e706069..97b7690eb07 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -4596,6 +4596,30 @@ func (i *IssueEvent) GetURL() string { return *i.URL } +// GetDirection returns the Direction field if it's non-nil, zero value otherwise. +func (i *IssueListCommentsOptions) GetDirection() string { + if i == nil || i.Direction == nil { + return "" + } + return *i.Direction +} + +// GetSince returns the Since field if it's non-nil, zero value otherwise. +func (i *IssueListCommentsOptions) GetSince() time.Time { + if i == nil || i.Since == nil { + return time.Time{} + } + return *i.Since +} + +// GetSort returns the Sort field if it's non-nil, zero value otherwise. +func (i *IssueListCommentsOptions) GetSort() string { + if i == nil || i.Sort == nil { + return "" + } + return *i.Sort +} + // GetAssignee returns the Assignee field if it's non-nil, zero value otherwise. func (i *IssueRequest) GetAssignee() string { if i == nil || i.Assignee == nil { diff --git a/github/issues_comments.go b/github/issues_comments.go index ab68afe2fa4..42d6bc78898 100644 --- a/github/issues_comments.go +++ b/github/issues_comments.go @@ -36,13 +36,13 @@ func (i IssueComment) String() string { // IssuesService.ListComments method. type IssueListCommentsOptions struct { // Sort specifies how to sort comments. Possible values are: created, updated. - Sort string `url:"sort,omitempty"` + Sort *string `url:"sort,omitempty"` // Direction in which to sort comments. Possible values are: asc, desc. - Direction string `url:"direction,omitempty"` + Direction *string `url:"direction,omitempty"` // Since filters comments by time. - Since time.Time `url:"since,omitempty"` + Since *time.Time `url:"since,omitempty"` ListOptions } diff --git a/github/issues_comments_test.go b/github/issues_comments_test.go index 6911a798539..69acb24280e 100644 --- a/github/issues_comments_test.go +++ b/github/issues_comments_test.go @@ -31,10 +31,11 @@ func TestIssuesService_ListComments_allIssues(t *testing.T) { fmt.Fprint(w, `[{"id":1}]`) }) + since := time.Date(2002, time.February, 10, 15, 30, 0, 0, time.UTC) opt := &IssueListCommentsOptions{ - Sort: "updated", - Direction: "desc", - Since: time.Date(2002, time.February, 10, 15, 30, 0, 0, time.UTC), + Sort: String("updated"), + Direction: String("desc"), + Since: &since, ListOptions: ListOptions{Page: 2}, } comments, _, err := client.Issues.ListComments(context.Background(), "o", "r", 0, opt) From 4ba4e4d60843f3fcbc6e87eb24801b60f36813cb Mon Sep 17 00:00:00 2001 From: James Cockbain Date: Thu, 5 Dec 2019 12:42:20 +0000 Subject: [PATCH 0082/1468] Add option to follow 301 redirects for GetArchiveLink (#1336) Fixes #1248. --- github/repos_contents.go | 29 ++++++++++++++++++------ github/repos_contents_test.go | 42 ++++++++++++++++++++++++++++++++++- 2 files changed, 63 insertions(+), 8 deletions(-) diff --git a/github/repos_contents.go b/github/repos_contents.go index bf6cabc5c0b..eed0420ab84 100644 --- a/github/repos_contents.go +++ b/github/repos_contents.go @@ -240,15 +240,28 @@ const ( // or github.Zipball constant. // // GitHub API docs: https://developer.github.com/v3/repos/contents/#get-archive-link -func (s *RepositoriesService) GetArchiveLink(ctx context.Context, owner, repo string, archiveformat archiveFormat, opt *RepositoryContentGetOptions) (*url.URL, *Response, error) { +func (s *RepositoriesService) GetArchiveLink(ctx context.Context, owner, repo string, archiveformat archiveFormat, opt *RepositoryContentGetOptions, followRedirects bool) (*url.URL, *Response, error) { u := fmt.Sprintf("repos/%s/%s/%s", owner, repo, archiveformat) if opt != nil && opt.Ref != "" { u += fmt.Sprintf("/%s", opt.Ref) } - req, err := s.client.NewRequest("GET", u, nil) + resp, err := s.getArchiveLinkFromURL(ctx, u, followRedirects) if err != nil { return nil, nil, err } + if resp.StatusCode != http.StatusFound { + return nil, newResponse(resp), fmt.Errorf("unexpected status code: %s", resp.Status) + } + parsedURL, err := url.Parse(resp.Header.Get("Location")) + return parsedURL, newResponse(resp), err +} + +func (s *RepositoriesService) getArchiveLinkFromURL(ctx context.Context, u string, followRedirects bool) (*http.Response, error) { + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, err + } + var resp *http.Response // Use http.DefaultTransport if no custom Transport is configured req = withContext(ctx, req) @@ -258,12 +271,14 @@ func (s *RepositoriesService) GetArchiveLink(ctx context.Context, owner, repo st resp, err = s.client.client.Transport.RoundTrip(req) } if err != nil { - return nil, nil, err + return nil, err } resp.Body.Close() - if resp.StatusCode != http.StatusFound { - return nil, newResponse(resp), fmt.Errorf("unexpected status code: %s", resp.Status) + + // If redirect response is returned, follow it + if followRedirects && resp.StatusCode == http.StatusMovedPermanently { + u = resp.Header.Get("Location") + resp, err = s.getArchiveLinkFromURL(ctx, u, false) } - parsedURL, err := url.Parse(resp.Header.Get("Location")) - return parsedURL, newResponse(resp), err + return resp, err } diff --git a/github/repos_contents_test.go b/github/repos_contents_test.go index 29bab8d270e..f122525800a 100644 --- a/github/repos_contents_test.go +++ b/github/repos_contents_test.go @@ -10,6 +10,7 @@ import ( "fmt" "io/ioutil" "net/http" + "net/url" "reflect" "testing" ) @@ -375,7 +376,46 @@ func TestRepositoriesService_GetArchiveLink(t *testing.T) { testMethod(t, r, "GET") http.Redirect(w, r, "http://github.com/a", http.StatusFound) }) - url, resp, err := client.Repositories.GetArchiveLink(context.Background(), "o", "r", Tarball, &RepositoryContentGetOptions{}) + url, resp, err := client.Repositories.GetArchiveLink(context.Background(), "o", "r", Tarball, &RepositoryContentGetOptions{}, true) + if err != nil { + t.Errorf("Repositories.GetArchiveLink returned error: %v", err) + } + if resp.StatusCode != http.StatusFound { + t.Errorf("Repositories.GetArchiveLink returned status: %d, want %d", resp.StatusCode, http.StatusFound) + } + want := "http://github.com/a" + if url.String() != want { + t.Errorf("Repositories.GetArchiveLink returned %+v, want %+v", url.String(), want) + } +} + +func TestRepositoriesService_GetArchiveLink_StatusMovedPermanently_dontFollowRedirects(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + mux.HandleFunc("/repos/o/r/tarball", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + http.Redirect(w, r, "http://github.com/a", http.StatusMovedPermanently) + }) + _, resp, _ := client.Repositories.GetArchiveLink(context.Background(), "o", "r", Tarball, &RepositoryContentGetOptions{}, false) + if resp.StatusCode != http.StatusMovedPermanently { + t.Errorf("Repositories.GetArchiveLink returned status: %d, want %d", resp.StatusCode, http.StatusMovedPermanently) + } +} + +func TestRepositoriesService_GetArchiveLink_StatusMovedPermanently_followRedirects(t *testing.T) { + client, mux, serverURL, teardown := setup() + defer teardown() + // Mock a redirect link, which leads to an archive link + mux.HandleFunc("/repos/o/r/tarball", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + redirectURL, _ := url.Parse(serverURL + baseURLPath + "/redirect") + http.Redirect(w, r, redirectURL.String(), http.StatusMovedPermanently) + }) + mux.HandleFunc("/redirect", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + http.Redirect(w, r, "http://github.com/a", http.StatusFound) + }) + url, resp, err := client.Repositories.GetArchiveLink(context.Background(), "o", "r", Tarball, &RepositoryContentGetOptions{}, true) if err != nil { t.Errorf("Repositories.GetArchiveLink returned error: %v", err) } From 43a73bd5e0824ba5fb2efe2ed10b7b7834a2ab9f Mon Sep 17 00:00:00 2001 From: haya14busa Date: Thu, 5 Dec 2019 21:43:27 +0900 Subject: [PATCH 0083/1468] Remove needless HeadBranch from Create/Update CheckRun APIs (#1292) --- github/checks.go | 2 -- github/checks_test.go | 10 ++++------ github/github-accessors.go | 8 -------- 3 files changed, 4 insertions(+), 16 deletions(-) diff --git a/github/checks.go b/github/checks.go index 84f8403401f..1acc26e9935 100644 --- a/github/checks.go +++ b/github/checks.go @@ -140,7 +140,6 @@ func (s *ChecksService) GetCheckSuite(ctx context.Context, owner, repo string, c // CreateCheckRunOptions sets up parameters needed to create a CheckRun. type CreateCheckRunOptions struct { Name string `json:"name"` // The name of the check (e.g., "code-coverage"). (Required.) - HeadBranch string `json:"head_branch"` // The name of the branch to perform a check against. (Required.) HeadSHA string `json:"head_sha"` // The SHA of the commit. (Required.) DetailsURL *string `json:"details_url,omitempty"` // The URL of the integrator's site that has the full details of the check. (Optional.) ExternalID *string `json:"external_id,omitempty"` // A reference for the run on the integrator's system. (Optional.) @@ -183,7 +182,6 @@ func (s *ChecksService) CreateCheckRun(ctx context.Context, owner, repo string, // UpdateCheckRunOptions sets up parameters needed to update a CheckRun. type UpdateCheckRunOptions struct { Name string `json:"name"` // The name of the check (e.g., "code-coverage"). (Required.) - HeadBranch *string `json:"head_branch,omitempty"` // The name of the branch to perform a check against. (Optional.) HeadSHA *string `json:"head_sha,omitempty"` // The SHA of the commit. (Optional.) DetailsURL *string `json:"details_url,omitempty"` // The URL of the integrator's site that has the full details of the check. (Optional.) ExternalID *string `json:"external_id,omitempty"` // A reference for the run on the integrator's system. (Optional.) diff --git a/github/checks_test.go b/github/checks_test.go index 848c7e7d389..e510e32f701 100644 --- a/github/checks_test.go +++ b/github/checks_test.go @@ -102,11 +102,10 @@ func TestChecksService_CreateCheckRun(t *testing.T) { }) startedAt, _ := time.Parse(time.RFC3339, "2018-05-04T01:14:52Z") checkRunOpt := CreateCheckRunOptions{ - HeadBranch: "master", - Name: "testCreateCheckRun", - HeadSHA: "deadbeef", - Status: String("in_progress"), - StartedAt: &Timestamp{startedAt}, + Name: "testCreateCheckRun", + HeadSHA: "deadbeef", + Status: String("in_progress"), + StartedAt: &Timestamp{startedAt}, Output: &CheckRunOutput{ Title: String("Mighty test report"), Summary: String(""), @@ -200,7 +199,6 @@ func TestChecksService_UpdateCheckRun(t *testing.T) { }) startedAt, _ := time.Parse(time.RFC3339, "2018-05-04T01:14:52Z") updateCheckRunOpt := UpdateCheckRunOptions{ - HeadBranch: String("master"), Name: "testUpdateCheckRun", HeadSHA: String("deadbeef"), Status: String("completed"), diff --git a/github/github-accessors.go b/github/github-accessors.go index 97b7690eb07..c9678b5b668 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -12396,14 +12396,6 @@ func (u *UpdateCheckRunOptions) GetExternalID() string { return *u.ExternalID } -// GetHeadBranch returns the HeadBranch field if it's non-nil, zero value otherwise. -func (u *UpdateCheckRunOptions) GetHeadBranch() string { - if u == nil || u.HeadBranch == nil { - return "" - } - return *u.HeadBranch -} - // GetHeadSHA returns the HeadSHA field if it's non-nil, zero value otherwise. func (u *UpdateCheckRunOptions) GetHeadSHA() string { if u == nil || u.HeadSHA == nil { From 6688527555292834572a9d635bd77b9639c7c548 Mon Sep 17 00:00:00 2001 From: Jordan Sussman Date: Thu, 5 Dec 2019 07:44:27 -0500 Subject: [PATCH 0084/1468] Add support for UserEvent webhooks (#1302) Fixes #1301. --- github/admin.go | 18 +++++ github/event.go | 2 + github/event_types.go | 14 ++++ github/github-accessors.go | 112 ++++++++++++++++++++++++++++++++ github/github-stringify_test.go | 19 ++++++ github/messages.go | 1 + github/messages_test.go | 4 ++ 7 files changed, 170 insertions(+) diff --git a/github/admin.go b/github/admin.go index 2d96733a1c7..31cd1fa2a48 100644 --- a/github/admin.go +++ b/github/admin.go @@ -62,6 +62,24 @@ func (m UserLDAPMapping) String() string { return Stringify(m) } +// Enterprise represents the GitHub enterprise profile. +type Enterprise struct { + ID *int `json:"id,omitempty"` + Slug *string `json:"slug,omitempty"` + Name *string `json:"name,omitempty"` + NodeID *string `json:"node_id,omitempty"` + AvatarURL *string `json:"avatar_url,omitempty"` + Description *string `json:"description,omitempty"` + WebsiteURL *string `json:"website_url,omitempty"` + HTMLURL *string `json:"html_url,omitempty"` + CreatedAt *Timestamp `json:"created_at,omitempty"` + UpdatedAt *Timestamp `json:"updated_at,omitempty"` +} + +func (m Enterprise) String() string { + return Stringify(m) +} + // UpdateUserLDAPMapping updates the mapping between a GitHub user and an LDAP user. // // GitHub API docs: https://developer.github.com/v3/enterprise/ldap/#update-ldap-mapping-for-a-user diff --git a/github/event.go b/github/event.go index 0ba8f46a1b0..de20f58403d 100644 --- a/github/event.go +++ b/github/event.go @@ -110,6 +110,8 @@ func (e *Event) ParsePayload() (payload interface{}, err error) { payload = &TeamEvent{} case "TeamAddEvent": payload = &TeamAddEvent{} + case "UserEvent": + payload = &UserEvent{} case "WatchEvent": payload = &WatchEvent{} } diff --git a/github/event_types.go b/github/event_types.go index 049751aa4f9..a04c7f6219f 100644 --- a/github/event_types.go +++ b/github/event_types.go @@ -872,6 +872,20 @@ type TeamAddEvent struct { Installation *Installation `json:"installation,omitempty"` } +// UserEvent is triggered when a user is created or deleted. +// The Webhook event name is "user". +// +// Only global webhooks can subscribe to this event type. +// +// GitHub API docs: https://developer.github.com/enterprise/v3/activity/events/types/#userevent-enterprise +type UserEvent struct { + User *User `json:"user,omitempty"` + // The action performed. Possible values are: "created" or "deleted". + Action *string `json:"action,omitempty"` + Enterprise *Enterprise `json:"enterprise,omitempty"` + Sender *User `json:"sender,omitempty"` +} + // WatchEvent is related to starring a repository, not watching. See this API // blog post for an explanation: https://developer.github.com/changes/2012-09-05-watcher-api/ // diff --git a/github/github-accessors.go b/github/github-accessors.go index c9678b5b668..b8f0765b1c5 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -2716,6 +2716,86 @@ func (d *DraftReviewComment) GetPosition() int { return *d.Position } +// GetAvatarURL returns the AvatarURL field if it's non-nil, zero value otherwise. +func (e *Enterprise) GetAvatarURL() string { + if e == nil || e.AvatarURL == nil { + return "" + } + return *e.AvatarURL +} + +// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise. +func (e *Enterprise) GetCreatedAt() Timestamp { + if e == nil || e.CreatedAt == nil { + return Timestamp{} + } + return *e.CreatedAt +} + +// GetDescription returns the Description field if it's non-nil, zero value otherwise. +func (e *Enterprise) GetDescription() string { + if e == nil || e.Description == nil { + return "" + } + return *e.Description +} + +// GetHTMLURL returns the HTMLURL field if it's non-nil, zero value otherwise. +func (e *Enterprise) GetHTMLURL() string { + if e == nil || e.HTMLURL == nil { + return "" + } + return *e.HTMLURL +} + +// GetID returns the ID field if it's non-nil, zero value otherwise. +func (e *Enterprise) GetID() int { + if e == nil || e.ID == nil { + return 0 + } + return *e.ID +} + +// GetName returns the Name field if it's non-nil, zero value otherwise. +func (e *Enterprise) GetName() string { + if e == nil || e.Name == nil { + return "" + } + return *e.Name +} + +// GetNodeID returns the NodeID field if it's non-nil, zero value otherwise. +func (e *Enterprise) GetNodeID() string { + if e == nil || e.NodeID == nil { + return "" + } + return *e.NodeID +} + +// GetSlug returns the Slug field if it's non-nil, zero value otherwise. +func (e *Enterprise) GetSlug() string { + if e == nil || e.Slug == nil { + return "" + } + return *e.Slug +} + +// GetUpdatedAt returns the UpdatedAt field if it's non-nil, zero value otherwise. +func (e *Enterprise) GetUpdatedAt() Timestamp { + if e == nil || e.UpdatedAt == nil { + return Timestamp{} + } + return *e.UpdatedAt +} + +// GetWebsiteURL returns the WebsiteURL field if it's non-nil, zero value otherwise. +func (e *Enterprise) GetWebsiteURL() string { + if e == nil || e.WebsiteURL == nil { + return "" + } + return *e.WebsiteURL +} + // GetActor returns the Actor field. func (e *Event) GetActor() *User { if e == nil { @@ -12796,6 +12876,38 @@ func (u *UserEmail) GetVisibility() string { return *u.Visibility } +// GetAction returns the Action field if it's non-nil, zero value otherwise. +func (u *UserEvent) GetAction() string { + if u == nil || u.Action == nil { + return "" + } + return *u.Action +} + +// GetEnterprise returns the Enterprise field. +func (u *UserEvent) GetEnterprise() *Enterprise { + if u == nil { + return nil + } + return u.Enterprise +} + +// GetSender returns the Sender field. +func (u *UserEvent) GetSender() *User { + if u == nil { + return nil + } + return u.Sender +} + +// GetUser returns the User field. +func (u *UserEvent) GetUser() *User { + if u == nil { + return nil + } + return u.User +} + // GetAvatarURL returns the AvatarURL field if it's non-nil, zero value otherwise. func (u *UserLDAPMapping) GetAvatarURL() string { if u == nil || u.AvatarURL == nil { diff --git a/github/github-stringify_test.go b/github/github-stringify_test.go index f7e6d2b448b..28ac8125dd3 100644 --- a/github/github-stringify_test.go +++ b/github/github-stringify_test.go @@ -307,6 +307,25 @@ func TestDraftReviewComment_String(t *testing.T) { } } +func TestEnterprise_String(t *testing.T) { + v := Enterprise{ + ID: Int(0), + Slug: String(""), + Name: String(""), + NodeID: String(""), + AvatarURL: String(""), + Description: String(""), + WebsiteURL: String(""), + HTMLURL: String(""), + CreatedAt: &Timestamp{}, + UpdatedAt: &Timestamp{}, + } + want := `github.Enterprise{ID:0, Slug:"", Name:"", NodeID:"", AvatarURL:"", Description:"", WebsiteURL:"", HTMLURL:"", CreatedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, UpdatedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}}` + if got := v.String(); got != want { + t.Errorf("Enterprise.String = %v, want %v", got, want) + } +} + func TestEvent_String(t *testing.T) { v := Event{ Type: String(""), diff --git a/github/messages.go b/github/messages.go index ac7c17f3ca8..a87daa3e9ef 100644 --- a/github/messages.go +++ b/github/messages.go @@ -80,6 +80,7 @@ var ( "status": "StatusEvent", "team": "TeamEvent", "team_add": "TeamAddEvent", + "user": "UserEvent", "watch": "WatchEvent", } ) diff --git a/github/messages_test.go b/github/messages_test.go index 105904c665c..30f7d95fb78 100644 --- a/github/messages_test.go +++ b/github/messages_test.go @@ -339,6 +339,10 @@ func TestParseWebHook(t *testing.T) { payload: &TeamAddEvent{}, messageType: "team_add", }, + { + payload: &UserEvent{}, + messageType: "user", + }, { payload: &WatchEvent{}, messageType: "watch", From 1c5c6afcce9e36ddd3043e7fc2e74a0a96dd1979 Mon Sep 17 00:00:00 2001 From: Jordan Sussman Date: Thu, 5 Dec 2019 07:47:23 -0500 Subject: [PATCH 0085/1468] Add create and delete endpoints (#1315) Fixes #1314. --- github/admin_users.go | 72 ++++++++++++++++++++ github/admin_users_test.go | 72 ++++++++++++++++++++ github/github-accessors.go | 112 ++++++++++++++++++++++++++++++++ github/github-stringify_test.go | 12 ++++ 4 files changed, 268 insertions(+) diff --git a/github/admin_users.go b/github/admin_users.go index ea7a47d31ce..742855501ea 100644 --- a/github/admin_users.go +++ b/github/admin_users.go @@ -7,6 +7,7 @@ package github import ( "context" + "fmt" ) // createUserRequest is a subset of User and is used internally @@ -59,3 +60,74 @@ func (s *AdminService) DeleteUser(ctx context.Context, username string) (*Respon return resp, nil } + +// ImpersonateUserOptions represents the scoping for the OAuth token. +type ImpersonateUserOptions struct { + Scopes []string `json:"scopes,omitempty"` +} + +// OAuthAPP represents the GitHub Site Administrator OAuth app. +type OAuthAPP struct { + URL *string `json:"url,omitempty"` + Name *string `json:"name,omitempty"` + ClientID *string `json:"client_id,omitempty"` +} + +func (s OAuthAPP) String() string { + return Stringify(s) +} + +// UserAuthorization represents the impersonation response. +type UserAuthorization struct { + ID *int64 `json:"id,omitempty"` + URL *string `json:"url,omitempty"` + Scopes []string `json:"scopes,omitempty"` + Token *string `json:"token,omitempty"` + TokenLastEight *string `json:"token_last_eight,omitempty"` + HashedToken *string `json:"hashed_token,omitempty"` + App *OAuthAPP `json:"app,omitempty"` + Note *string `json:"note,omitempty"` + NoteURL *string `json:"note_url,omitempty"` + UpdatedAt *Timestamp `json:"updated_at,omitempty"` + CreatedAt *Timestamp `json:"created_at,omitempty"` + Fingerprint *string `json:"fingerprint,omitempty"` +} + +// CreateUserImpersonation creates an impersonation OAuth token. +// +// GitHub Enterprise API docs: https://developer.github.com/enterprise/v3/enterprise-admin/users/#create-an-impersonation-oauth-token +func (s *AdminService) CreateUserImpersonation(ctx context.Context, username string, opt *ImpersonateUserOptions) (*UserAuthorization, *Response, error) { + u := fmt.Sprintf("admin/users/%s/authorizations", username) + + req, err := s.client.NewRequest("POST", u, opt) + if err != nil { + return nil, nil, err + } + + a := new(UserAuthorization) + resp, err := s.client.Do(ctx, req, a) + if err != nil { + return nil, resp, err + } + + return a, resp, nil +} + +// DeleteUserImpersonation deletes an impersonation OAuth token. +// +// GitHub Enterprise API docs: https://developer.github.com/enterprise/v3/enterprise-admin/users/#delete-an-impersonation-oauth-token +func (s *AdminService) DeleteUserImpersonation(ctx context.Context, username string) (*Response, error) { + u := fmt.Sprintf("admin/users/%s/authorizations", username) + + req, err := s.client.NewRequest("DELETE", u, nil) + if err != nil { + return nil, err + } + + resp, err := s.client.Do(ctx, req, nil) + if err != nil { + return resp, err + } + + return resp, nil +} diff --git a/github/admin_users_test.go b/github/admin_users_test.go index ad5379e2f2b..2c3b6d7ac2d 100644 --- a/github/admin_users_test.go +++ b/github/admin_users_test.go @@ -12,6 +12,7 @@ import ( "net/http" "reflect" "testing" + "time" ) func TestAdminUsers_Create(t *testing.T) { @@ -55,3 +56,74 @@ func TestAdminUsers_Delete(t *testing.T) { t.Errorf("Admin.DeleteUser returned error: %v", err) } } + +func TestUserImpersonation_Create(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/admin/users/github/authorizations", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "POST") + testBody(t, r, `{"scopes":["repo"]}`+"\n") + fmt.Fprint(w, `{"id": 1234, + "url": "https://git.company.com/api/v3/authorizations/1234", + "app": { + "name": "GitHub Site Administrator", + "url": "https://developer.github.com/v3/enterprise/users/", + "client_id": "1234" + }, + "token": "1234", + "hashed_token": "1234", + "token_last_eight": "1234", + "note": null, + "note_url": null, + "created_at": "2018-01-01T00:00:00Z", + "updated_at": "2018-01-01T00:00:00Z", + "scopes": [ + "repo" + ], + "fingerprint": null}`) + }) + + opt := &ImpersonateUserOptions{Scopes: []string{"repo"}} + auth, _, err := client.Admin.CreateUserImpersonation(context.Background(), "github", opt) + if err != nil { + t.Errorf("Admin.CreateUserImpersonation returned error: %v", err) + } + + date := Timestamp{Time: time.Date(2018, time.January, 1, 0, 0, 0, 0, time.UTC)} + want := &UserAuthorization{ + ID: Int64(1234), + URL: String("https://git.company.com/api/v3/authorizations/1234"), + App: &OAuthAPP{ + Name: String("GitHub Site Administrator"), + URL: String("https://developer.github.com/v3/enterprise/users/"), + ClientID: String("1234"), + }, + Token: String("1234"), + HashedToken: String("1234"), + TokenLastEight: String("1234"), + Note: nil, + NoteURL: nil, + CreatedAt: &date, + UpdatedAt: &date, + Scopes: []string{"repo"}, + Fingerprint: nil, + } + if !reflect.DeepEqual(auth, want) { + t.Errorf("Admin.CreateUserImpersonation returned %+v, want %+v", auth, want) + } +} + +func TestUserImpersonation_Delete(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/admin/users/github/authorizations", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "DELETE") + }) + + _, err := client.Admin.DeleteUserImpersonation(context.Background(), "github") + if err != nil { + t.Errorf("Admin.DeleteUserImpersonation returned error: %v", err) + } +} diff --git a/github/github-accessors.go b/github/github-accessors.go index b8f0765b1c5..91c235d9047 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -6252,6 +6252,30 @@ func (n *NotificationSubject) GetURL() string { return *n.URL } +// GetClientID returns the ClientID field if it's non-nil, zero value otherwise. +func (o *OAuthAPP) GetClientID() string { + if o == nil || o.ClientID == nil { + return "" + } + return *o.ClientID +} + +// GetName returns the Name field if it's non-nil, zero value otherwise. +func (o *OAuthAPP) GetName() string { + if o == nil || o.Name == nil { + return "" + } + return *o.Name +} + +// GetURL returns the URL field if it's non-nil, zero value otherwise. +func (o *OAuthAPP) GetURL() string { + if o == nil || o.URL == nil { + return "" + } + return *o.URL +} + // GetAvatarURL returns the AvatarURL field if it's non-nil, zero value otherwise. func (o *Organization) GetAvatarURL() string { if o == nil || o.AvatarURL == nil { @@ -12828,6 +12852,94 @@ func (u *User) GetURL() string { return *u.URL } +// GetApp returns the App field. +func (u *UserAuthorization) GetApp() *OAuthAPP { + if u == nil { + return nil + } + return u.App +} + +// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise. +func (u *UserAuthorization) GetCreatedAt() Timestamp { + if u == nil || u.CreatedAt == nil { + return Timestamp{} + } + return *u.CreatedAt +} + +// GetFingerprint returns the Fingerprint field if it's non-nil, zero value otherwise. +func (u *UserAuthorization) GetFingerprint() string { + if u == nil || u.Fingerprint == nil { + return "" + } + return *u.Fingerprint +} + +// GetHashedToken returns the HashedToken field if it's non-nil, zero value otherwise. +func (u *UserAuthorization) GetHashedToken() string { + if u == nil || u.HashedToken == nil { + return "" + } + return *u.HashedToken +} + +// GetID returns the ID field if it's non-nil, zero value otherwise. +func (u *UserAuthorization) GetID() int64 { + if u == nil || u.ID == nil { + return 0 + } + return *u.ID +} + +// GetNote returns the Note field if it's non-nil, zero value otherwise. +func (u *UserAuthorization) GetNote() string { + if u == nil || u.Note == nil { + return "" + } + return *u.Note +} + +// GetNoteURL returns the NoteURL field if it's non-nil, zero value otherwise. +func (u *UserAuthorization) GetNoteURL() string { + if u == nil || u.NoteURL == nil { + return "" + } + return *u.NoteURL +} + +// GetToken returns the Token field if it's non-nil, zero value otherwise. +func (u *UserAuthorization) GetToken() string { + if u == nil || u.Token == nil { + return "" + } + return *u.Token +} + +// GetTokenLastEight returns the TokenLastEight field if it's non-nil, zero value otherwise. +func (u *UserAuthorization) GetTokenLastEight() string { + if u == nil || u.TokenLastEight == nil { + return "" + } + return *u.TokenLastEight +} + +// GetUpdatedAt returns the UpdatedAt field if it's non-nil, zero value otherwise. +func (u *UserAuthorization) GetUpdatedAt() Timestamp { + if u == nil || u.UpdatedAt == nil { + return Timestamp{} + } + return *u.UpdatedAt +} + +// GetURL returns the URL field if it's non-nil, zero value otherwise. +func (u *UserAuthorization) GetURL() string { + if u == nil || u.URL == nil { + return "" + } + return *u.URL +} + // GetMessage returns the Message field if it's non-nil, zero value otherwise. func (u *UserContext) GetMessage() string { if u == nil || u.Message == nil { diff --git a/github/github-stringify_test.go b/github/github-stringify_test.go index 28ac8125dd3..04cd771cf22 100644 --- a/github/github-stringify_test.go +++ b/github/github-stringify_test.go @@ -798,6 +798,18 @@ func TestNewTeam_String(t *testing.T) { } } +func TestOAuthAPP_String(t *testing.T) { + v := OAuthAPP{ + URL: String(""), + Name: String(""), + ClientID: String(""), + } + want := `github.OAuthAPP{URL:"", Name:"", ClientID:""}` + if got := v.String(); got != want { + t.Errorf("OAuthAPP.String = %v, want %v", got, want) + } +} + func TestOrgStats_String(t *testing.T) { v := OrgStats{ TotalOrgs: Int(0), From bdfbfc679db1afad16672c8dd2eedbc4a38890ef Mon Sep 17 00:00:00 2001 From: Shibasis Patel Date: Thu, 5 Dec 2019 18:18:47 +0530 Subject: [PATCH 0086/1468] Add support for allowing apps to push to protected branches (#1283) Fixes #1275. --- github/apps.go | 24 ++++++---- github/github-accessors.go | 40 +++++++++++++++++ github/repos.go | 91 ++++++++++++++++++++++++++++++++++++++ github/repos_test.go | 86 ++++++++++++++++++++++++++++++++++- 4 files changed, 231 insertions(+), 10 deletions(-) diff --git a/github/apps.go b/github/apps.go index 913464f62fb..251ac631053 100644 --- a/github/apps.go +++ b/github/apps.go @@ -19,15 +19,18 @@ type AppsService service // App represents a GitHub App. type App struct { - ID *int64 `json:"id,omitempty"` - NodeID *string `json:"node_id,omitempty"` - Owner *User `json:"owner,omitempty"` - Name *string `json:"name,omitempty"` - Description *string `json:"description,omitempty"` - ExternalURL *string `json:"external_url,omitempty"` - HTMLURL *string `json:"html_url,omitempty"` - CreatedAt *Timestamp `json:"created_at,omitempty"` - UpdatedAt *Timestamp `json:"updated_at,omitempty"` + ID *int64 `json:"id,omitempty"` + Slug *string `json:"slug,omitempty"` + NodeID *string `json:"node_id,omitempty"` + Owner *User `json:"owner,omitempty"` + Name *string `json:"name,omitempty"` + Description *string `json:"description,omitempty"` + ExternalURL *string `json:"external_url,omitempty"` + HTMLURL *string `json:"html_url,omitempty"` + CreatedAt *Timestamp `json:"created_at,omitempty"` + UpdatedAt *Timestamp `json:"updated_at,omitempty"` + Permissions *InstallationPermissions `json:"permissions,omitempty"` + Events []*Event `json:"events,omitempty"` } // InstallationToken represents an installation token. @@ -56,10 +59,13 @@ type InstallationTokenOptions struct { // https://developer.github.com/enterprise/v3/apps/permissions/ type InstallationPermissions struct { Administration *string `json:"administration,omitempty"` + Blocking *string `json:"blocking,omitempty"` Checks *string `json:"checks,omitempty"` Contents *string `json:"contents,omitempty"` ContentReferences *string `json:"content_references,omitempty"` Deployments *string `json:"deployments,omitempty"` + Emails *string `json:"emails,omitempty"` + Followers *string `json:"followers,omitempty"` Issues *string `json:"issues,omitempty"` Metadata *string `json:"metadata,omitempty"` Members *string `json:"members,omitempty"` diff --git a/github/github-accessors.go b/github/github-accessors.go index 91c235d9047..3805905e032 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -180,6 +180,22 @@ func (a *App) GetOwner() *User { return a.Owner } +// GetPermissions returns the Permissions field. +func (a *App) GetPermissions() *InstallationPermissions { + if a == nil { + return nil + } + return a.Permissions +} + +// GetSlug returns the Slug field if it's non-nil, zero value otherwise. +func (a *App) GetSlug() string { + if a == nil || a.Slug == nil { + return "" + } + return *a.Slug +} + // GetUpdatedAt returns the UpdatedAt field if it's non-nil, zero value otherwise. func (a *App) GetUpdatedAt() Timestamp { if a == nil || a.UpdatedAt == nil { @@ -3868,6 +3884,14 @@ func (i *InstallationPermissions) GetAdministration() string { return *i.Administration } +// GetBlocking returns the Blocking field if it's non-nil, zero value otherwise. +func (i *InstallationPermissions) GetBlocking() string { + if i == nil || i.Blocking == nil { + return "" + } + return *i.Blocking +} + // GetChecks returns the Checks field if it's non-nil, zero value otherwise. func (i *InstallationPermissions) GetChecks() string { if i == nil || i.Checks == nil { @@ -3900,6 +3924,22 @@ func (i *InstallationPermissions) GetDeployments() string { return *i.Deployments } +// GetEmails returns the Emails field if it's non-nil, zero value otherwise. +func (i *InstallationPermissions) GetEmails() string { + if i == nil || i.Emails == nil { + return "" + } + return *i.Emails +} + +// GetFollowers returns the Followers field if it's non-nil, zero value otherwise. +func (i *InstallationPermissions) GetFollowers() string { + if i == nil || i.Followers == nil { + return "" + } + return *i.Followers +} + // GetIssues returns the Issues field if it's non-nil, zero value otherwise. func (i *InstallationPermissions) GetIssues() string { if i == nil || i.Issues == nil { diff --git a/github/repos.go b/github/repos.go index 1960e0a773b..934a3f8302f 100644 --- a/github/repos.go +++ b/github/repos.go @@ -791,6 +791,8 @@ type BranchRestrictions struct { Users []*User `json:"users"` // The list of team slugs with push access. Teams []*Team `json:"teams"` + // The list of app slugs with push access. + Apps []*App `json:"apps"` } // BranchRestrictionsRequest represents the request to create/edit the @@ -802,6 +804,8 @@ type BranchRestrictionsRequest struct { Users []string `json:"users"` // The list of team slugs with push access. (Required; use []string{} instead of nil for empty list.) Teams []string `json:"teams"` + // The list of app slugs with push access. + Apps []string `json:"apps,omitempty"` } // DismissalRestrictions specifies which users and teams can dismiss pull request reviews. @@ -1287,6 +1291,93 @@ func (s *RepositoriesService) ReplaceAllTopics(ctx context.Context, owner, repo return t.Names, resp, nil } +// ListApps lists the Github apps that have push access to a given protected branch. +// It requires the Github apps to have `write` access to the `content` permission. +// +// GitHub API docs: https://developer.github.com/v3/repos/branches/#list-apps-with-access-to-protected-branch +func (s *RepositoriesService) ListApps(ctx context.Context, owner, repo, branch string) ([]*App, *Response, error) { + u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/restrictions/apps", owner, repo, branch) + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + + var apps []*App + resp, err := s.client.Do(ctx, req, &apps) + if err != nil { + return nil, resp, err + } + + return apps, resp, nil +} + +// ReplaceAppRestrictions replaces the apps that have push access to a given protected branch. +// It removes all apps that previously had push access and grants push access to the new list of apps. +// It requires the Github apps to have `write` access to the `content` permission. +// +// Note: The list of users, apps, and teams in total is limited to 100 items. +// +// GitHub API docs: https://developer.github.com/v3/repos/branches/#replace-app-restrictions-of-protected-branch +func (s *RepositoriesService) ReplaceAppRestrictions(ctx context.Context, owner, repo, branch string, slug []string) ([]*App, *Response, error) { + u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/restrictions/apps", owner, repo, branch) + req, err := s.client.NewRequest("PUT", u, slug) + if err != nil { + return nil, nil, err + } + + var apps []*App + resp, err := s.client.Do(ctx, req, &apps) + if err != nil { + return nil, nil, err + } + + return apps, resp, nil +} + +// AddAppRestrictions grants the specified apps push access to a given protected branch. +// It requires the Github apps to have `write` access to the `content` permission. +// +// Note: The list of users, apps, and teams in total is limited to 100 items. +// +// GitHub API docs: https://developer.github.com/v3/repos/branches/#add-app-restrictions-of-protected-branch +func (s *RepositoriesService) AddAppRestrictions(ctx context.Context, owner, repo, branch string, slug []string) ([]*App, *Response, error) { + u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/restrictions/apps", owner, repo, branch) + req, err := s.client.NewRequest("POST", u, slug) + if err != nil { + return nil, nil, err + } + + var apps []*App + resp, err := s.client.Do(ctx, req, &apps) + if err != nil { + return nil, nil, err + } + + return apps, resp, nil +} + +// RemoveAppRestrictions removes the ability of an app to push to this branch. +// It requires the Github apps to have `write` access to the `content` permission. +// +// Note: The list of users, apps, and teams in total is limited to 100 items. +// +// GitHub API docs: https://developer.github.com/v3/repos/branches/#remove-app-restrictions-of-protected-branch +func (s *RepositoriesService) RemoveAppRestrictions(ctx context.Context, owner, repo, branch string, slug []string) ([]*App, *Response, error) { + u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/restrictions/apps", owner, repo, branch) + req, err := s.client.NewRequest("DELETE", u, slug) + if err != nil { + return nil, nil, err + } + + var apps []*App + resp, err := s.client.Do(ctx, req, &apps) + if err != nil { + return nil, nil, err + } + + return apps, resp, nil +} + // TransferRequest represents a request to transfer a repository. type TransferRequest struct { NewOwner string `json:"new_owner"` diff --git a/github/repos_test.go b/github/repos_test.go index d0fdc563d3d..b381ec55bf0 100644 --- a/github/repos_test.go +++ b/github/repos_test.go @@ -1019,6 +1019,7 @@ func TestRepositoriesService_UpdateBranchProtection(t *testing.T) { Restrictions: &BranchRestrictionsRequest{ Users: []string{"u"}, Teams: []string{"t"}, + Apps: []string{"a"}, }, } @@ -1054,7 +1055,8 @@ func TestRepositoriesService_UpdateBranchProtection(t *testing.T) { }, "restrictions":{ "users":[{"id":1,"login":"u"}], - "teams":[{"id":2,"slug":"t"}] + "teams":[{"id":2,"slug":"t"}], + "apps":[{"id":3,"slug":"a"}] } }`) }) @@ -1088,6 +1090,9 @@ func TestRepositoriesService_UpdateBranchProtection(t *testing.T) { Teams: []*Team{ {Slug: String("t"), ID: Int64(2)}, }, + Apps: []*App{ + {Slug: String("a"), ID: Int64(3)}, + }, }, } if !reflect.DeepEqual(protection, want) { @@ -1664,6 +1669,85 @@ func TestRepositoriesService_ReplaceAllTopics_emptySlice(t *testing.T) { } } +func TestRepositoriesService_ListApps(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/repos/o/r/branches/b/protection/restrictions/apps", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + }) + + _, _, err := client.Repositories.ListApps(context.Background(), "o", "r", "b") + if err != nil { + t.Errorf("Repositories.ListApps returned error: %v", err) + } +} + +func TestRepositoriesService_ReplaceAppRestrictions(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/repos/o/r/branches/b/protection/restrictions/apps", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "PUT") + fmt.Fprint(w, `[{ + "name": "octocat" + }]`) + }) + input := []string{"octocat"} + got, _, err := client.Repositories.ReplaceAppRestrictions(context.Background(), "o", "r", "b", input) + if err != nil { + t.Errorf("Repositories.ReplaceAppRestrictions returned error: %v", err) + } + want := []*App{ + {Name: String("octocat")}, + } + if !reflect.DeepEqual(got, want) { + t.Errorf("Repositories.ReplaceAppRestrictions returned %+v, want %+v", got, want) + } +} + +func TestRepositoriesService_AddAppRestrictions(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/repos/o/r/branches/b/protection/restrictions/apps", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "POST") + fmt.Fprint(w, `[{ + "name": "octocat" + }]`) + }) + input := []string{"octocat"} + got, _, err := client.Repositories.AddAppRestrictions(context.Background(), "o", "r", "b", input) + if err != nil { + t.Errorf("Repositories.AddAppRestrictions returned error: %v", err) + } + want := []*App{ + {Name: String("octocat")}, + } + if !reflect.DeepEqual(got, want) { + t.Errorf("Repositories.AddAppRestrictions returned %+v, want %+v", got, want) + } +} + +func TestRepositoriesService_RemoveAppRestrictions(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/repos/o/r/branches/b/protection/restrictions/apps", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "DELETE") + fmt.Fprint(w, `[]`) + }) + input := []string{"octocat"} + got, _, err := client.Repositories.RemoveAppRestrictions(context.Background(), "o", "r", "b", input) + if err != nil { + t.Errorf("Repositories.RemoveAppRestrictions returned error: %v", err) + } + want := []*App{} + if !reflect.DeepEqual(got, want) { + t.Errorf("Repositories.RemoveAppRestrictions returned %+v, want %+v", got, want) + } +} + func TestRepositoriesService_Transfer(t *testing.T) { client, mux, _, teardown := setup() defer teardown() From f6e074d7fdfd72604c260d21b17c09ac73b7335c Mon Sep 17 00:00:00 2001 From: Willem D'Haeseleer Date: Thu, 5 Dec 2019 04:51:24 -0800 Subject: [PATCH 0087/1468] Support delete files for CreateTree (#1310) Fixes #1268. --- github/git_trees.go | 34 +++++++++++++++++++++ github/git_trees_test.go | 66 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 100 insertions(+) diff --git a/github/git_trees.go b/github/git_trees.go index 4bc2913541a..df843f4de9a 100644 --- a/github/git_trees.go +++ b/github/git_trees.go @@ -7,6 +7,7 @@ package github import ( "context" + "encoding/json" "fmt" ) @@ -43,6 +44,39 @@ func (t TreeEntry) String() string { return Stringify(t) } +func (t *TreeEntry) MarshalJSON() ([]byte, error) { + if t.SHA == nil && t.Content == nil { + return json.Marshal(struct { + SHA *string `json:"sha"` + Path *string `json:"path,omitempty"` + Mode *string `json:"mode,omitempty"` + Type *string `json:"type,omitempty"` + }{ + nil, + t.Path, + t.Mode, + t.Type, + }) + } + return json.Marshal(struct { + SHA *string `json:"sha,omitempty"` + Path *string `json:"path,omitempty"` + Mode *string `json:"mode,omitempty"` + Type *string `json:"type,omitempty"` + Size *int `json:"size,omitempty"` + Content *string `json:"content,omitempty"` + URL *string `json:"url,omitempty"` + }{ + SHA: t.SHA, + Path: t.Path, + Mode: t.Mode, + Type: t.Type, + Size: t.Size, + Content: t.Content, + URL: t.URL, + }) +} + // GetTree fetches the Tree object for a given sha hash from a repository. // // GitHub API docs: https://developer.github.com/v3/git/trees/#get-a-tree diff --git a/github/git_trees_test.go b/github/git_trees_test.go index 1f7024fc052..1d1b789cd6f 100644 --- a/github/git_trees_test.go +++ b/github/git_trees_test.go @@ -186,6 +186,72 @@ func TestGitService_CreateTree_Content(t *testing.T) { } } +func TestGitService_CreateTree_Delete(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + input := []TreeEntry{ + { + Path: String("content.md"), + Mode: String("100644"), + }, + } + + mux.HandleFunc("/repos/o/r/git/trees", func(w http.ResponseWriter, r *http.Request) { + v := new(createTree) + json.NewDecoder(r.Body).Decode(v) + + testMethod(t, r, "POST") + + want := &createTree{ + BaseTree: "b", + Entries: input, + } + if !reflect.DeepEqual(v, want) { + t.Errorf("Git.CreateTree request body: %+v, want %+v", v, want) + } + + fmt.Fprint(w, `{ + "sha": "5c6780ad2c68743383b740fd1dab6f6a33202b11", + "url": "https://api.github.com/repos/o/r/git/trees/5c6780ad2c68743383b740fd1dab6f6a33202b11", + "tree": [ + { + "mode": "100644", + "type": "blob", + "sha": null, + "path": "content.md", + "size": 12, + "url": "https://api.github.com/repos/o/r/git/blobs/aad8feacf6f8063150476a7b2bd9770f2794c08b" + } + ] + }`) + }) + + tree, _, err := client.Git.CreateTree(context.Background(), "o", "r", "b", input) + if err != nil { + t.Errorf("Git.CreateTree returned error: %v", err) + } + + want := Tree{ + String("5c6780ad2c68743383b740fd1dab6f6a33202b11"), + []TreeEntry{ + { + Path: String("content.md"), + Mode: String("100644"), + Type: String("blob"), + Size: Int(12), + SHA: nil, + URL: String("https://api.github.com/repos/o/r/git/blobs/aad8feacf6f8063150476a7b2bd9770f2794c08b"), + }, + }, + nil, + } + + if !reflect.DeepEqual(*tree, want) { + t.Errorf("Git.CreateTree returned %+v, want %+v", *tree, want) + } +} + func TestGitService_CreateTree_invalidOwner(t *testing.T) { client, _, _, teardown := setup() defer teardown() From 10891412a8c284c4d919633e2a5cda70189e99a2 Mon Sep 17 00:00:00 2001 From: Joshua Bezaleel Abednego Date: Thu, 5 Dec 2019 19:52:21 +0700 Subject: [PATCH 0088/1468] Add ListCommentReactionOptions to ListCommentReactions (#1282) Fixes #1281. --- github/reactions.go | 13 ++++++++++++- github/reactions_test.go | 12 +++++++----- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/github/reactions.go b/github/reactions.go index 0865f8cdca4..1935ce11174 100644 --- a/github/reactions.go +++ b/github/reactions.go @@ -44,10 +44,21 @@ func (r Reaction) String() string { return Stringify(r) } +// ListCommentReactionOptions specifies the optional parameters to the +// ReactionsService.ListCommentReactions method. +type ListCommentReactionOptions struct { + // Content restricts the returned comment reactions to only those with the given type. + // Omit this parameter to list all reactions to a commit comment. + // Possible values are: "+1", "-1", "laugh", "confused", "heart", "hooray", "rocket", or "eyes". + Content string `url:"content,omitempty"` + + ListOptions +} + // ListCommentReactions lists the reactions for a commit comment. // // GitHub API docs: https://developer.github.com/v3/reactions/#list-reactions-for-a-commit-comment -func (s *ReactionsService) ListCommentReactions(ctx context.Context, owner, repo string, id int64, opt *ListOptions) ([]*Reaction, *Response, error) { +func (s *ReactionsService) ListCommentReactions(ctx context.Context, owner, repo string, id int64, opt *ListCommentReactionOptions) ([]*Reaction, *Response, error) { u := fmt.Sprintf("repos/%v/%v/comments/%v/reactions", owner, repo, id) u, err := addOptions(u, opt) if err != nil { diff --git a/github/reactions_test.go b/github/reactions_test.go index ef1660d9af7..c32274dec53 100644 --- a/github/reactions_test.go +++ b/github/reactions_test.go @@ -7,6 +7,7 @@ package github import ( "context" + "fmt" "net/http" "reflect" "testing" @@ -67,17 +68,18 @@ func TestReactionsService_ListCommentReactions(t *testing.T) { testMethod(t, r, "GET") testHeader(t, r, "Accept", mediaTypeReactionsPreview) - w.WriteHeader(http.StatusOK) - w.Write([]byte(`[{"id":1,"user":{"login":"l","id":2},"content":"+1"}]`)) + testFormValues(t, r, values{"content": "+1"}) + fmt.Fprint(w, `[{"id":1,"user":{"login":"l","id":2},"content":"+1"}]`) }) - got, _, err := client.Reactions.ListCommentReactions(context.Background(), "o", "r", 1, nil) + opt := &ListCommentReactionOptions{Content: "+1"} + reactions, _, err := client.Reactions.ListCommentReactions(context.Background(), "o", "r", 1, opt) if err != nil { t.Errorf("ListCommentReactions returned error: %v", err) } want := []*Reaction{{ID: Int64(1), User: &User{Login: String("l"), ID: Int64(2)}, Content: String("+1")}} - if !reflect.DeepEqual(got, want) { - t.Errorf("ListCommentReactions = %+v, want %+v", got, want) + if !reflect.DeepEqual(reactions, want) { + t.Errorf("ListCommentReactions = %+v, want %+v", reactions, want) } } From b1ff3c518fefa41463d3dc158239a4538c0ef305 Mon Sep 17 00:00:00 2001 From: Sander Knape Date: Thu, 5 Dec 2019 13:53:51 +0100 Subject: [PATCH 0089/1468] Add vulnerability-alerts GET endpoint (#1342) Fixes #1341. --- github/repos.go | 20 ++++++++++++++++++++ github/repos_test.go | 21 +++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/github/repos.go b/github/repos.go index 934a3f8302f..34f22ebce05 100644 --- a/github/repos.go +++ b/github/repos.go @@ -519,6 +519,26 @@ type ListContributorsOptions struct { ListOptions } +// GetVulnerabilityAlerts checks if vulnerability alerts are enabled for a repository. +// +// GitHub API docs: https://developer.github.com/v3/repos/#check-if-vulnerability-alerts-are-enabled-for-a-repository +func (s *RepositoriesService) GetVulnerabilityAlerts(ctx context.Context, owner, repository string) (bool, *Response, error) { + u := fmt.Sprintf("repos/%v/%v/vulnerability-alerts", owner, repository) + + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return false, nil, err + } + + // TODO: remove custom Accept header when this API fully launches + req.Header.Set("Accept", mediaTypeRequiredVulnerabilityAlertsPreview) + + resp, err := s.client.Do(ctx, req, nil) + vulnerabilityAlertsEnabled, err := parseBoolResponse(err) + + return vulnerabilityAlertsEnabled, resp, err +} + // EnableVulnerabilityAlerts enables vulnerability alerts and the dependency graph for a repository. // // GitHub API docs: https://developer.github.com/v3/repos/#enable-vulnerability-alerts diff --git a/github/repos_test.go b/github/repos_test.go index b381ec55bf0..3b2893bcb73 100644 --- a/github/repos_test.go +++ b/github/repos_test.go @@ -630,6 +630,27 @@ func TestRepositoriesService_Edit_invalidOwner(t *testing.T) { testURLParseError(t, err) } +func TestRepositoriesService_GetVulnerabilityAlerts(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/repos/o/r/vulnerability-alerts", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + testHeader(t, r, "Accept", mediaTypeRequiredVulnerabilityAlertsPreview) + + w.WriteHeader(http.StatusNoContent) + }) + + vulnerabilityAlertsEnabled, _, err := client.Repositories.GetVulnerabilityAlerts(context.Background(), "o", "r") + if err != nil { + t.Errorf("Repositories.GetVulnerabilityAlerts returned error: %v", err) + } + + if want := true; vulnerabilityAlertsEnabled != want { + t.Errorf("Repositories.GetVulnerabilityAlerts returned %+v, want %+v", vulnerabilityAlertsEnabled, want) + } +} + func TestRepositoriesService_EnableVulnerabilityAlerts(t *testing.T) { client, mux, _, teardown := setup() defer teardown() From 0e41ab9770b24c2a6e6327575591a35268a64656 Mon Sep 17 00:00:00 2001 From: tkhandel Date: Thu, 5 Dec 2019 07:55:17 -0500 Subject: [PATCH 0090/1468] Simplify rate limit error check (#1321) Fixes #1318. --- github/github.go | 4 ++-- github/github_test.go | 50 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 2 deletions(-) diff --git a/github/github.go b/github/github.go index f5398325747..3f4edd4ac3a 100644 --- a/github/github.go +++ b/github/github.go @@ -642,7 +642,7 @@ type TwoFactorAuthError ErrorResponse func (r *TwoFactorAuthError) Error() string { return (*ErrorResponse)(r).Error() } // RateLimitError occurs when GitHub returns 403 Forbidden response with a rate limit -// remaining value of 0, and error message starts with "API rate limit exceeded for ". +// remaining value of 0. type RateLimitError struct { Rate Rate // Rate specifies last known rate limit for the client Response *http.Response // HTTP response that caused this error @@ -757,7 +757,7 @@ func CheckResponse(r *http.Response) error { switch { case r.StatusCode == http.StatusUnauthorized && strings.HasPrefix(r.Header.Get(headerOTP), "required"): return (*TwoFactorAuthError)(errorResponse) - case r.StatusCode == http.StatusForbidden && r.Header.Get(headerRateRemaining) == "0" && strings.HasPrefix(errorResponse.Message, "API rate limit exceeded for "): + case r.StatusCode == http.StatusForbidden && r.Header.Get(headerRateRemaining) == "0": return &RateLimitError{ Rate: parseRate(r), Response: errorResponse.Response, diff --git a/github/github_test.go b/github/github_test.go index 9dfac059f3f..cb342382c05 100644 --- a/github/github_test.go +++ b/github/github_test.go @@ -862,6 +862,56 @@ func TestCheckResponse(t *testing.T) { } } +func TestCheckResponse_RateLimit(t *testing.T) { + res := &http.Response{ + Request: &http.Request{}, + StatusCode: http.StatusForbidden, + Header: http.Header{}, + Body: ioutil.NopCloser(strings.NewReader(`{"message":"m", + "documentation_url": "url"}`)), + } + res.Header.Set(headerRateLimit, "60") + res.Header.Set(headerRateRemaining, "0") + res.Header.Set(headerRateReset, "243424") + + err := CheckResponse(res).(*RateLimitError) + + if err == nil { + t.Errorf("Expected error response.") + } + + want := &RateLimitError{ + Rate: parseRate(res), + Response: res, + Message: "m", + } + if !reflect.DeepEqual(err, want) { + t.Errorf("Error = %#v, want %#v", err, want) + } +} + +func TestCheckResponse_AbuseRateLimit(t *testing.T) { + res := &http.Response{ + Request: &http.Request{}, + StatusCode: http.StatusForbidden, + Body: ioutil.NopCloser(strings.NewReader(`{"message":"m", + "documentation_url": "developer.github.com/v3/#abuse-rate-limits"}`)), + } + err := CheckResponse(res).(*AbuseRateLimitError) + + if err == nil { + t.Errorf("Expected error response.") + } + + want := &AbuseRateLimitError{ + Response: res, + Message: "m", + } + if !reflect.DeepEqual(err, want) { + t.Errorf("Error = %#v, want %#v", err, want) + } +} + // ensure that we properly handle API errors that do not contain a response body func TestCheckResponse_noBody(t *testing.T) { res := &http.Response{ From 81eca3eea39b515a6118091f2ec32a19a71bb2c3 Mon Sep 17 00:00:00 2001 From: Sergio Garcia Date: Thu, 5 Dec 2019 07:56:52 -0500 Subject: [PATCH 0091/1468] Test for marshalling Organizations and make JSON comparison non sensitive to key order (#1303) Helps #55. --- github/github_test.go | 32 ++++++++++++++------------------ github/orgs_test.go | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 18 deletions(-) diff --git a/github/github_test.go b/github/github_test.go index cb342382c05..759d76c5645 100644 --- a/github/github_test.go +++ b/github/github_test.go @@ -6,7 +6,6 @@ package github import ( - "bytes" "context" "encoding/json" "fmt" @@ -135,32 +134,29 @@ func testBody(t *testing.T, r *http.Request, want string) { } } -// Helper function to test that a value is marshalled to JSON as expected. +// Test whether the marshaling of v produces JSON that corresponds +// to the want string. func testJSONMarshal(t *testing.T, v interface{}, want string) { - j, err := json.Marshal(v) + // Unmarshal the wanted JSON, to verify its correctness, and marshal it back + // to sort the keys. + u := reflect.New(reflect.TypeOf(v)).Interface() + if err := json.Unmarshal([]byte(want), &u); err != nil { + t.Errorf("Unable to unmarshal JSON for %v: %v", want, err) + } + w, err := json.Marshal(u) if err != nil { - t.Errorf("Unable to marshal JSON for %v", v) + t.Errorf("Unable to marshal JSON for %#v", u) } - w := new(bytes.Buffer) - err = json.Compact(w, []byte(want)) + // Marshal the target value. + j, err := json.Marshal(v) if err != nil { - t.Errorf("String is not valid json: %s", want) + t.Errorf("Unable to marshal JSON for %#v", v) } - if w.String() != string(j) { + if string(w) != string(j) { t.Errorf("json.Marshal(%q) returned %s, want %s", v, j, w) } - - // now go the other direction and make sure things unmarshal as expected - u := reflect.ValueOf(v).Interface() - if err := json.Unmarshal([]byte(want), u); err != nil { - t.Errorf("Unable to unmarshal JSON for %v: %v", want, err) - } - - if !reflect.DeepEqual(v, u) { - t.Errorf("json.Unmarshal(%q) returned %s, want %s", want, u, v) - } } func TestNewClient(t *testing.T) { diff --git a/github/orgs_test.go b/github/orgs_test.go index 9383bf11c3e..c39f6097283 100644 --- a/github/orgs_test.go +++ b/github/orgs_test.go @@ -14,6 +14,38 @@ import ( "testing" ) +func TestOrganization_marshal(t *testing.T) { + testJSONMarshal(t, &Organization{}, "{}") + + o := &Organization{ + BillingEmail: String("support@github.com"), + Blog: String("https://github.com/blog"), + Company: String("GitHub"), + Email: String("support@github.com"), + Location: String("San Francisco"), + Name: String("github"), + Description: String("GitHub, the company."), + DefaultRepoPermission: String("read"), + MembersCanCreateRepos: Bool(true), + MembersAllowedRepositoryCreationType: String("all"), + } + want := ` + { + "billing_email": "support@github.com", + "blog": "https://github.com/blog", + "company": "GitHub", + "email": "support@github.com", + "location": "San Francisco", + "name": "github", + "description": "GitHub, the company.", + "default_repository_permission": "read", + "members_can_create_repositories": true, + "members_allowed_repository_creation_type": "all" + } + ` + testJSONMarshal(t, o, want) +} + func TestOrganizationsService_ListAll(t *testing.T) { client, mux, _, teardown := setup() defer teardown() From 59e8d177dc7711d2ae71e77291d27c573ef6c8e0 Mon Sep 17 00:00:00 2001 From: safwan olaimat Date: Thu, 5 Dec 2019 15:00:39 +0200 Subject: [PATCH 0092/1468] Add struct response for AddCollaborator function (#1330) Fixes #1329. --- github/github-accessors.go | 64 ++++++++++++++++++++++++++++++ github/repos_collaborators.go | 25 ++++++++++-- github/repos_collaborators_test.go | 32 +++++++++++---- 3 files changed, 110 insertions(+), 11 deletions(-) diff --git a/github/github-accessors.go b/github/github-accessors.go index 3805905e032..b26ee6b7fd5 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -1196,6 +1196,70 @@ func (c *CodeSearchResult) GetTotal() int { return *c.Total } +// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise. +func (c *CollaboratorInvitation) GetCreatedAt() Timestamp { + if c == nil || c.CreatedAt == nil { + return Timestamp{} + } + return *c.CreatedAt +} + +// GetHTMLURL returns the HTMLURL field if it's non-nil, zero value otherwise. +func (c *CollaboratorInvitation) GetHTMLURL() string { + if c == nil || c.HTMLURL == nil { + return "" + } + return *c.HTMLURL +} + +// GetID returns the ID field if it's non-nil, zero value otherwise. +func (c *CollaboratorInvitation) GetID() int64 { + if c == nil || c.ID == nil { + return 0 + } + return *c.ID +} + +// GetInvitee returns the Invitee field. +func (c *CollaboratorInvitation) GetInvitee() *User { + if c == nil { + return nil + } + return c.Invitee +} + +// GetInviter returns the Inviter field. +func (c *CollaboratorInvitation) GetInviter() *User { + if c == nil { + return nil + } + return c.Inviter +} + +// GetPermissions returns the Permissions field if it's non-nil, zero value otherwise. +func (c *CollaboratorInvitation) GetPermissions() string { + if c == nil || c.Permissions == nil { + return "" + } + return *c.Permissions +} + +// GetRepo returns the Repo field. +func (c *CollaboratorInvitation) GetRepo() *Repository { + if c == nil { + return nil + } + return c.Repo +} + +// GetURL returns the URL field if it's non-nil, zero value otherwise. +func (c *CollaboratorInvitation) GetURL() string { + if c == nil || c.URL == nil { + return "" + } + return *c.URL +} + // GetCommitURL returns the CommitURL field if it's non-nil, zero value otherwise. func (c *CombinedStatus) GetCommitURL() string { if c == nil || c.CommitURL == nil { diff --git a/github/repos_collaborators.go b/github/repos_collaborators.go index 757e9f39e44..04d8068720c 100644 --- a/github/repos_collaborators.go +++ b/github/repos_collaborators.go @@ -26,6 +26,19 @@ type ListCollaboratorsOptions struct { ListOptions } +// CollaboratorInvitation represents an invitation created when adding a collaborator. +// GitHub API docs: https://developer.github.com/v3/repos/collaborators/#response-when-a-new-invitation-is-created +type CollaboratorInvitation struct { + ID *int64 `json:"id,omitempty"` + Repo *Repository `json:"repository,omitempty"` + Invitee *User `json:"invitee,omitempty"` + Inviter *User `json:"inviter,omitempty"` + Permissions *string `json:"permissions,omitempty"` + CreatedAt *Timestamp `json:"created_at,omitempty"` + URL *string `json:"url,omitempty"` + HTMLURL *string `json:"html_url,omitempty"` +} + // ListCollaborators lists the GitHub users that have access to the repository. // // GitHub API docs: https://developer.github.com/v3/repos/collaborators/#list-collaborators @@ -113,14 +126,18 @@ type RepositoryAddCollaboratorOptions struct { // to become a collaborator to the given repo. // // GitHub API docs: https://developer.github.com/v3/repos/collaborators/#add-user-as-a-collaborator -func (s *RepositoriesService) AddCollaborator(ctx context.Context, owner, repo, user string, opt *RepositoryAddCollaboratorOptions) (*Response, error) { +func (s *RepositoriesService) AddCollaborator(ctx context.Context, owner, repo, user string, opt *RepositoryAddCollaboratorOptions) (*CollaboratorInvitation, *Response, error) { u := fmt.Sprintf("repos/%v/%v/collaborators/%v", owner, repo, user) req, err := s.client.NewRequest("PUT", u, opt) if err != nil { - return nil, err + return nil, nil, err } - - return s.client.Do(ctx, req, nil) + acr := new(CollaboratorInvitation) + resp, err := s.client.Do(ctx, req, acr) + if err != nil { + return nil, resp, err + } + return acr, resp, nil } // RemoveCollaborator removes the specified GitHub user as collaborator from the given repo. diff --git a/github/repos_collaborators_test.go b/github/repos_collaborators_test.go index a4d3210c8ff..d2165579cb1 100644 --- a/github/repos_collaborators_test.go +++ b/github/repos_collaborators_test.go @@ -149,30 +149,48 @@ func TestRepositoriesService_AddCollaborator(t *testing.T) { defer teardown() opt := &RepositoryAddCollaboratorOptions{Permission: "admin"} - mux.HandleFunc("/repos/o/r/collaborators/u", func(w http.ResponseWriter, r *http.Request) { v := new(RepositoryAddCollaboratorOptions) json.NewDecoder(r.Body).Decode(v) - testMethod(t, r, "PUT") if !reflect.DeepEqual(v, opt) { t.Errorf("Request body = %+v, want %+v", v, opt) } - - w.WriteHeader(http.StatusNoContent) + w.WriteHeader(http.StatusOK) + w.Write([]byte(`{"permissions": "write","url": "https://api.github.com/user/repository_invitations/1296269","html_url": "https://github.com/octocat/Hello-World/invitations","id":1,"permissions":"write","repository":{"url":"s","name":"r","id":1},"invitee":{"login":"u"},"inviter":{"login":"o"}}`)) }) - - _, err := client.Repositories.AddCollaborator(context.Background(), "o", "r", "u", opt) + collaboratorInvitation, _, err := client.Repositories.AddCollaborator(context.Background(), "o", "r", "u", opt) if err != nil { t.Errorf("Repositories.AddCollaborator returned error: %v", err) } + want := &CollaboratorInvitation{ + ID: Int64(1), + Repo: &Repository{ + ID: Int64(1), + URL: String("s"), + Name: String("r"), + }, + Invitee: &User{ + Login: String("u"), + }, + Inviter: &User{ + Login: String("o"), + }, + Permissions: String("write"), + URL: String("https://api.github.com/user/repository_invitations/1296269"), + HTMLURL: String("https://github.com/octocat/Hello-World/invitations"), + } + + if !reflect.DeepEqual(collaboratorInvitation, want) { + t.Errorf("AddCollaborator returned %+v, want %+v", collaboratorInvitation, want) + } } func TestRepositoriesService_AddCollaborator_invalidUser(t *testing.T) { client, _, _, teardown := setup() defer teardown() - _, err := client.Repositories.AddCollaborator(context.Background(), "%", "%", "%", nil) + _, _, err := client.Repositories.AddCollaborator(context.Background(), "%", "%", "%", nil) testURLParseError(t, err) } From 043128dfaa65c433de3416420afc335aea58a372 Mon Sep 17 00:00:00 2001 From: Glenn Lewis <6598971+gmlewis@users.noreply.github.com> Date: Sat, 7 Dec 2019 22:21:29 -0500 Subject: [PATCH 0093/1468] Add note about force-push (#1349) --- CONTRIBUTING.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e2a2b282db1..bd7db848cfc 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -64,6 +64,9 @@ are more sensitive, emailed to . messages are able to be formatted properly by various git tools. 1. Finally, push the commits to your fork and submit a [pull request][]. + **NOTE:** Please do not use force-push on PRs in this repo, as it makes + it more difficult for reviewers to see what has changed since the last + code review. [forking]: https://help.github.com/articles/fork-a-repo [golint]: https://github.com/golang/lint From fd8be9c18eee90b2dec83aa6c3b322a13c20576a Mon Sep 17 00:00:00 2001 From: Rajat Jindal Date: Mon, 9 Dec 2019 19:48:53 +0530 Subject: [PATCH 0094/1468] Support new fields in Organization struct (#1347) Fixes #1346. --- github/github-accessors.go | 24 ++++++++++++++++++++++++ github/github-stringify_test.go | 5 ++++- github/orgs.go | 12 ++++++++++++ github/orgs_test.go | 7 +++++++ 4 files changed, 47 insertions(+), 1 deletion(-) diff --git a/github/github-accessors.go b/github/github-accessors.go index b26ee6b7fd5..1454e221685 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -6548,6 +6548,30 @@ func (o *Organization) GetMembersAllowedRepositoryCreationType() string { return *o.MembersAllowedRepositoryCreationType } +// GetMembersCanCreateInternalRepos returns the MembersCanCreateInternalRepos field if it's non-nil, zero value otherwise. +func (o *Organization) GetMembersCanCreateInternalRepos() bool { + if o == nil || o.MembersCanCreateInternalRepos == nil { + return false + } + return *o.MembersCanCreateInternalRepos +} + +// GetMembersCanCreatePrivateRepos returns the MembersCanCreatePrivateRepos field if it's non-nil, zero value otherwise. +func (o *Organization) GetMembersCanCreatePrivateRepos() bool { + if o == nil || o.MembersCanCreatePrivateRepos == nil { + return false + } + return *o.MembersCanCreatePrivateRepos +} + +// GetMembersCanCreatePublicRepos returns the MembersCanCreatePublicRepos field if it's non-nil, zero value otherwise. +func (o *Organization) GetMembersCanCreatePublicRepos() bool { + if o == nil || o.MembersCanCreatePublicRepos == nil { + return false + } + return *o.MembersCanCreatePublicRepos +} + // GetMembersCanCreateRepos returns the MembersCanCreateRepos field if it's non-nil, zero value otherwise. func (o *Organization) GetMembersCanCreateRepos() bool { if o == nil || o.MembersCanCreateRepos == nil { diff --git a/github/github-stringify_test.go b/github/github-stringify_test.go index 04cd771cf22..2216c8c4052 100644 --- a/github/github-stringify_test.go +++ b/github/github-stringify_test.go @@ -852,6 +852,9 @@ func TestOrganization_String(t *testing.T) { DefaultRepoPermission: String(""), DefaultRepoSettings: String(""), MembersCanCreateRepos: Bool(false), + MembersCanCreatePublicRepos: Bool(false), + MembersCanCreatePrivateRepos: Bool(false), + MembersCanCreateInternalRepos: Bool(false), MembersAllowedRepositoryCreationType: String(""), URL: String(""), EventsURL: String(""), @@ -861,7 +864,7 @@ func TestOrganization_String(t *testing.T) { PublicMembersURL: String(""), ReposURL: String(""), } - want := `github.Organization{Login:"", ID:0, NodeID:"", AvatarURL:"", HTMLURL:"", Name:"", Company:"", Blog:"", Location:"", Email:"", Description:"", PublicRepos:0, PublicGists:0, Followers:0, Following:0, TotalPrivateRepos:0, OwnedPrivateRepos:0, PrivateGists:0, DiskUsage:0, Collaborators:0, BillingEmail:"", Type:"", Plan:github.Plan{}, TwoFactorRequirementEnabled:false, DefaultRepoPermission:"", DefaultRepoSettings:"", MembersCanCreateRepos:false, MembersAllowedRepositoryCreationType:"", URL:"", EventsURL:"", HooksURL:"", IssuesURL:"", MembersURL:"", PublicMembersURL:"", ReposURL:""}` + want := `github.Organization{Login:"", ID:0, NodeID:"", AvatarURL:"", HTMLURL:"", Name:"", Company:"", Blog:"", Location:"", Email:"", Description:"", PublicRepos:0, PublicGists:0, Followers:0, Following:0, TotalPrivateRepos:0, OwnedPrivateRepos:0, PrivateGists:0, DiskUsage:0, Collaborators:0, BillingEmail:"", Type:"", Plan:github.Plan{}, TwoFactorRequirementEnabled:false, DefaultRepoPermission:"", DefaultRepoSettings:"", MembersCanCreateRepos:false, MembersCanCreatePublicRepos:false, MembersCanCreatePrivateRepos:false, MembersCanCreateInternalRepos:false, MembersAllowedRepositoryCreationType:"", URL:"", EventsURL:"", HooksURL:"", IssuesURL:"", MembersURL:"", PublicMembersURL:"", ReposURL:""}` if got := v.String(); got != want { t.Errorf("Organization.String = %v, want %v", got, want) } diff --git a/github/orgs.go b/github/orgs.go index 5012c6c9f1c..bae67dad580 100644 --- a/github/orgs.go +++ b/github/orgs.go @@ -56,8 +56,17 @@ type Organization struct { // MembersCanCreateRepos default value is true and is only used in Organizations.Edit. MembersCanCreateRepos *bool `json:"members_can_create_repositories,omitempty"` + // https://developer.github.com/changes/2019-12-03-internal-visibility-changes/#rest-v3-api + MembersCanCreatePublicRepos *bool `json:"members_can_create_public_repositories,omitempty"` + MembersCanCreatePrivateRepos *bool `json:"members_can_create_private_repositories,omitempty"` + MembersCanCreateInternalRepos *bool `json:"members_can_create_internal_repositories,omitempty"` + // MembersAllowedRepositoryCreationType denotes if organization members can create repositories // and the type of repositories they can create. Possible values are: "all", "private", or "none". + // + // Deprecated: Use MembersCanCreatePublicRepos, MembersCanCreatePrivateRepos, MembersCanCreateInternalRepos + // instead. The new fields overrides the existing MembersAllowedRepositoryCreationType during 'edit' + // operation and does not consider 'internal' repositories during 'get' operation MembersAllowedRepositoryCreationType *string `json:"members_allowed_repository_creation_type,omitempty"` // API URLs @@ -213,6 +222,9 @@ func (s *OrganizationsService) Edit(ctx context.Context, name string, org *Organ return nil, nil, err } + // TODO: remove custom Accept header when this API fully launches. + req.Header.Set("Accept", mediaTypeMemberAllowedRepoCreationTypePreview) + o := new(Organization) resp, err := s.client.Do(ctx, req, o) if err != nil { diff --git a/github/orgs_test.go b/github/orgs_test.go index c39f6097283..cf69453c33f 100644 --- a/github/orgs_test.go +++ b/github/orgs_test.go @@ -27,6 +27,9 @@ func TestOrganization_marshal(t *testing.T) { Description: String("GitHub, the company."), DefaultRepoPermission: String("read"), MembersCanCreateRepos: Bool(true), + MembersCanCreateInternalRepos: Bool(true), + MembersCanCreatePrivateRepos: Bool(true), + MembersCanCreatePublicRepos: Bool(false), MembersAllowedRepositoryCreationType: String("all"), } want := ` @@ -40,6 +43,9 @@ func TestOrganization_marshal(t *testing.T) { "description": "GitHub, the company.", "default_repository_permission": "read", "members_can_create_repositories": true, + "members_can_create_public_repositories": false, + "members_can_create_private_repositories": true, + "members_can_create_internal_repositories": true, "members_allowed_repository_creation_type": "all" } ` @@ -178,6 +184,7 @@ func TestOrganizationsService_Edit(t *testing.T) { v := new(Organization) json.NewDecoder(r.Body).Decode(v) + testHeader(t, r, "Accept", mediaTypeMemberAllowedRepoCreationTypePreview) testMethod(t, r, "PATCH") if !reflect.DeepEqual(v, input) { t.Errorf("Request body = %+v, want %+v", v, input) From 1a07ca55c956bb1e859c72922ddea5a7a989b378 Mon Sep 17 00:00:00 2001 From: Ioannis Georgoulas Date: Mon, 9 Dec 2019 14:20:32 +0000 Subject: [PATCH 0095/1468] Add context nil check on client Doer (#1348) Fixes #1260. --- github/github.go | 5 ++++- github/github_test.go | 13 +++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/github/github.go b/github/github.go index 3f4edd4ac3a..1084412c252 100644 --- a/github/github.go +++ b/github/github.go @@ -498,9 +498,12 @@ func parseRate(r *http.Response) Rate { // first decode it. If rate limit is exceeded and reset time is in the future, // Do returns *RateLimitError immediately without making a network API call. // -// The provided ctx must be non-nil. If it is canceled or times out, +// The provided ctx must be non-nil, if it is nil an error is returned. If it is canceled or times out, // ctx.Err() will be returned. func (c *Client) Do(ctx context.Context, req *http.Request, v interface{}) (*Response, error) { + if ctx == nil { + return nil, errors.New("context must be non-nil") + } req = withContext(ctx, req) rateLimitCategory := category(req.URL.Path) diff --git a/github/github_test.go b/github/github_test.go index 759d76c5645..1aa3ef9b1bb 100644 --- a/github/github_test.go +++ b/github/github_test.go @@ -8,6 +8,7 @@ package github import ( "context" "encoding/json" + "errors" "fmt" "io/ioutil" "net/http" @@ -477,6 +478,18 @@ func TestDo(t *testing.T) { } } +func TestDo_nilContext(t *testing.T) { + client, _, _, teardown := setup() + defer teardown() + + req, _ := client.NewRequest("GET", ".", nil) + _, err := client.Do(nil, req, nil) + + if !reflect.DeepEqual(err, errors.New("context must be non-nil")) { + t.Errorf("Expected context must be non-nil error") + } +} + func TestDo_httpError(t *testing.T) { client, mux, _, teardown := setup() defer teardown() From 98728187b839fbc96f91171dfe97cc5978788e2d Mon Sep 17 00:00:00 2001 From: Glenn Lewis <6598971+gmlewis@users.noreply.github.com> Date: Mon, 23 Dec 2019 14:24:04 -0500 Subject: [PATCH 0096/1468] Allow any Payload during deployment creation (#1119) Fixes #1116. --- github/github-accessors.go | 8 -------- github/repos_deployments.go | 18 +++++++++--------- 2 files changed, 9 insertions(+), 17 deletions(-) diff --git a/github/github-accessors.go b/github/github-accessors.go index 1454e221685..0c1edd7aeb5 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -2404,14 +2404,6 @@ func (d *DeploymentRequest) GetEnvironment() string { return *d.Environment } -// GetPayload returns the Payload field if it's non-nil, zero value otherwise. -func (d *DeploymentRequest) GetPayload() string { - if d == nil || d.Payload == nil { - return "" - } - return *d.Payload -} - // GetProductionEnvironment returns the ProductionEnvironment field if it's non-nil, zero value otherwise. func (d *DeploymentRequest) GetProductionEnvironment() bool { if d == nil || d.ProductionEnvironment == nil { diff --git a/github/repos_deployments.go b/github/repos_deployments.go index 604632e91b6..6453345e042 100644 --- a/github/repos_deployments.go +++ b/github/repos_deployments.go @@ -32,15 +32,15 @@ type Deployment struct { // DeploymentRequest represents a deployment request type DeploymentRequest struct { - Ref *string `json:"ref,omitempty"` - Task *string `json:"task,omitempty"` - AutoMerge *bool `json:"auto_merge,omitempty"` - RequiredContexts *[]string `json:"required_contexts,omitempty"` - Payload *string `json:"payload,omitempty"` - Environment *string `json:"environment,omitempty"` - Description *string `json:"description,omitempty"` - TransientEnvironment *bool `json:"transient_environment,omitempty"` - ProductionEnvironment *bool `json:"production_environment,omitempty"` + Ref *string `json:"ref,omitempty"` + Task *string `json:"task,omitempty"` + AutoMerge *bool `json:"auto_merge,omitempty"` + RequiredContexts *[]string `json:"required_contexts,omitempty"` + Payload interface{} `json:"payload,omitempty"` + Environment *string `json:"environment,omitempty"` + Description *string `json:"description,omitempty"` + TransientEnvironment *bool `json:"transient_environment,omitempty"` + ProductionEnvironment *bool `json:"production_environment,omitempty"` } // DeploymentsListOptions specifies the optional parameters to the From 35682d88e4f1c2ee9ad5dea2dd44efaa2e399cd2 Mon Sep 17 00:00:00 2001 From: David Lopez Reyes Date: Tue, 24 Dec 2019 06:25:51 +1100 Subject: [PATCH 0097/1468] Add support for multiline PR comments (#1326) Fixes #1297. --- github/github-accessors.go | 48 +++++++++++++++++++++++++++++++++ github/github-stringify_test.go | 8 +++++- github/github.go | 3 +++ github/pulls_comments.go | 16 +++++++++-- github/pulls_comments_test.go | 25 ++++++++++++++--- 5 files changed, 94 insertions(+), 6 deletions(-) diff --git a/github/github-accessors.go b/github/github-accessors.go index 0c1edd7aeb5..9e8a3993d10 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -8340,6 +8340,14 @@ func (p *PullRequestComment) GetInReplyTo() int64 { return *p.InReplyTo } +// GetLine returns the Line field if it's non-nil, zero value otherwise. +func (p *PullRequestComment) GetLine() int { + if p == nil || p.Line == nil { + return 0 + } + return *p.Line +} + // GetNodeID returns the NodeID field if it's non-nil, zero value otherwise. func (p *PullRequestComment) GetNodeID() string { if p == nil || p.NodeID == nil { @@ -8356,6 +8364,14 @@ func (p *PullRequestComment) GetOriginalCommitID() string { return *p.OriginalCommitID } +// GetOriginalLine returns the OriginalLine field if it's non-nil, zero value otherwise. +func (p *PullRequestComment) GetOriginalLine() int { + if p == nil || p.OriginalLine == nil { + return 0 + } + return *p.OriginalLine +} + // GetOriginalPosition returns the OriginalPosition field if it's non-nil, zero value otherwise. func (p *PullRequestComment) GetOriginalPosition() int { if p == nil || p.OriginalPosition == nil { @@ -8364,6 +8380,14 @@ func (p *PullRequestComment) GetOriginalPosition() int { return *p.OriginalPosition } +// GetOriginalStartLine returns the OriginalStartLine field if it's non-nil, zero value otherwise. +func (p *PullRequestComment) GetOriginalStartLine() int { + if p == nil || p.OriginalStartLine == nil { + return 0 + } + return *p.OriginalStartLine +} + // GetPath returns the Path field if it's non-nil, zero value otherwise. func (p *PullRequestComment) GetPath() string { if p == nil || p.Path == nil { @@ -8404,6 +8428,30 @@ func (p *PullRequestComment) GetReactions() *Reactions { return p.Reactions } +// GetSide returns the Side field if it's non-nil, zero value otherwise. +func (p *PullRequestComment) GetSide() string { + if p == nil || p.Side == nil { + return "" + } + return *p.Side +} + +// GetStartLine returns the StartLine field if it's non-nil, zero value otherwise. +func (p *PullRequestComment) GetStartLine() int { + if p == nil || p.StartLine == nil { + return 0 + } + return *p.StartLine +} + +// GetStartSide returns the StartSide field if it's non-nil, zero value otherwise. +func (p *PullRequestComment) GetStartSide() string { + if p == nil || p.StartSide == nil { + return "" + } + return *p.StartSide +} + // GetUpdatedAt returns the UpdatedAt field if it's non-nil, zero value otherwise. func (p *PullRequestComment) GetUpdatedAt() time.Time { if p == nil || p.UpdatedAt == nil { diff --git a/github/github-stringify_test.go b/github/github-stringify_test.go index 2216c8c4052..97a13ee2a55 100644 --- a/github/github-stringify_test.go +++ b/github/github-stringify_test.go @@ -989,6 +989,12 @@ func TestPullRequestComment_String(t *testing.T) { PullRequestReviewID: Int64(0), Position: Int(0), OriginalPosition: Int(0), + StartLine: Int(0), + Line: Int(0), + OriginalLine: Int(0), + OriginalStartLine: Int(0), + Side: String(""), + StartSide: String(""), CommitID: String(""), OriginalCommitID: String(""), User: &User{}, @@ -998,7 +1004,7 @@ func TestPullRequestComment_String(t *testing.T) { HTMLURL: String(""), PullRequestURL: String(""), } - want := `github.PullRequestComment{ID:0, NodeID:"", InReplyTo:0, Body:"", Path:"", DiffHunk:"", PullRequestReviewID:0, Position:0, OriginalPosition:0, CommitID:"", OriginalCommitID:"", User:github.User{}, Reactions:github.Reactions{}, AuthorAssociation:"", URL:"", HTMLURL:"", PullRequestURL:""}` + want := `github.PullRequestComment{ID:0, NodeID:"", InReplyTo:0, Body:"", Path:"", DiffHunk:"", PullRequestReviewID:0, Position:0, OriginalPosition:0, StartLine:0, Line:0, OriginalLine:0, OriginalStartLine:0, Side:"", StartSide:"", CommitID:"", OriginalCommitID:"", User:github.User{}, Reactions:github.Reactions{}, AuthorAssociation:"", URL:"", HTMLURL:"", PullRequestURL:""}` if got := v.String(); got != want { t.Errorf("PullRequestComment.String = %v, want %v", got, want) } diff --git a/github/github.go b/github/github.go index 1084412c252..109a8c9bb7f 100644 --- a/github/github.go +++ b/github/github.go @@ -150,6 +150,9 @@ const ( // https://developer.github.com/v3/previews/#create-and-use-repository-templates mediaTypeRepositoryTemplatePreview = "application/vnd.github.baptiste-preview+json" + + // https://developer.github.com/changes/2019-10-03-multi-line-comments/ + mediaTypeMultiLineCommentsPreview = "application/vnd.github.comfort-fade-preview+json" ) // A Client manages communication with the GitHub API. diff --git a/github/pulls_comments.go b/github/pulls_comments.go index 8886c9d124d..3372e3383ef 100644 --- a/github/pulls_comments.go +++ b/github/pulls_comments.go @@ -8,6 +8,7 @@ package github import ( "context" "fmt" + "strings" "time" ) @@ -22,6 +23,12 @@ type PullRequestComment struct { PullRequestReviewID *int64 `json:"pull_request_review_id,omitempty"` Position *int `json:"position,omitempty"` OriginalPosition *int `json:"original_position,omitempty"` + StartLine *int `json:"start_line,omitempty"` + Line *int `json:"line,omitempty"` + OriginalLine *int `json:"original_line,omitempty"` + OriginalStartLine *int `json:"original_start_line,omitempty"` + Side *string `json:"side,omitempty"` + StartSide *string `json:"start_side,omitempty"` CommitID *string `json:"commit_id,omitempty"` OriginalCommitID *string `json:"original_commit_id,omitempty"` User *User `json:"user,omitempty"` @@ -78,7 +85,8 @@ func (s *PullRequestsService) ListComments(ctx context.Context, owner string, re } // TODO: remove custom Accept header when this API fully launches. - req.Header.Set("Accept", mediaTypeReactionsPreview) + acceptHeaders := []string{mediaTypeReactionsPreview, mediaTypeMultiLineCommentsPreview} + req.Header.Set("Accept", strings.Join(acceptHeaders, ", ")) var comments []*PullRequestComment resp, err := s.client.Do(ctx, req, &comments) @@ -100,7 +108,8 @@ func (s *PullRequestsService) GetComment(ctx context.Context, owner string, repo } // TODO: remove custom Accept header when this API fully launches. - req.Header.Set("Accept", mediaTypeReactionsPreview) + acceptHeaders := []string{mediaTypeReactionsPreview, mediaTypeMultiLineCommentsPreview} + req.Header.Set("Accept", strings.Join(acceptHeaders, ", ")) comment := new(PullRequestComment) resp, err := s.client.Do(ctx, req, comment) @@ -120,6 +129,9 @@ func (s *PullRequestsService) CreateComment(ctx context.Context, owner string, r if err != nil { return nil, nil, err } + // TODO: remove custom Accept headers when their respective API fully launches. + acceptHeaders := []string{mediaTypeReactionsPreview, mediaTypeMultiLineCommentsPreview} + req.Header.Set("Accept", strings.Join(acceptHeaders, ", ")) c := new(PullRequestComment) resp, err := s.client.Do(ctx, req, c) diff --git a/github/pulls_comments_test.go b/github/pulls_comments_test.go index b07b2cd99b0..ace57003828 100644 --- a/github/pulls_comments_test.go +++ b/github/pulls_comments_test.go @@ -11,6 +11,7 @@ import ( "fmt" "net/http" "reflect" + "strings" "testing" "time" ) @@ -40,6 +41,12 @@ func TestPullComments_marshall(t *testing.T) { PullRequestReviewID: Int64(42), Position: Int(1), OriginalPosition: Int(4), + StartLine: Int(2), + Line: Int(3), + OriginalLine: Int(2), + OriginalStartLine: Int(2), + Side: String("RIGHT"), + StartSide: String("LEFT"), CommitID: String("ab"), OriginalCommitID: String("9c"), User: &User{ @@ -76,6 +83,12 @@ func TestPullComments_marshall(t *testing.T) { "pull_request_review_id": 42, "position": 1, "original_position": 4, + "start_line": 2, + "line": 3, + "original_line": 2, + "original_start_line": 2, + "side": "RIGHT", + "start_side": "LEFT", "commit_id": "ab", "original_commit_id": "9c", "user": { @@ -119,9 +132,10 @@ func TestPullRequestsService_ListComments_allPulls(t *testing.T) { client, mux, _, teardown := setup() defer teardown() + wantAcceptHeaders := []string{mediaTypeReactionsPreview, mediaTypeMultiLineCommentsPreview} mux.HandleFunc("/repos/o/r/pulls/comments", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") - testHeader(t, r, "Accept", mediaTypeReactionsPreview) + testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", ")) testFormValues(t, r, values{ "sort": "updated", "direction": "desc", @@ -152,9 +166,10 @@ func TestPullRequestsService_ListComments_specificPull(t *testing.T) { client, mux, _, teardown := setup() defer teardown() + wantAcceptHeaders := []string{mediaTypeReactionsPreview, mediaTypeMultiLineCommentsPreview} mux.HandleFunc("/repos/o/r/pulls/1/comments", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") - testHeader(t, r, "Accept", mediaTypeReactionsPreview) + testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", ")) fmt.Fprint(w, `[{"id":1, "pull_request_review_id":42}]`) }) @@ -181,9 +196,10 @@ func TestPullRequestsService_GetComment(t *testing.T) { client, mux, _, teardown := setup() defer teardown() + wantAcceptHeaders := []string{mediaTypeReactionsPreview, mediaTypeMultiLineCommentsPreview} mux.HandleFunc("/repos/o/r/pulls/comments/1", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") - testHeader(t, r, "Accept", mediaTypeReactionsPreview) + testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", ")) fmt.Fprint(w, `{"id":1}`) }) @@ -212,10 +228,13 @@ func TestPullRequestsService_CreateComment(t *testing.T) { input := &PullRequestComment{Body: String("b")} + wantAcceptHeaders := []string{mediaTypeReactionsPreview, mediaTypeMultiLineCommentsPreview} mux.HandleFunc("/repos/o/r/pulls/1/comments", func(w http.ResponseWriter, r *http.Request) { v := new(PullRequestComment) json.NewDecoder(r.Body).Decode(v) + // TODO: remove custom Accept header assertion when the API fully launches. + testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", ")) testMethod(t, r, "POST") if !reflect.DeepEqual(v, input) { t.Errorf("Request body = %+v, want %+v", v, input) From 40fcc261cf8cf4e4fb03b63f8fbfa13949119590 Mon Sep 17 00:00:00 2001 From: Vaibhav Singh Date: Thu, 26 Dec 2019 20:39:21 +0530 Subject: [PATCH 0098/1468] Remove custom preview headers from "graduated" APIs (#1355) Fixes #1351. --- github/github.go | 18 -------------- github/issues.go | 12 +++------ github/issues_labels.go | 30 ----------------------- github/issues_labels_test.go | 10 -------- github/issues_test.go | 12 ++++----- github/orgs_members.go | 6 ----- github/orgs_members_test.go | 4 +-- github/pulls.go | 10 ++++---- github/pulls_test.go | 10 ++++---- github/repos.go | 5 ---- github/repos_collaborators.go | 2 -- github/repos_collaborators_test.go | 1 - github/repos_test.go | 2 -- github/search.go | 4 --- github/teams.go | 31 +++++------------------- github/teams_discussion_comments.go | 15 ------------ github/teams_discussion_comments_test.go | 5 ---- github/teams_discussions.go | 15 ------------ github/teams_discussions_test.go | 5 ---- github/teams_members.go | 4 --- github/teams_members_test.go | 2 -- github/teams_test.go | 20 +++++---------- github/users.go | 3 --- github/users_test.go | 1 - 24 files changed, 31 insertions(+), 196 deletions(-) diff --git a/github/github.go b/github/github.go index 109a8c9bb7f..b9a2488aaf5 100644 --- a/github/github.go +++ b/github/github.go @@ -88,27 +88,9 @@ const ( // https://developer.github.com/changes/2017-07-17-update-topics-on-repositories/ mediaTypeTopicsPreview = "application/vnd.github.mercy-preview+json" - // https://developer.github.com/changes/2017-08-30-preview-nested-teams/ - mediaTypeNestedTeamsPreview = "application/vnd.github.hellcat-preview+json" - - // https://developer.github.com/changes/2017-11-09-repository-transfer-api-preview/ - mediaTypeRepositoryTransferPreview = "application/vnd.github.nightshade-preview+json" - - // https://developer.github.com/changes/2018-01-25-organization-invitation-api-preview/ - mediaTypeOrganizationInvitationPreview = "application/vnd.github.dazzler-preview+json" - // https://developer.github.com/changes/2018-03-16-protected-branches-required-approving-reviews/ mediaTypeRequiredApprovingReviewsPreview = "application/vnd.github.luke-cage-preview+json" - // https://developer.github.com/changes/2018-02-22-label-description-search-preview/ - mediaTypeLabelDescriptionSearchPreview = "application/vnd.github.symmetra-preview+json" - - // https://developer.github.com/changes/2018-02-07-team-discussions-api/ - mediaTypeTeamDiscussionsPreview = "application/vnd.github.echo-preview+json" - - // https://developer.github.com/changes/2018-03-21-hovercard-api-preview/ - mediaTypeHovercardPreview = "application/vnd.github.hagar-preview+json" - // https://developer.github.com/changes/2018-01-10-lock-reason-api-preview/ mediaTypeLockReasonPreview = "application/vnd.github.sailor-v-preview+json" diff --git a/github/issues.go b/github/issues.go index 1e0991ce4ff..b08934c3e52 100644 --- a/github/issues.go +++ b/github/issues.go @@ -160,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, mediaTypeLockReasonPreview} + acceptHeaders := []string{mediaTypeReactionsPreview, mediaTypeLockReasonPreview} req.Header.Set("Accept", strings.Join(acceptHeaders, ", ")) var issues []*Issue @@ -228,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, mediaTypeIntegrationPreview} + acceptHeaders := []string{mediaTypeReactionsPreview, mediaTypeIntegrationPreview} req.Header.Set("Accept", strings.Join(acceptHeaders, ", ")) var issues []*Issue @@ -251,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, mediaTypeLockReasonPreview} + acceptHeaders := []string{mediaTypeReactionsPreview, mediaTypeLockReasonPreview} req.Header.Set("Accept", strings.Join(acceptHeaders, ", ")) issue := new(Issue) @@ -273,9 +273,6 @@ func (s *IssuesService) Create(ctx context.Context, owner string, repo string, i return nil, nil, err } - // TODO: remove custom Accept header when this API fully launches. - req.Header.Set("Accept", mediaTypeLabelDescriptionSearchPreview) - i := new(Issue) resp, err := s.client.Do(ctx, req, i) if err != nil { @@ -295,9 +292,6 @@ func (s *IssuesService) Edit(ctx context.Context, owner string, repo string, num return nil, nil, err } - // TODO: remove custom Accept header when this API fully launches. - req.Header.Set("Accept", mediaTypeLabelDescriptionSearchPreview) - i := new(Issue) resp, err := s.client.Do(ctx, req, i) if err != nil { diff --git a/github/issues_labels.go b/github/issues_labels.go index adcbe06834a..0771a28c8f8 100644 --- a/github/issues_labels.go +++ b/github/issues_labels.go @@ -40,9 +40,6 @@ func (s *IssuesService) ListLabels(ctx context.Context, owner string, repo strin return nil, nil, err } - // TODO: remove custom Accept header when this API fully launches. - req.Header.Set("Accept", mediaTypeLabelDescriptionSearchPreview) - var labels []*Label resp, err := s.client.Do(ctx, req, &labels) if err != nil { @@ -62,9 +59,6 @@ func (s *IssuesService) GetLabel(ctx context.Context, owner string, repo string, return nil, nil, err } - // TODO: remove custom Accept header when this API fully launches. - req.Header.Set("Accept", mediaTypeLabelDescriptionSearchPreview) - label := new(Label) resp, err := s.client.Do(ctx, req, label) if err != nil { @@ -84,9 +78,6 @@ func (s *IssuesService) CreateLabel(ctx context.Context, owner string, repo stri return nil, nil, err } - // TODO: remove custom Accept header when this API fully launches. - req.Header.Set("Accept", mediaTypeLabelDescriptionSearchPreview) - l := new(Label) resp, err := s.client.Do(ctx, req, l) if err != nil { @@ -106,9 +97,6 @@ func (s *IssuesService) EditLabel(ctx context.Context, owner string, repo string return nil, nil, err } - // TODO: remove custom Accept header when this API fully launches. - req.Header.Set("Accept", mediaTypeLabelDescriptionSearchPreview) - l := new(Label) resp, err := s.client.Do(ctx, req, l) if err != nil { @@ -145,9 +133,6 @@ func (s *IssuesService) ListLabelsByIssue(ctx context.Context, owner string, rep return nil, nil, err } - // TODO: remove custom Accept header when this API fully launches. - req.Header.Set("Accept", mediaTypeLabelDescriptionSearchPreview) - var labels []*Label resp, err := s.client.Do(ctx, req, &labels) if err != nil { @@ -167,9 +152,6 @@ func (s *IssuesService) AddLabelsToIssue(ctx context.Context, owner string, repo return nil, nil, err } - // TODO: remove custom Accept header when this API fully launches. - req.Header.Set("Accept", mediaTypeLabelDescriptionSearchPreview) - var l []*Label resp, err := s.client.Do(ctx, req, &l) if err != nil { @@ -189,9 +171,6 @@ func (s *IssuesService) RemoveLabelForIssue(ctx context.Context, owner string, r return nil, err } - // TODO: remove custom Accept header when this API fully launches. - req.Header.Set("Accept", mediaTypeLabelDescriptionSearchPreview) - return s.client.Do(ctx, req, nil) } @@ -205,9 +184,6 @@ func (s *IssuesService) ReplaceLabelsForIssue(ctx context.Context, owner string, return nil, nil, err } - // TODO: remove custom Accept header when this API fully launches. - req.Header.Set("Accept", mediaTypeLabelDescriptionSearchPreview) - var l []*Label resp, err := s.client.Do(ctx, req, &l) if err != nil { @@ -227,9 +203,6 @@ func (s *IssuesService) RemoveLabelsForIssue(ctx context.Context, owner string, return nil, err } - // TODO: remove custom Accept header when this API fully launches. - req.Header.Set("Accept", mediaTypeLabelDescriptionSearchPreview) - return s.client.Do(ctx, req, nil) } @@ -248,9 +221,6 @@ func (s *IssuesService) ListLabelsForMilestone(ctx context.Context, owner string return nil, nil, err } - // TODO: remove custom Accept header when this API fully launches. - req.Header.Set("Accept", mediaTypeLabelDescriptionSearchPreview) - var labels []*Label resp, err := s.client.Do(ctx, req, &labels) if err != nil { diff --git a/github/issues_labels_test.go b/github/issues_labels_test.go index 6437d8800fa..e97b23b0064 100644 --- a/github/issues_labels_test.go +++ b/github/issues_labels_test.go @@ -20,7 +20,6 @@ func TestIssuesService_ListLabels(t *testing.T) { mux.HandleFunc("/repos/o/r/labels", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") - testHeader(t, r, "Accept", mediaTypeLabelDescriptionSearchPreview) testFormValues(t, r, values{"page": "2"}) fmt.Fprint(w, `[{"name": "a"},{"name": "b"}]`) }) @@ -51,7 +50,6 @@ func TestIssuesService_GetLabel(t *testing.T) { mux.HandleFunc("/repos/o/r/labels/n", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") - testHeader(t, r, "Accept", mediaTypeLabelDescriptionSearchPreview) fmt.Fprint(w, `{"url":"u", "name": "n", "color": "c", "description": "d"}`) }) @@ -85,7 +83,6 @@ func TestIssuesService_CreateLabel(t *testing.T) { json.NewDecoder(r.Body).Decode(v) testMethod(t, r, "POST") - testHeader(t, r, "Accept", mediaTypeLabelDescriptionSearchPreview) if !reflect.DeepEqual(v, input) { t.Errorf("Request body = %+v, want %+v", v, input) } @@ -123,7 +120,6 @@ func TestIssuesService_EditLabel(t *testing.T) { json.NewDecoder(r.Body).Decode(v) testMethod(t, r, "PATCH") - testHeader(t, r, "Accept", mediaTypeLabelDescriptionSearchPreview) if !reflect.DeepEqual(v, input) { t.Errorf("Request body = %+v, want %+v", v, input) } @@ -178,7 +174,6 @@ func TestIssuesService_ListLabelsByIssue(t *testing.T) { mux.HandleFunc("/repos/o/r/issues/1/labels", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") - testHeader(t, r, "Accept", mediaTypeLabelDescriptionSearchPreview) testFormValues(t, r, values{"page": "2"}) fmt.Fprint(w, `[{"name":"a","id":1},{"name":"b","id":2}]`) }) @@ -217,7 +212,6 @@ func TestIssuesService_AddLabelsToIssue(t *testing.T) { json.NewDecoder(r.Body).Decode(&v) testMethod(t, r, "POST") - testHeader(t, r, "Accept", mediaTypeLabelDescriptionSearchPreview) if !reflect.DeepEqual(v, input) { t.Errorf("Request body = %+v, want %+v", v, input) } @@ -249,7 +243,6 @@ func TestIssuesService_RemoveLabelForIssue(t *testing.T) { defer teardown() mux.HandleFunc("/repos/o/r/issues/1/labels/l", func(w http.ResponseWriter, r *http.Request) { - testHeader(t, r, "Accept", mediaTypeLabelDescriptionSearchPreview) testMethod(t, r, "DELETE") }) @@ -278,7 +271,6 @@ func TestIssuesService_ReplaceLabelsForIssue(t *testing.T) { json.NewDecoder(r.Body).Decode(&v) testMethod(t, r, "PUT") - testHeader(t, r, "Accept", mediaTypeLabelDescriptionSearchPreview) if !reflect.DeepEqual(v, input) { t.Errorf("Request body = %+v, want %+v", v, input) } @@ -311,7 +303,6 @@ func TestIssuesService_RemoveLabelsForIssue(t *testing.T) { mux.HandleFunc("/repos/o/r/issues/1/labels", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "DELETE") - testHeader(t, r, "Accept", mediaTypeLabelDescriptionSearchPreview) }) _, err := client.Issues.RemoveLabelsForIssue(context.Background(), "o", "r", 1) @@ -334,7 +325,6 @@ func TestIssuesService_ListLabelsForMilestone(t *testing.T) { mux.HandleFunc("/repos/o/r/milestones/1/labels", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") - testHeader(t, r, "Accept", mediaTypeLabelDescriptionSearchPreview) testFormValues(t, r, values{"page": "2"}) fmt.Fprint(w, `[{"name": "a"},{"name": "b"}]`) }) diff --git a/github/issues_test.go b/github/issues_test.go index 7edcf09b68a..e26d7f5d75b 100644 --- a/github/issues_test.go +++ b/github/issues_test.go @@ -20,7 +20,7 @@ func TestIssuesService_List_all(t *testing.T) { client, mux, _, teardown := setup() defer teardown() - wantAcceptHeaders := []string{mediaTypeReactionsPreview, mediaTypeLabelDescriptionSearchPreview, mediaTypeLockReasonPreview} + wantAcceptHeaders := []string{mediaTypeReactionsPreview, mediaTypeLockReasonPreview} mux.HandleFunc("/issues", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", ")) @@ -57,7 +57,7 @@ func TestIssuesService_List_owned(t *testing.T) { client, mux, _, teardown := setup() defer teardown() - wantAcceptHeaders := []string{mediaTypeReactionsPreview, mediaTypeLabelDescriptionSearchPreview, mediaTypeLockReasonPreview} + wantAcceptHeaders := []string{mediaTypeReactionsPreview, mediaTypeLockReasonPreview} mux.HandleFunc("/user/issues", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", ")) @@ -79,7 +79,7 @@ func TestIssuesService_ListByOrg(t *testing.T) { client, mux, _, teardown := setup() defer teardown() - wantAcceptHeaders := []string{mediaTypeReactionsPreview, mediaTypeLabelDescriptionSearchPreview, mediaTypeLockReasonPreview} + wantAcceptHeaders := []string{mediaTypeReactionsPreview, mediaTypeLockReasonPreview} mux.HandleFunc("/orgs/o/issues", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", ")) @@ -109,7 +109,7 @@ func TestIssuesService_ListByRepo(t *testing.T) { client, mux, _, teardown := setup() defer teardown() - wantAcceptHeaders := []string{mediaTypeReactionsPreview, mediaTypeLabelDescriptionSearchPreview, mediaTypeIntegrationPreview} + wantAcceptHeaders := []string{mediaTypeReactionsPreview, mediaTypeIntegrationPreview} mux.HandleFunc("/repos/o/r/issues", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", ")) @@ -155,7 +155,7 @@ func TestIssuesService_Get(t *testing.T) { client, mux, _, teardown := setup() defer teardown() - wantAcceptHeaders := []string{mediaTypeReactionsPreview, mediaTypeLabelDescriptionSearchPreview, mediaTypeLockReasonPreview} + wantAcceptHeaders := []string{mediaTypeReactionsPreview, 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(wantAcceptHeaders, ", ")) @@ -204,7 +204,6 @@ func TestIssuesService_Create(t *testing.T) { json.NewDecoder(r.Body).Decode(v) testMethod(t, r, "POST") - testHeader(t, r, "Accept", mediaTypeLabelDescriptionSearchPreview) if !reflect.DeepEqual(v, input) { t.Errorf("Request body = %+v, want %+v", v, input) } @@ -242,7 +241,6 @@ func TestIssuesService_Edit(t *testing.T) { json.NewDecoder(r.Body).Decode(v) testMethod(t, r, "PATCH") - testHeader(t, r, "Accept", mediaTypeLabelDescriptionSearchPreview) if !reflect.DeepEqual(v, input) { t.Errorf("Request body = %+v, want %+v", v, input) } diff --git a/github/orgs_members.go b/github/orgs_members.go index d18435999c9..a2fc9265dff 100644 --- a/github/orgs_members.go +++ b/github/orgs_members.go @@ -331,9 +331,6 @@ func (s *OrganizationsService) CreateOrgInvitation(ctx context.Context, org stri return nil, nil, err } - // TODO: remove custom Accept header when this API fully launches. - req.Header.Set("Accept", mediaTypeOrganizationInvitationPreview) - var invitation *Invitation resp, err := s.client.Do(ctx, req, &invitation) if err != nil { @@ -358,9 +355,6 @@ func (s *OrganizationsService) ListOrgInvitationTeams(ctx context.Context, org, return nil, nil, err } - // TODO: remove custom Accept header when this API fully launches. - req.Header.Set("Accept", mediaTypeOrganizationInvitationPreview) - var orgInvitationTeams []*Team resp, err := s.client.Do(ctx, req, &orgInvitationTeams) if err != nil { diff --git a/github/orgs_members_test.go b/github/orgs_members_test.go index e524d03f169..50da85d291f 100644 --- a/github/orgs_members_test.go +++ b/github/orgs_members_test.go @@ -402,7 +402,7 @@ func TestOrganizationsService_ListPendingOrgInvitations(t *testing.T) { "site_admin": false }, "team_count": 2, - "invitation_team_url": "https://api.github.com/organizations/2/invitations/1/teams" + "invitation_team_url": "https://api.github.com/organizations/2/invitations/1/teams" } ]`) }) @@ -466,7 +466,6 @@ func TestOrganizationsService_CreateOrgInvitation(t *testing.T) { json.NewDecoder(r.Body).Decode(v) testMethod(t, r, "POST") - testHeader(t, r, "Accept", mediaTypeOrganizationInvitationPreview) if !reflect.DeepEqual(v, input) { t.Errorf("Request body = %+v, want %+v", v, input) } @@ -493,7 +492,6 @@ func TestOrganizationsService_ListOrgInvitationTeams(t *testing.T) { mux.HandleFunc("/orgs/o/invitations/22/teams", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") testFormValues(t, r, values{"page": "1"}) - testHeader(t, r, "Accept", mediaTypeOrganizationInvitationPreview) fmt.Fprint(w, `[ { "id": 1, diff --git a/github/pulls.go b/github/pulls.go index 83ca9e55a0b..867455aeaf6 100644 --- a/github/pulls.go +++ b/github/pulls.go @@ -149,7 +149,7 @@ func (s *PullRequestsService) List(ctx context.Context, owner string, repo strin } // TODO: remove custom Accept header when this API fully launches. - acceptHeaders := []string{mediaTypeLabelDescriptionSearchPreview, mediaTypeLockReasonPreview, mediaTypeDraftPreview} + acceptHeaders := []string{mediaTypeLockReasonPreview, mediaTypeDraftPreview} req.Header.Set("Accept", strings.Join(acceptHeaders, ", ")) var pulls []*PullRequest @@ -179,7 +179,7 @@ func (s *PullRequestsService) ListPullRequestsWithCommit(ctx context.Context, ow } // TODO: remove custom Accept header when this API fully launches. - acceptHeaders := []string{mediaTypeListPullsOrBranchesForCommitPreview, mediaTypeDraftPreview, mediaTypeLabelDescriptionSearchPreview, mediaTypeLockReasonPreview} + acceptHeaders := []string{mediaTypeListPullsOrBranchesForCommitPreview, mediaTypeDraftPreview, mediaTypeLockReasonPreview} req.Header.Set("Accept", strings.Join(acceptHeaders, ", ")) var pulls []*PullRequest resp, err := s.client.Do(ctx, req, &pulls) @@ -201,7 +201,7 @@ func (s *PullRequestsService) Get(ctx context.Context, owner string, repo string } // TODO: remove custom Accept header when this API fully launches. - acceptHeaders := []string{mediaTypeLabelDescriptionSearchPreview, mediaTypeLockReasonPreview, mediaTypeDraftPreview} + acceptHeaders := []string{mediaTypeLockReasonPreview, mediaTypeDraftPreview} req.Header.Set("Accept", strings.Join(acceptHeaders, ", ")) pull := new(PullRequest) @@ -261,7 +261,7 @@ func (s *PullRequestsService) Create(ctx context.Context, owner string, repo str } // TODO: remove custom Accept header when this API fully launches. - acceptHeaders := []string{mediaTypeLabelDescriptionSearchPreview, mediaTypeDraftPreview} + acceptHeaders := []string{mediaTypeDraftPreview} req.Header.Set("Accept", strings.Join(acceptHeaders, ", ")) p := new(PullRequest) @@ -357,7 +357,7 @@ func (s *PullRequestsService) Edit(ctx context.Context, owner string, repo strin } // TODO: remove custom Accept header when this API fully launches. - acceptHeaders := []string{mediaTypeLabelDescriptionSearchPreview, mediaTypeLockReasonPreview} + acceptHeaders := []string{mediaTypeLockReasonPreview} req.Header.Set("Accept", strings.Join(acceptHeaders, ", ")) p := new(PullRequest) diff --git a/github/pulls_test.go b/github/pulls_test.go index 65647d65300..b19921f5d34 100644 --- a/github/pulls_test.go +++ b/github/pulls_test.go @@ -20,7 +20,7 @@ func TestPullRequestsService_List(t *testing.T) { client, mux, _, teardown := setup() defer teardown() - wantAcceptHeaders := []string{mediaTypeLabelDescriptionSearchPreview, mediaTypeLockReasonPreview, mediaTypeDraftPreview} + wantAcceptHeaders := []string{mediaTypeLockReasonPreview, mediaTypeDraftPreview} mux.HandleFunc("/repos/o/r/pulls", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", ")) @@ -51,7 +51,7 @@ func TestPullRequestsService_ListPullRequestsWithCommit(t *testing.T) { client, mux, _, teardown := setup() defer teardown() - wantAcceptHeaders := []string{mediaTypeListPullsOrBranchesForCommitPreview, mediaTypeDraftPreview, mediaTypeLabelDescriptionSearchPreview, mediaTypeLockReasonPreview} + wantAcceptHeaders := []string{mediaTypeListPullsOrBranchesForCommitPreview, mediaTypeDraftPreview, 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, ", ")) @@ -90,7 +90,7 @@ func TestPullRequestsService_Get(t *testing.T) { client, mux, _, teardown := setup() defer teardown() - wantAcceptHeaders := []string{mediaTypeLabelDescriptionSearchPreview, mediaTypeLockReasonPreview, mediaTypeDraftPreview} + wantAcceptHeaders := []string{mediaTypeLockReasonPreview, mediaTypeDraftPreview} mux.HandleFunc("/repos/o/r/pulls/1", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", ")) @@ -306,7 +306,7 @@ func TestPullRequestsService_Create(t *testing.T) { json.NewDecoder(r.Body).Decode(v) testMethod(t, r, "POST") - wantAcceptHeaders := []string{mediaTypeLabelDescriptionSearchPreview, mediaTypeDraftPreview} + wantAcceptHeaders := []string{mediaTypeDraftPreview} testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", ")) if !reflect.DeepEqual(v, input) { t.Errorf("Request body = %+v, want %+v", v, input) @@ -398,7 +398,7 @@ func TestPullRequestsService_Edit(t *testing.T) { for i, tt := range tests { madeRequest := false - wantAcceptHeaders := []string{mediaTypeLabelDescriptionSearchPreview, mediaTypeLockReasonPreview} + wantAcceptHeaders := []string{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", strings.Join(wantAcceptHeaders, ", ")) diff --git a/github/repos.go b/github/repos.go index 34f22ebce05..fe85108afd8 100644 --- a/github/repos.go +++ b/github/repos.go @@ -672,8 +672,6 @@ func (s *RepositoriesService) ListTeams(ctx context.Context, owner string, repo return nil, nil, err } - req.Header.Set("Accept", mediaTypeNestedTeamsPreview) - var teams []*Team resp, err := s.client.Do(ctx, req, &teams) if err != nil { @@ -1421,9 +1419,6 @@ func (s *RepositoriesService) Transfer(ctx context.Context, owner, repo string, return nil, nil, err } - // TODO: remove custom Accept header when this API fully launches. - req.Header.Set("Accept", mediaTypeRepositoryTransferPreview) - r := new(Repository) resp, err := s.client.Do(ctx, req, r) if err != nil { diff --git a/github/repos_collaborators.go b/github/repos_collaborators.go index 04d8068720c..8254ac0661b 100644 --- a/github/repos_collaborators.go +++ b/github/repos_collaborators.go @@ -54,8 +54,6 @@ func (s *RepositoriesService) ListCollaborators(ctx context.Context, owner, repo return nil, nil, err } - req.Header.Set("Accept", mediaTypeNestedTeamsPreview) - var users []*User resp, err := s.client.Do(ctx, req, &users) if err != nil { diff --git a/github/repos_collaborators_test.go b/github/repos_collaborators_test.go index d2165579cb1..e14dc8bd2c0 100644 --- a/github/repos_collaborators_test.go +++ b/github/repos_collaborators_test.go @@ -20,7 +20,6 @@ func TestRepositoriesService_ListCollaborators(t *testing.T) { mux.HandleFunc("/repos/o/r/collaborators", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") - testHeader(t, r, "Accept", mediaTypeNestedTeamsPreview) testFormValues(t, r, values{"page": "2"}) fmt.Fprintf(w, `[{"id":1}, {"id":2}]`) }) diff --git a/github/repos_test.go b/github/repos_test.go index 3b2893bcb73..1d4544663eb 100644 --- a/github/repos_test.go +++ b/github/repos_test.go @@ -766,7 +766,6 @@ func TestRepositoriesService_ListTeams(t *testing.T) { mux.HandleFunc("/repos/o/r/teams", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") - testHeader(t, r, "Accept", mediaTypeNestedTeamsPreview) testFormValues(t, r, values{"page": "2"}) fmt.Fprint(w, `[{"id":1}]`) }) @@ -1780,7 +1779,6 @@ func TestRepositoriesService_Transfer(t *testing.T) { json.NewDecoder(r.Body).Decode(&v) testMethod(t, r, "POST") - testHeader(t, r, "Accept", mediaTypeRepositoryTransferPreview) if !reflect.DeepEqual(v, input) { t.Errorf("Request body = %+v, want %+v", v, input) } diff --git a/github/search.go b/github/search.go index 4e66ba1c3e8..d294a4f06ee 100644 --- a/github/search.go +++ b/github/search.go @@ -284,10 +284,6 @@ func (s *SearchService) search(ctx context.Context, searchType string, parameter // Accept header for search repositories based on topics preview endpoint // TODO: remove custom Accept header when this API fully launches. req.Header.Set("Accept", mediaTypeTopicsPreview) - case searchType == "labels": - // Accept header for search labels based on label description preview endpoint. - // TODO: remove custom Accept header when this API fully launches. - req.Header.Set("Accept", mediaTypeLabelDescriptionSearchPreview) case opt != nil && opt.TextMatch: // Accept header defaults to "application/vnd.github.v3+json" // We change it here to fetch back text-match metadata diff --git a/github/teams.go b/github/teams.go index 7f00b986e62..0300532f2df 100644 --- a/github/teams.go +++ b/github/teams.go @@ -87,9 +87,6 @@ func (s *TeamsService) ListTeams(ctx context.Context, org string, opt *ListOptio return nil, nil, err } - // TODO: remove custom Accept header when this API fully launches. - req.Header.Set("Accept", mediaTypeNestedTeamsPreview) - var teams []*Team resp, err := s.client.Do(ctx, req, &teams) if err != nil { @@ -109,9 +106,6 @@ func (s *TeamsService) GetTeam(ctx context.Context, team int64) (*Team, *Respons return nil, nil, err } - // TODO: remove custom Accept header when this API fully launches. - req.Header.Set("Accept", mediaTypeNestedTeamsPreview) - t := new(Team) resp, err := s.client.Do(ctx, req, t) if err != nil { @@ -181,9 +175,6 @@ func (s *TeamsService) CreateTeam(ctx context.Context, org string, team NewTeam) return nil, nil, err } - // TODO: remove custom Accept header when this API fully launches. - req.Header.Set("Accept", mediaTypeNestedTeamsPreview) - t := new(Team) resp, err := s.client.Do(ctx, req, t) if err != nil { @@ -203,9 +194,6 @@ func (s *TeamsService) EditTeam(ctx context.Context, id int64, team NewTeam) (*T return nil, nil, err } - // TODO: remove custom Accept header when this API fully launches. - req.Header.Set("Accept", mediaTypeNestedTeamsPreview) - t := new(Team) resp, err := s.client.Do(ctx, req, t) if err != nil { @@ -225,8 +213,6 @@ func (s *TeamsService) DeleteTeam(ctx context.Context, team int64) (*Response, e return nil, err } - req.Header.Set("Accept", mediaTypeNestedTeamsPreview) - return s.client.Do(ctx, req, nil) } @@ -245,8 +231,6 @@ func (s *TeamsService) ListChildTeams(ctx context.Context, teamID int64, opt *Li return nil, nil, err } - req.Header.Set("Accept", mediaTypeNestedTeamsPreview) - var teams []*Team resp, err := s.client.Do(ctx, req, &teams) if err != nil { @@ -272,7 +256,7 @@ func (s *TeamsService) ListTeamRepos(ctx context.Context, team int64, opt *ListO } // TODO: remove custom Accept header when topics API fully launches. - headers := []string{mediaTypeTopicsPreview, mediaTypeNestedTeamsPreview} + headers := []string{mediaTypeTopicsPreview} req.Header.Set("Accept", strings.Join(headers, ", ")) var repos []*Repository @@ -296,7 +280,7 @@ func (s *TeamsService) IsTeamRepo(ctx context.Context, team int64, owner string, return nil, nil, err } - headers := []string{mediaTypeOrgPermissionRepo, mediaTypeNestedTeamsPreview} + headers := []string{mediaTypeOrgPermissionRepo} req.Header.Set("Accept", strings.Join(headers, ", ")) repository := new(Repository) @@ -365,9 +349,6 @@ func (s *TeamsService) ListUserTeams(ctx context.Context, opt *ListOptions) ([]* return nil, nil, err } - // TODO: remove custom Accept header when this API fully launches. - req.Header.Set("Accept", mediaTypeNestedTeamsPreview) - var teams []*Team resp, err := s.client.Do(ctx, req, &teams) if err != nil { @@ -389,7 +370,7 @@ func (s *TeamsService) ListTeamProjects(ctx context.Context, teamID int64) ([]*P } // TODO: remove custom Accept header when this API fully launches. - acceptHeaders := []string{mediaTypeNestedTeamsPreview, mediaTypeProjectsPreview} + acceptHeaders := []string{mediaTypeProjectsPreview} req.Header.Set("Accept", strings.Join(acceptHeaders, ", ")) var projects []*Project @@ -413,7 +394,7 @@ func (s *TeamsService) ReviewTeamProjects(ctx context.Context, teamID, projectID } // TODO: remove custom Accept header when this API fully launches. - acceptHeaders := []string{mediaTypeNestedTeamsPreview, mediaTypeProjectsPreview} + acceptHeaders := []string{mediaTypeProjectsPreview} req.Header.Set("Accept", strings.Join(acceptHeaders, ", ")) projects := &Project{} @@ -450,7 +431,7 @@ func (s *TeamsService) AddTeamProject(ctx context.Context, teamID, projectID int } // TODO: remove custom Accept header when this API fully launches. - acceptHeaders := []string{mediaTypeNestedTeamsPreview, mediaTypeProjectsPreview} + acceptHeaders := []string{mediaTypeProjectsPreview} req.Header.Set("Accept", strings.Join(acceptHeaders, ", ")) return s.client.Do(ctx, req, nil) @@ -471,7 +452,7 @@ func (s *TeamsService) RemoveTeamProject(ctx context.Context, teamID int64, proj } // TODO: remove custom Accept header when this API fully launches. - acceptHeaders := []string{mediaTypeNestedTeamsPreview, mediaTypeProjectsPreview} + acceptHeaders := []string{mediaTypeProjectsPreview} req.Header.Set("Accept", strings.Join(acceptHeaders, ", ")) return s.client.Do(ctx, req, nil) diff --git a/github/teams_discussion_comments.go b/github/teams_discussion_comments.go index a0206b9c92b..ff871f22be0 100644 --- a/github/teams_discussion_comments.go +++ b/github/teams_discussion_comments.go @@ -55,9 +55,6 @@ func (s *TeamsService) ListComments(ctx context.Context, teamID int64, discussio return nil, nil, err } - // TODO: remove custom Accept header when this API fully launches. - req.Header.Set("Accept", mediaTypeTeamDiscussionsPreview) - var comments []*DiscussionComment resp, err := s.client.Do(ctx, req, &comments) if err != nil { @@ -78,9 +75,6 @@ func (s *TeamsService) GetComment(ctx context.Context, teamID int64, discussionN return nil, nil, err } - // TODO: remove custom Accept header when this API fully launches. - req.Header.Set("Accept", mediaTypeTeamDiscussionsPreview) - discussionComment := &DiscussionComment{} resp, err := s.client.Do(ctx, req, discussionComment) if err != nil { @@ -101,9 +95,6 @@ func (s *TeamsService) CreateComment(ctx context.Context, teamID int64, discsusi return nil, nil, err } - // TODO: remove custom Accept header when this API fully launches. - req.Header.Set("Accept", mediaTypeTeamDiscussionsPreview) - discussionComment := &DiscussionComment{} resp, err := s.client.Do(ctx, req, discussionComment) if err != nil { @@ -125,9 +116,6 @@ func (s *TeamsService) EditComment(ctx context.Context, teamID int64, discussion return nil, nil, err } - // TODO: remove custom Accept header when this API fully launches. - req.Header.Set("Accept", mediaTypeTeamDiscussionsPreview) - discussionComment := &DiscussionComment{} resp, err := s.client.Do(ctx, req, discussionComment) if err != nil { @@ -148,8 +136,5 @@ func (s *TeamsService) DeleteComment(ctx context.Context, teamID int64, discussi return nil, err } - // TODO: remove custom Accept header when this API fully launches. - req.Header.Set("Accept", mediaTypeTeamDiscussionsPreview) - return s.client.Do(ctx, req, nil) } diff --git a/github/teams_discussion_comments_test.go b/github/teams_discussion_comments_test.go index f4c9f96f4b5..96ed1464109 100644 --- a/github/teams_discussion_comments_test.go +++ b/github/teams_discussion_comments_test.go @@ -21,7 +21,6 @@ func TestTeamsService_ListComments(t *testing.T) { mux.HandleFunc("/teams/2/discussions/3/comments", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") - testHeader(t, r, "Accept", mediaTypeTeamDiscussionsPreview) testFormValues(t, r, values{ "direction": "desc", }) @@ -112,7 +111,6 @@ func TestTeamsService_GetComment(t *testing.T) { mux.HandleFunc("/teams/2/discussions/3/comments/4", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") - testHeader(t, r, "Accept", mediaTypeTeamDiscussionsPreview) fmt.Fprint(w, `{"number":4}`) }) @@ -138,7 +136,6 @@ func TestTeamsService_CreateComment(t *testing.T) { json.NewDecoder(r.Body).Decode(v) testMethod(t, r, "POST") - testHeader(t, r, "Accept", mediaTypeTeamDiscussionsPreview) if !reflect.DeepEqual(v, &input) { t.Errorf("Request body = %+v, want %+v", v, input) } @@ -168,7 +165,6 @@ func TestTeamsService_EditComment(t *testing.T) { json.NewDecoder(r.Body).Decode(v) testMethod(t, r, "PATCH") - testHeader(t, r, "Accept", mediaTypeTeamDiscussionsPreview) if !reflect.DeepEqual(v, &input) { t.Errorf("Request body = %+v, want %+v", v, input) } @@ -193,7 +189,6 @@ func TestTeamsService_DeleteComment(t *testing.T) { mux.HandleFunc("/teams/2/discussions/3/comments/4", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "DELETE") - testHeader(t, r, "Accept", mediaTypeTeamDiscussionsPreview) }) _, err := client.Teams.DeleteComment(context.Background(), 2, 3, 4) diff --git a/github/teams_discussions.go b/github/teams_discussions.go index f491c9d1d6e..433d01595a6 100644 --- a/github/teams_discussions.go +++ b/github/teams_discussions.go @@ -60,9 +60,6 @@ func (s *TeamsService) ListDiscussions(ctx context.Context, teamID int64, option return nil, nil, err } - // TODO: remove custom Accept header when this API fully launches. - req.Header.Set("Accept", mediaTypeTeamDiscussionsPreview) - var teamDiscussions []*TeamDiscussion resp, err := s.client.Do(ctx, req, &teamDiscussions) if err != nil { @@ -83,9 +80,6 @@ func (s *TeamsService) GetDiscussion(ctx context.Context, teamID int64, discussi return nil, nil, err } - // TODO: remove custom Accept header when this API fully launches. - req.Header.Set("Accept", mediaTypeTeamDiscussionsPreview) - teamDiscussion := &TeamDiscussion{} resp, err := s.client.Do(ctx, req, teamDiscussion) if err != nil { @@ -106,9 +100,6 @@ func (s *TeamsService) CreateDiscussion(ctx context.Context, teamID int64, discu return nil, nil, err } - // TODO: remove custom Accept header when this API fully launches. - req.Header.Set("Accept", mediaTypeTeamDiscussionsPreview) - teamDiscussion := &TeamDiscussion{} resp, err := s.client.Do(ctx, req, teamDiscussion) if err != nil { @@ -130,9 +121,6 @@ func (s *TeamsService) EditDiscussion(ctx context.Context, teamID int64, discuss return nil, nil, err } - // TODO: remove custom Accept header when this API fully launches. - req.Header.Set("Accept", mediaTypeTeamDiscussionsPreview) - teamDiscussion := &TeamDiscussion{} resp, err := s.client.Do(ctx, req, teamDiscussion) if err != nil { @@ -153,8 +141,5 @@ func (s *TeamsService) DeleteDiscussion(ctx context.Context, teamID int64, discu return nil, err } - // TODO: remove custom Accept header when this API fully launches. - req.Header.Set("Accept", mediaTypeTeamDiscussionsPreview) - return s.client.Do(ctx, req, nil) } diff --git a/github/teams_discussions_test.go b/github/teams_discussions_test.go index c588c228954..65be1ce6f3d 100644 --- a/github/teams_discussions_test.go +++ b/github/teams_discussions_test.go @@ -21,7 +21,6 @@ func TestTeamsService_ListDiscussions(t *testing.T) { mux.HandleFunc("/teams/2/discussions", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") - testHeader(t, r, "Accept", mediaTypeTeamDiscussionsPreview) testFormValues(t, r, values{ "direction": "desc", }) @@ -121,7 +120,6 @@ func TestTeamsService_GetDiscussion(t *testing.T) { mux.HandleFunc("/teams/2/discussions/3", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") - testHeader(t, r, "Accept", mediaTypeTeamDiscussionsPreview) fmt.Fprint(w, `{"number":3}`) }) @@ -147,7 +145,6 @@ func TestTeamsService_CreateDiscussion(t *testing.T) { json.NewDecoder(r.Body).Decode(v) testMethod(t, r, "POST") - testHeader(t, r, "Accept", mediaTypeTeamDiscussionsPreview) if !reflect.DeepEqual(v, &input) { t.Errorf("Request body = %+v, want %+v", v, input) } @@ -177,7 +174,6 @@ func TestTeamsService_EditDiscussion(t *testing.T) { json.NewDecoder(r.Body).Decode(v) testMethod(t, r, "PATCH") - testHeader(t, r, "Accept", mediaTypeTeamDiscussionsPreview) if !reflect.DeepEqual(v, &input) { t.Errorf("Request body = %+v, want %+v", v, input) } @@ -202,7 +198,6 @@ func TestTeamsService_DeleteDiscussion(t *testing.T) { mux.HandleFunc("/teams/2/discussions/3", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "DELETE") - testHeader(t, r, "Accept", mediaTypeTeamDiscussionsPreview) }) _, err := client.Teams.DeleteDiscussion(context.Background(), 2, 3) diff --git a/github/teams_members.go b/github/teams_members.go index d5cfa0dc7dd..2a211fe9072 100644 --- a/github/teams_members.go +++ b/github/teams_members.go @@ -36,8 +36,6 @@ func (s *TeamsService) ListTeamMembers(ctx context.Context, team int64, opt *Tea return nil, nil, err } - req.Header.Set("Accept", mediaTypeNestedTeamsPreview) - var members []*User resp, err := s.client.Do(ctx, req, &members) if err != nil { @@ -75,8 +73,6 @@ func (s *TeamsService) GetTeamMembership(ctx context.Context, team int64, user s return nil, nil, err } - req.Header.Set("Accept", mediaTypeNestedTeamsPreview) - t := new(Membership) resp, err := s.client.Do(ctx, req, t) if err != nil { diff --git a/github/teams_members_test.go b/github/teams_members_test.go index 2489da0e2b7..616a747b410 100644 --- a/github/teams_members_test.go +++ b/github/teams_members_test.go @@ -20,7 +20,6 @@ func TestTeamsService__ListTeamMembers(t *testing.T) { mux.HandleFunc("/teams/1/members", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") - testHeader(t, r, "Accept", mediaTypeNestedTeamsPreview) testFormValues(t, r, values{"role": "member", "page": "2"}) fmt.Fprint(w, `[{"id":1}]`) }) @@ -107,7 +106,6 @@ func TestTeamsService__GetTeamMembership(t *testing.T) { mux.HandleFunc("/teams/1/memberships/u", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") - testHeader(t, r, "Accept", mediaTypeNestedTeamsPreview) fmt.Fprint(w, `{"url":"u", "state":"active"}`) }) diff --git a/github/teams_test.go b/github/teams_test.go index 97dc325d556..f68a14af03a 100644 --- a/github/teams_test.go +++ b/github/teams_test.go @@ -22,7 +22,6 @@ func TestTeamsService_ListTeams(t *testing.T) { mux.HandleFunc("/orgs/o/teams", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") - testHeader(t, r, "Accept", mediaTypeNestedTeamsPreview) testFormValues(t, r, values{"page": "2"}) fmt.Fprint(w, `[{"id":1}]`) }) @@ -53,7 +52,6 @@ func TestTeamsService_GetTeam(t *testing.T) { mux.HandleFunc("/teams/1", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") - testHeader(t, r, "Accept", mediaTypeNestedTeamsPreview) fmt.Fprint(w, `{"id":1, "name":"n", "description": "d", "url":"u", "slug": "s", "permission":"p", "ldap_dn":"cn=n,ou=groups,dc=example,dc=com", "parent":null}`) }) @@ -74,7 +72,6 @@ func TestTeamsService_GetTeam_nestedTeams(t *testing.T) { mux.HandleFunc("/teams/1", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") - testHeader(t, r, "Accept", mediaTypeNestedTeamsPreview) fmt.Fprint(w, `{"id":1, "name":"n", "description": "d", "url":"u", "slug": "s", "permission":"p", "parent": {"id":2, "name":"n", "description": "d", "parent": null}}`) }) @@ -152,7 +149,6 @@ func TestTeamsService_CreateTeam(t *testing.T) { json.NewDecoder(r.Body).Decode(v) testMethod(t, r, "POST") - testHeader(t, r, "Accept", mediaTypeNestedTeamsPreview) if !reflect.DeepEqual(v, &input) { t.Errorf("Request body = %+v, want %+v", v, input) } @@ -189,7 +185,6 @@ func TestTeamsService_EditTeam(t *testing.T) { v := new(NewTeam) json.NewDecoder(r.Body).Decode(v) - testHeader(t, r, "Accept", mediaTypeNestedTeamsPreview) testMethod(t, r, "PATCH") if !reflect.DeepEqual(v, &input) { t.Errorf("Request body = %+v, want %+v", v, input) @@ -215,7 +210,6 @@ func TestTeamsService_DeleteTeam(t *testing.T) { mux.HandleFunc("/teams/1", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "DELETE") - testHeader(t, r, "Accept", mediaTypeNestedTeamsPreview) }) _, err := client.Teams.DeleteTeam(context.Background(), 1) @@ -230,7 +224,6 @@ func TestTeamsService_ListChildTeams(t *testing.T) { mux.HandleFunc("/teams/1/teams", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") - testHeader(t, r, "Accept", mediaTypeNestedTeamsPreview) testFormValues(t, r, values{"page": "2"}) fmt.Fprint(w, `[{"id":2}]`) }) @@ -253,7 +246,7 @@ func TestTeamsService_ListTeamRepos(t *testing.T) { mux.HandleFunc("/teams/1/repos", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") - wantAcceptHeaders := []string{mediaTypeTopicsPreview, mediaTypeNestedTeamsPreview} + wantAcceptHeaders := []string{mediaTypeTopicsPreview} testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", ")) testFormValues(t, r, values{"page": "2"}) fmt.Fprint(w, `[{"id":1}]`) @@ -277,7 +270,7 @@ func TestTeamsService_IsTeamRepo_true(t *testing.T) { mux.HandleFunc("/teams/1/repos/o/r", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") - wantAcceptHeaders := []string{mediaTypeOrgPermissionRepo, mediaTypeNestedTeamsPreview} + wantAcceptHeaders := []string{mediaTypeOrgPermissionRepo} testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", ")) fmt.Fprint(w, `{"id":1}`) }) @@ -419,7 +412,6 @@ func TestTeamsService_ListUserTeams(t *testing.T) { mux.HandleFunc("/user/teams", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") - testHeader(t, r, "Accept", mediaTypeNestedTeamsPreview) testFormValues(t, r, values{"page": "1"}) fmt.Fprint(w, `[{"id":1}]`) }) @@ -517,7 +509,7 @@ func TestTeamsService_ListProjects(t *testing.T) { client, mux, _, teardown := setup() defer teardown() - wantAcceptHeaders := []string{mediaTypeNestedTeamsPreview, mediaTypeProjectsPreview} + wantAcceptHeaders := []string{mediaTypeProjectsPreview} mux.HandleFunc("/teams/1/projects", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", ")) @@ -539,7 +531,7 @@ func TestTeamsService_ReviewProjects(t *testing.T) { client, mux, _, teardown := setup() defer teardown() - wantAcceptHeaders := []string{mediaTypeNestedTeamsPreview, mediaTypeProjectsPreview} + wantAcceptHeaders := []string{mediaTypeProjectsPreview} mux.HandleFunc("/teams/1/projects/1", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", ")) @@ -565,7 +557,7 @@ func TestTeamsService_AddTeamProject(t *testing.T) { Permission: String("admin"), } - wantAcceptHeaders := []string{mediaTypeNestedTeamsPreview, mediaTypeProjectsPreview} + wantAcceptHeaders := []string{mediaTypeProjectsPreview} mux.HandleFunc("/teams/1/projects/1", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "PUT") testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", ")) @@ -589,7 +581,7 @@ func TestTeamsService_RemoveTeamProject(t *testing.T) { client, mux, _, teardown := setup() defer teardown() - wantAcceptHeaders := []string{mediaTypeNestedTeamsPreview, mediaTypeProjectsPreview} + wantAcceptHeaders := []string{mediaTypeProjectsPreview} mux.HandleFunc("/teams/1/projects/1", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "DELETE") testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", ")) diff --git a/github/users.go b/github/users.go index 2592aea0f4f..88a15bdb761 100644 --- a/github/users.go +++ b/github/users.go @@ -176,9 +176,6 @@ func (s *UsersService) GetHovercard(ctx context.Context, user string, opt *Hover return nil, nil, err } - // TODO: remove custom Accept header when this API fully launches. - req.Header.Set("Accept", mediaTypeHovercardPreview) - hc := new(Hovercard) resp, err := s.client.Do(ctx, req, hc) if err != nil { diff --git a/github/users_test.go b/github/users_test.go index 8fa95a227b5..d1ce7e39da3 100644 --- a/github/users_test.go +++ b/github/users_test.go @@ -159,7 +159,6 @@ func TestUsersService_GetHovercard(t *testing.T) { mux.HandleFunc("/users/u/hovercard", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") - testHeader(t, r, "Accept", mediaTypeHovercardPreview) testFormValues(t, r, values{"subject_type": "repository", "subject_id": "20180408"}) fmt.Fprint(w, `{"contexts": [{"message":"Owns this repository", "octicon": "repo"}]}`) }) From 7c15ddab767f5a36d259f6565b88e82475842742 Mon Sep 17 00:00:00 2001 From: Eivind Date: Wed, 8 Jan 2020 02:54:46 +0100 Subject: [PATCH 0099/1468] Add support for repository dispatches (#1306) Fixes #1316. --- github/event.go | 2 + github/event_types.go | 18 ++++++++ github/github-accessors.go | 56 +++++++++++++++++++++++ github/github.go | 3 ++ github/messages.go | 1 + github/messages_test.go | 4 ++ github/repos.go | 33 ++++++++++++++ github/repos_test.go | 92 ++++++++++++++++++++++++++++++++++++++ 8 files changed, 209 insertions(+) diff --git a/github/event.go b/github/event.go index de20f58403d..848fa6daeee 100644 --- a/github/event.go +++ b/github/event.go @@ -100,6 +100,8 @@ func (e *Event) ParsePayload() (payload interface{}, err error) { payload = &ReleaseEvent{} case "RepositoryEvent": payload = &RepositoryEvent{} + case "RepositoryDispatchEvent": + payload = &RepositoryDispatchEvent{} case "RepositoryVulnerabilityAlertEvent": payload = &RepositoryVulnerabilityAlertEvent{} case "StarEvent": diff --git a/github/event_types.go b/github/event_types.go index a04c7f6219f..df12821c430 100644 --- a/github/event_types.go +++ b/github/event_types.go @@ -7,6 +7,8 @@ package github +import "encoding/json" + // RequestedAction is included in a CheckRunEvent when a user has invoked an action, // i.e. when the CheckRunEvent's Action field is "requested_action". type RequestedAction struct { @@ -776,6 +778,22 @@ type RepositoryEvent struct { Installation *Installation `json:"installation,omitempty"` } +// RepositoryDispatchEvent is triggered when a client sends a POST request to the repository dispatch event endpoint. +// +// GitHub API docs: https://developer.github.com/v3/activity/events/types/#repositorydispatchevent +type RepositoryDispatchEvent struct { + // Action is the event_type that submitted with the repository dispatch payload. Value can be any string. + Action *string `json:"action,omitempty"` + Branch *string `json:"branch,omitempty"` + ClientPayload json.RawMessage `json:"client_payload,omitempty"` + Repo *Repository `json:"repository,omitempty"` + + // The following fields are only populated by Webhook events. + Org *Organization `json:"organization,omitempty"` + Sender *User `json:"sender,omitempty"` + Installation *Installation `json:"installation,omitempty"` +} + // RepositoryVulnerabilityAlertEvent is triggered when a security alert is created, dismissed, or resolved. // // GitHub API docs: https://developer.github.com/v3/activity/events/types/#repositoryvulnerabilityalertevent diff --git a/github/github-accessors.go b/github/github-accessors.go index 9e8a3993d10..4ff4a3f5a46 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -2764,6 +2764,14 @@ func (d *DismissedReview) GetState() string { return *d.State } +// GetClientPayload returns the ClientPayload field if it's non-nil, zero value otherwise. +func (d *DispatchRequestOptions) GetClientPayload() json.RawMessage { + if d == nil || d.ClientPayload == nil { + return json.RawMessage{} + } + return *d.ClientPayload +} + // GetBody returns the Body field if it's non-nil, zero value otherwise. func (d *DraftReviewComment) GetBody() string { if d == nil || d.Body == nil { @@ -10756,6 +10764,54 @@ func (r *RepositoryContentResponse) GetContent() *RepositoryContent { return r.Content } +// GetAction returns the Action field if it's non-nil, zero value otherwise. +func (r *RepositoryDispatchEvent) GetAction() string { + if r == nil || r.Action == nil { + return "" + } + return *r.Action +} + +// GetBranch returns the Branch field if it's non-nil, zero value otherwise. +func (r *RepositoryDispatchEvent) GetBranch() string { + if r == nil || r.Branch == nil { + return "" + } + return *r.Branch +} + +// GetInstallation returns the Installation field. +func (r *RepositoryDispatchEvent) GetInstallation() *Installation { + if r == nil { + return nil + } + return r.Installation +} + +// GetOrg returns the Org field. +func (r *RepositoryDispatchEvent) GetOrg() *Organization { + if r == nil { + return nil + } + return r.Org +} + +// GetRepo returns the Repo field. +func (r *RepositoryDispatchEvent) GetRepo() *Repository { + if r == nil { + return nil + } + return r.Repo +} + +// GetSender returns the Sender field. +func (r *RepositoryDispatchEvent) GetSender() *User { + if r == nil { + return nil + } + return r.Sender +} + // GetAction returns the Action field if it's non-nil, zero value otherwise. func (r *RepositoryEvent) GetAction() string { if r == nil || r.Action == nil { diff --git a/github/github.go b/github/github.go index b9a2488aaf5..9c5040ec772 100644 --- a/github/github.go +++ b/github/github.go @@ -135,6 +135,9 @@ const ( // https://developer.github.com/changes/2019-10-03-multi-line-comments/ mediaTypeMultiLineCommentsPreview = "application/vnd.github.comfort-fade-preview+json" + + // https://developer.github.com/v3/repos/#create-a-repository-dispatch-event + mediaTypeRepositoryDispatchPreview = "application/vnd.github.everest-preview+json" ) // A Client manages communication with the GitHub API. diff --git a/github/messages.go b/github/messages.go index a87daa3e9ef..759f9e81809 100644 --- a/github/messages.go +++ b/github/messages.go @@ -74,6 +74,7 @@ var ( "pull_request": "PullRequestEvent", "push": "PushEvent", "repository": "RepositoryEvent", + "repository_dispatch": "RepositoryDispatchEvent", "repository_vulnerability_alert": "RepositoryVulnerabilityAlertEvent", "release": "ReleaseEvent", "star": "StarEvent", diff --git a/github/messages_test.go b/github/messages_test.go index 30f7d95fb78..2dad247399b 100644 --- a/github/messages_test.go +++ b/github/messages_test.go @@ -347,6 +347,10 @@ func TestParseWebHook(t *testing.T) { payload: &WatchEvent{}, messageType: "watch", }, + { + payload: &RepositoryDispatchEvent{}, + messageType: "repository_dispatch", + }, } for _, test := range tests { diff --git a/github/repos.go b/github/repos.go index fe85108afd8..c695d8c0bb5 100644 --- a/github/repos.go +++ b/github/repos.go @@ -7,6 +7,7 @@ package github import ( "context" + "encoding/json" "fmt" "strings" ) @@ -1427,3 +1428,35 @@ func (s *RepositoriesService) Transfer(ctx context.Context, owner, repo string, return r, resp, nil } + +// DispatchRequestOptions represents a request to trigger a repository_dispatch event. +type DispatchRequestOptions struct { + // EventType is a custom webhook event name. (Required.) + EventType string `json:"event_type"` + // ClientPayload is a custom JSON payload with extra information about the webhook event. + // Defaults to an empty JSON object. + ClientPayload *json.RawMessage `json:"client_payload,omitempty"` +} + +// Dispatch triggers a repository_dispatch event in a GitHub Actions workflow. +// +// GitHub API docs: https://developer.github.com/v3/repos/#create-a-repository-dispatch-event +func (s *RepositoriesService) Dispatch(ctx context.Context, owner, repo string, opts DispatchRequestOptions) (*Repository, *Response, error) { + u := fmt.Sprintf("repos/%v/%v/dispatches", owner, repo) + + req, err := s.client.NewRequest("POST", u, &opts) + if err != nil { + return nil, nil, err + } + + // TODO: remove custom Accept header when this API fully launches. + req.Header.Set("Accept", mediaTypeRepositoryDispatchPreview) + + r := new(Repository) + resp, err := s.client.Do(ctx, req, r) + if err != nil { + return nil, resp, err + } + + return r, resp, nil +} diff --git a/github/repos_test.go b/github/repos_test.go index 1d4544663eb..1e48b7e2534 100644 --- a/github/repos_test.go +++ b/github/repos_test.go @@ -1796,3 +1796,95 @@ func TestRepositoriesService_Transfer(t *testing.T) { t.Errorf("Repositories.Transfer returned %+v, want %+v", got, want) } } + +func TestRepositoriesService_Dispatch(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + var input DispatchRequestOptions + + mux.HandleFunc("/repos/o/r/dispatches", func(w http.ResponseWriter, r *http.Request) { + var v DispatchRequestOptions + json.NewDecoder(r.Body).Decode(&v) + + testMethod(t, r, "POST") + testHeader(t, r, "Accept", mediaTypeRepositoryDispatchPreview) + if !reflect.DeepEqual(v, input) { + t.Errorf("Request body = %+v, want %+v", v, input) + } + + fmt.Fprint(w, `{"owner":{"login":"a"}}`) + }) + + ctx := context.Background() + + testCases := []interface{}{ + nil, + struct { + Foo string + }{ + Foo: "test", + }, + struct { + Bar int + }{ + Bar: 42, + }, + struct { + Foo string + Bar int + Baz bool + }{ + Foo: "test", + Bar: 42, + Baz: false, + }, + } + for _, tc := range testCases { + + if tc == nil { + input = DispatchRequestOptions{EventType: "go"} + } else { + bytes, _ := json.Marshal(tc) + payload := json.RawMessage(bytes) + input = DispatchRequestOptions{EventType: "go", ClientPayload: &payload} + } + + got, _, err := client.Repositories.Dispatch(ctx, "o", "r", input) + if err != nil { + t.Errorf("Repositories.Dispatch returned error: %v", err) + } + + want := &Repository{Owner: &User{Login: String("a")}} + if !reflect.DeepEqual(got, want) { + t.Errorf("Repositories.Dispatch returned %+v, want %+v", got, want) + } + } + + // Test s.client.NewRequest failure + client.BaseURL.Path = "" + got, resp, err := client.Repositories.Dispatch(ctx, "o", "r", input) + if got != nil { + t.Errorf("client.BaseURL.Path='' Dispatch = %#v, want nil", got) + } + if resp != nil { + t.Errorf("client.BaseURL.Path='' Dispatch resp = %#v, want nil", resp) + } + if err == nil { + t.Error("client.BaseURL.Path='' Dispatch err = nil, want error") + } + + // Test s.client.Do failure + client.BaseURL.Path = "/api-v3/" + client.rateLimits[0].Reset.Time = time.Now().Add(10 * time.Minute) + got, resp, err = client.Repositories.Dispatch(ctx, "o", "r", input) + if got != nil { + t.Errorf("rate.Reset.Time > now Dispatch = %#v, want nil", got) + } + if want := http.StatusForbidden; resp == nil || resp.Response.StatusCode != want { + t.Errorf("rate.Reset.Time > now Dispatch resp = %#v, want StatusCode=%v", resp.Response, want) + } + if err == nil { + t.Error("rate.Reset.Time > now Dispatch err = nil, want error") + } +} From b57bcf63fe0c7e1e1eb9651355cc8f0db15a6ae8 Mon Sep 17 00:00:00 2001 From: haya14busa Date: Wed, 8 Jan 2020 11:04:57 +0900 Subject: [PATCH 0100/1468] Re-populate HTTP response body of ErrorResponse (#1363) Fixes #1136. --- github/github.go | 9 ++++++--- github/github_test.go | 30 ++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/github/github.go b/github/github.go index 9c5040ec772..ad35287356f 100644 --- a/github/github.go +++ b/github/github.go @@ -726,9 +726,8 @@ func (e *Error) Error() string { // CheckResponse checks the API response for errors, and returns them if // present. A response is considered an error if it has a status code outside // the 200 range or equal to 202 Accepted. -// API error responses are expected to have either no response -// body, or a JSON response body that maps to ErrorResponse. Any other -// response body will be silently ignored. +// API error responses are expected to have response +// body, and a JSON response body that maps to ErrorResponse. // // The error type will be *RateLimitError for rate limit exceeded errors, // *AcceptedError for 202 Accepted status codes, @@ -745,6 +744,10 @@ func CheckResponse(r *http.Response) error { if err == nil && data != nil { json.Unmarshal(data, errorResponse) } + // Re-populate error response body because GitHub error responses are often + // undocumented and inconsistent. + // Issue #1136, #540. + r.Body = ioutil.NopCloser(bytes.NewBuffer(data)) switch { case r.StatusCode == http.StatusUnauthorized && strings.HasPrefix(r.Header.Get(headerOTP), "required"): return (*TwoFactorAuthError)(errorResponse) diff --git a/github/github_test.go b/github/github_test.go index 1aa3ef9b1bb..2bde0ac3b5d 100644 --- a/github/github_test.go +++ b/github/github_test.go @@ -942,6 +942,36 @@ func TestCheckResponse_noBody(t *testing.T) { } } +func TestCheckResponse_unexpectedErrorStructure(t *testing.T) { + httpBody := `{"message":"m", "errors": ["error 1"]}` + res := &http.Response{ + Request: &http.Request{}, + StatusCode: http.StatusBadRequest, + Body: ioutil.NopCloser(strings.NewReader(httpBody)), + } + err := CheckResponse(res).(*ErrorResponse) + + if err == nil { + t.Errorf("Expected error response.") + } + + want := &ErrorResponse{ + Response: res, + Message: "m", + Errors: []Error{{}}, + } + if !reflect.DeepEqual(err, want) { + t.Errorf("Error = %#v, want %#v", err, want) + } + data, err2 := ioutil.ReadAll(err.Response.Body) + if err2 != nil { + t.Fatalf("failed to read response body: %v", err) + } + if got := string(data); got != httpBody { + t.Errorf("ErrorResponse.Response.Body = %q, want %q", got, httpBody) + } +} + func TestParseBooleanResponse_true(t *testing.T) { result, err := parseBoolResponse(nil) if err != nil { From be5502b71328e51eb2b282f82221927cb4792ed5 Mon Sep 17 00:00:00 2001 From: haya14busa Date: Wed, 8 Jan 2020 11:14:12 +0900 Subject: [PATCH 0101/1468] Support unexpected error structure (#1364) Fixes #540. Related: #1136. --- github/github.go | 12 ++++++++++++ github/github_test.go | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/github/github.go b/github/github.go index ad35287356f..3ea1f6adcde 100644 --- a/github/github.go +++ b/github/github.go @@ -709,6 +709,10 @@ These are the possible validation error codes: some resources return this (e.g. github.User.CreateKey()), additional information is set in the Message field of the Error +GitHub error responses structure are often undocumented and inconsistent. +Sometimes error is just a simple string (Issue #540). +In such cases, Message represents an error message as a workaround. + GitHub API docs: https://developer.github.com/v3/#client-errors */ type Error struct { @@ -723,6 +727,14 @@ func (e *Error) Error() string { e.Code, e.Field, e.Resource) } +func (e *Error) UnmarshalJSON(data []byte) error { + type aliasError Error // avoid infinite recursion by using type alias. + if err := json.Unmarshal(data, (*aliasError)(e)); err != nil { + return json.Unmarshal(data, &e.Message) // data can be json string. + } + return nil +} + // CheckResponse checks the API response for errors, and returns them if // present. A response is considered an error if it has a status code outside // the 200 range or equal to 202 Accepted. diff --git a/github/github_test.go b/github/github_test.go index 2bde0ac3b5d..0780d14db50 100644 --- a/github/github_test.go +++ b/github/github_test.go @@ -958,7 +958,7 @@ func TestCheckResponse_unexpectedErrorStructure(t *testing.T) { want := &ErrorResponse{ Response: res, Message: "m", - Errors: []Error{{}}, + Errors: []Error{{Message: "error 1"}}, } if !reflect.DeepEqual(err, want) { t.Errorf("Error = %#v, want %#v", err, want) From a57775299c985b395c95231b7d97658dd6226bbf Mon Sep 17 00:00:00 2001 From: Glenn Lewis <6598971+gmlewis@users.noreply.github.com> Date: Wed, 8 Jan 2020 16:56:04 -0500 Subject: [PATCH 0102/1468] Add removeParent to EditTeam (#1357) Fixes #1267. --- github/teams.go | 40 ++++++++++++++++++++++++++++++++++++++-- github/teams_test.go | 43 ++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 80 insertions(+), 3 deletions(-) diff --git a/github/teams.go b/github/teams.go index 0300532f2df..2f7c6cb76e9 100644 --- a/github/teams.go +++ b/github/teams.go @@ -8,6 +8,7 @@ package github import ( "context" "fmt" + "net/http" "strings" "time" ) @@ -184,12 +185,47 @@ func (s *TeamsService) CreateTeam(ctx context.Context, org string, team NewTeam) return t, resp, nil } +// newTeamNoParent is the same as NewTeam but ensures that the +// "parent_team_id" field will be null. It is for internal use +// only and should not be exported. +type newTeamNoParent struct { + Name string `json:"name"` + Description *string `json:"description,omitempty"` + Maintainers []string `json:"maintainers,omitempty"` + RepoNames []string `json:"repo_names,omitempty"` + ParentTeamID *int64 `json:"parent_team_id"` // This will be "null" + Privacy *string `json:"privacy,omitempty"` + LDAPDN *string `json:"ldap_dn,omitempty"` +} + +// copyNewTeamWithoutParent is used to set the "parent_team_id" +// field to "null" after copying the other fields from a NewTeam. +// It is for internal use only and should not be exported. +func copyNewTeamWithoutParent(team *NewTeam) *newTeamNoParent { + return &newTeamNoParent{ + Name: team.Name, + Description: team.Description, + Maintainers: team.Maintainers, + RepoNames: team.RepoNames, + Privacy: team.Privacy, + LDAPDN: team.LDAPDN, + } +} + // EditTeam edits a team. // // GitHub API docs: https://developer.github.com/v3/teams/#edit-team -func (s *TeamsService) EditTeam(ctx context.Context, id int64, team NewTeam) (*Team, *Response, error) { +func (s *TeamsService) EditTeam(ctx context.Context, id int64, team NewTeam, removeParent bool) (*Team, *Response, error) { u := fmt.Sprintf("teams/%v", id) - req, err := s.client.NewRequest("PATCH", u, team) + + var req *http.Request + var err error + if removeParent { + teamRemoveParent := copyNewTeamWithoutParent(&team) + req, err = s.client.NewRequest("PATCH", u, teamRemoveParent) + } else { + req, err = s.client.NewRequest("PATCH", u, team) + } if err != nil { return nil, nil, err } diff --git a/github/teams_test.go b/github/teams_test.go index f68a14af03a..d65b7ffa882 100644 --- a/github/teams_test.go +++ b/github/teams_test.go @@ -6,9 +6,11 @@ package github import ( + "bytes" "context" "encoding/json" "fmt" + "io/ioutil" "net/http" "reflect" "strings" @@ -193,7 +195,7 @@ func TestTeamsService_EditTeam(t *testing.T) { fmt.Fprint(w, `{"id":1}`) }) - team, _, err := client.Teams.EditTeam(context.Background(), 1, input) + team, _, err := client.Teams.EditTeam(context.Background(), 1, input, false) if err != nil { t.Errorf("Teams.EditTeam returned error: %v", err) } @@ -204,6 +206,45 @@ func TestTeamsService_EditTeam(t *testing.T) { } } +func TestTeamsService_EditTeam_RemoveParent(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + input := NewTeam{Name: "n", Privacy: String("closed")} + var body string + + mux.HandleFunc("/teams/1", func(w http.ResponseWriter, r *http.Request) { + v := new(NewTeam) + buf, err := ioutil.ReadAll(r.Body) + if err != nil { + t.Errorf("Unable to read body: %v", err) + } + body = string(buf) + json.NewDecoder(bytes.NewBuffer(buf)).Decode(v) + + testMethod(t, r, "PATCH") + if !reflect.DeepEqual(v, &input) { + t.Errorf("Request body = %+v, want %+v", v, input) + } + + fmt.Fprint(w, `{"id":1}`) + }) + + team, _, err := client.Teams.EditTeam(context.Background(), 1, input, true) + if err != nil { + t.Errorf("Teams.EditTeam returned error: %v", err) + } + + want := &Team{ID: Int64(1)} + if !reflect.DeepEqual(team, want) { + t.Errorf("Teams.EditTeam returned %+v, want %+v", team, want) + } + + if want := `{"name":"n","parent_team_id":null,"privacy":"closed"}` + "\n"; body != want { + t.Errorf("Teams.EditTeam body = %+v, want %+v", body, want) + } +} + func TestTeamsService_DeleteTeam(t *testing.T) { client, mux, _, teardown := setup() defer teardown() From cfb91a4939527184d83c9bf5c00a5f8f3101031d Mon Sep 17 00:00:00 2001 From: Glenn Lewis <6598971+gmlewis@users.noreply.github.com> Date: Wed, 8 Jan 2020 16:59:23 -0500 Subject: [PATCH 0103/1468] Bump major version to v29 (#1344) --- README.md | 2 +- example/appengine/app.go | 2 +- example/basicauth/main.go | 2 +- example/commitpr/main.go | 2 +- example/migrations/main.go | 2 +- example/newrepo/main.go | 2 +- example/simple/main.go | 2 +- github/doc.go | 2 +- github/examples_test.go | 2 +- go.mod | 2 +- test/fields/fields.go | 2 +- test/integration/activity_test.go | 2 +- test/integration/authorizations_test.go | 2 +- test/integration/github_test.go | 2 +- test/integration/repos_test.go | 2 +- test/integration/users_test.go | 2 +- 16 files changed, 16 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index c6f5792454c..8a496fb058b 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ If you're interested in using the [GraphQL API v4][], the recommended library is ## Usage ## ```go -import "github.com/google/go-github/v28/github" // with go modules enabled (GO111MODULE=on or outside GOPATH) +import "github.com/google/go-github/v29/github" // with go modules enabled (GO111MODULE=on or outside GOPATH) import "github.com/google/go-github/github" // with go modules disabled ``` diff --git a/example/appengine/app.go b/example/appengine/app.go index 8f567496bb5..ba2818423f6 100644 --- a/example/appengine/app.go +++ b/example/appengine/app.go @@ -12,7 +12,7 @@ import ( "net/http" "os" - "github.com/google/go-github/v28/github" + "github.com/google/go-github/v29/github" "golang.org/x/oauth2" "google.golang.org/appengine" "google.golang.org/appengine/log" diff --git a/example/basicauth/main.go b/example/basicauth/main.go index 33b118ba61c..4c31a30c427 100644 --- a/example/basicauth/main.go +++ b/example/basicauth/main.go @@ -16,7 +16,7 @@ import ( "strings" "syscall" - "github.com/google/go-github/v28/github" + "github.com/google/go-github/v29/github" "golang.org/x/crypto/ssh/terminal" ) diff --git a/example/commitpr/main.go b/example/commitpr/main.go index 53061841aab..188424dc0eb 100644 --- a/example/commitpr/main.go +++ b/example/commitpr/main.go @@ -31,7 +31,7 @@ import ( "strings" "time" - "github.com/google/go-github/v28/github" + "github.com/google/go-github/v29/github" "golang.org/x/oauth2" ) diff --git a/example/migrations/main.go b/example/migrations/main.go index e0d30530758..d73380a7192 100644 --- a/example/migrations/main.go +++ b/example/migrations/main.go @@ -12,7 +12,7 @@ import ( "context" "fmt" - "github.com/google/go-github/v28/github" + "github.com/google/go-github/v29/github" "golang.org/x/oauth2" ) diff --git a/example/newrepo/main.go b/example/newrepo/main.go index 82eccf5eedd..4b03a4407f9 100644 --- a/example/newrepo/main.go +++ b/example/newrepo/main.go @@ -16,7 +16,7 @@ import ( "log" "os" - "github.com/google/go-github/v28/github" + "github.com/google/go-github/v29/github" "golang.org/x/oauth2" ) diff --git a/example/simple/main.go b/example/simple/main.go index 8bab9603635..33af5e5eaef 100644 --- a/example/simple/main.go +++ b/example/simple/main.go @@ -12,7 +12,7 @@ import ( "context" "fmt" - "github.com/google/go-github/v28/github" + "github.com/google/go-github/v29/github" ) // Fetch all the public organizations' membership of a user. diff --git a/github/doc.go b/github/doc.go index 8adfdc1d49b..403a6ecc6fa 100644 --- a/github/doc.go +++ b/github/doc.go @@ -8,7 +8,7 @@ Package github provides a client for using the GitHub API. Usage: - import "github.com/google/go-github/v28/github" // with go modules enabled (GO111MODULE=on or outside GOPATH) + import "github.com/google/go-github/v29/github" // with go modules enabled (GO111MODULE=on or outside GOPATH) import "github.com/google/go-github/github" // with go modules disabled Construct a new GitHub client, then use the various services on the client to diff --git a/github/examples_test.go b/github/examples_test.go index a47f927ec60..3035f0ccf7f 100644 --- a/github/examples_test.go +++ b/github/examples_test.go @@ -12,7 +12,7 @@ import ( "fmt" "log" - "github.com/google/go-github/v28/github" + "github.com/google/go-github/v29/github" ) func ExampleClient_Markdown() { diff --git a/go.mod b/go.mod index 23ce41ca4bb..bb82bb43edb 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module github.com/google/go-github/v28 +module github.com/google/go-github/v29 require ( github.com/golang/protobuf v1.3.2 // indirect diff --git a/test/fields/fields.go b/test/fields/fields.go index 6c7eac6b886..59a2c6476bd 100644 --- a/test/fields/fields.go +++ b/test/fields/fields.go @@ -25,7 +25,7 @@ import ( "reflect" "strings" - "github.com/google/go-github/v28/github" + "github.com/google/go-github/v29/github" "golang.org/x/oauth2" ) diff --git a/test/integration/activity_test.go b/test/integration/activity_test.go index 0ec78056e5a..15daf5d067b 100644 --- a/test/integration/activity_test.go +++ b/test/integration/activity_test.go @@ -11,7 +11,7 @@ import ( "context" "testing" - "github.com/google/go-github/v28/github" + "github.com/google/go-github/v29/github" ) const ( diff --git a/test/integration/authorizations_test.go b/test/integration/authorizations_test.go index f6f065d3692..7eaeca392b8 100644 --- a/test/integration/authorizations_test.go +++ b/test/integration/authorizations_test.go @@ -16,7 +16,7 @@ import ( "testing" "time" - "github.com/google/go-github/v28/github" + "github.com/google/go-github/v29/github" ) const msgEnvMissing = "Skipping test because the required environment variable (%v) is not present." diff --git a/test/integration/github_test.go b/test/integration/github_test.go index e68a56c44cf..a9aace3ff47 100644 --- a/test/integration/github_test.go +++ b/test/integration/github_test.go @@ -14,7 +14,7 @@ import ( "net/http" "os" - "github.com/google/go-github/v28/github" + "github.com/google/go-github/v29/github" "golang.org/x/oauth2" ) diff --git a/test/integration/repos_test.go b/test/integration/repos_test.go index c722fabdf3e..e4a09bfbf08 100644 --- a/test/integration/repos_test.go +++ b/test/integration/repos_test.go @@ -13,7 +13,7 @@ import ( "reflect" "testing" - "github.com/google/go-github/v28/github" + "github.com/google/go-github/v29/github" ) func TestRepositories_CRUD(t *testing.T) { diff --git a/test/integration/users_test.go b/test/integration/users_test.go index 3d587b694a6..bb8c5e23692 100644 --- a/test/integration/users_test.go +++ b/test/integration/users_test.go @@ -13,7 +13,7 @@ import ( "math/rand" "testing" - "github.com/google/go-github/v28/github" + "github.com/google/go-github/v29/github" ) func TestUsers_Get(t *testing.T) { From 26c91e4047b5d84455acadce710689969da00f60 Mon Sep 17 00:00:00 2001 From: Glenn Lewis <6598971+gmlewis@users.noreply.github.com> Date: Wed, 8 Jan 2020 17:12:44 -0500 Subject: [PATCH 0104/1468] Revert "Bump major version to v29 (#1344)" (#1366) This reverts commit cfb91a4939527184d83c9bf5c00a5f8f3101031d. --- README.md | 2 +- example/appengine/app.go | 2 +- example/basicauth/main.go | 2 +- example/commitpr/main.go | 2 +- example/migrations/main.go | 2 +- example/newrepo/main.go | 2 +- example/simple/main.go | 2 +- github/doc.go | 2 +- github/examples_test.go | 2 +- go.mod | 2 +- test/fields/fields.go | 2 +- test/integration/activity_test.go | 2 +- test/integration/authorizations_test.go | 2 +- test/integration/github_test.go | 2 +- test/integration/repos_test.go | 2 +- test/integration/users_test.go | 2 +- 16 files changed, 16 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 8a496fb058b..c6f5792454c 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ If you're interested in using the [GraphQL API v4][], the recommended library is ## Usage ## ```go -import "github.com/google/go-github/v29/github" // with go modules enabled (GO111MODULE=on or outside GOPATH) +import "github.com/google/go-github/v28/github" // with go modules enabled (GO111MODULE=on or outside GOPATH) import "github.com/google/go-github/github" // with go modules disabled ``` diff --git a/example/appengine/app.go b/example/appengine/app.go index ba2818423f6..8f567496bb5 100644 --- a/example/appengine/app.go +++ b/example/appengine/app.go @@ -12,7 +12,7 @@ import ( "net/http" "os" - "github.com/google/go-github/v29/github" + "github.com/google/go-github/v28/github" "golang.org/x/oauth2" "google.golang.org/appengine" "google.golang.org/appengine/log" diff --git a/example/basicauth/main.go b/example/basicauth/main.go index 4c31a30c427..33b118ba61c 100644 --- a/example/basicauth/main.go +++ b/example/basicauth/main.go @@ -16,7 +16,7 @@ import ( "strings" "syscall" - "github.com/google/go-github/v29/github" + "github.com/google/go-github/v28/github" "golang.org/x/crypto/ssh/terminal" ) diff --git a/example/commitpr/main.go b/example/commitpr/main.go index 188424dc0eb..53061841aab 100644 --- a/example/commitpr/main.go +++ b/example/commitpr/main.go @@ -31,7 +31,7 @@ import ( "strings" "time" - "github.com/google/go-github/v29/github" + "github.com/google/go-github/v28/github" "golang.org/x/oauth2" ) diff --git a/example/migrations/main.go b/example/migrations/main.go index d73380a7192..e0d30530758 100644 --- a/example/migrations/main.go +++ b/example/migrations/main.go @@ -12,7 +12,7 @@ import ( "context" "fmt" - "github.com/google/go-github/v29/github" + "github.com/google/go-github/v28/github" "golang.org/x/oauth2" ) diff --git a/example/newrepo/main.go b/example/newrepo/main.go index 4b03a4407f9..82eccf5eedd 100644 --- a/example/newrepo/main.go +++ b/example/newrepo/main.go @@ -16,7 +16,7 @@ import ( "log" "os" - "github.com/google/go-github/v29/github" + "github.com/google/go-github/v28/github" "golang.org/x/oauth2" ) diff --git a/example/simple/main.go b/example/simple/main.go index 33af5e5eaef..8bab9603635 100644 --- a/example/simple/main.go +++ b/example/simple/main.go @@ -12,7 +12,7 @@ import ( "context" "fmt" - "github.com/google/go-github/v29/github" + "github.com/google/go-github/v28/github" ) // Fetch all the public organizations' membership of a user. diff --git a/github/doc.go b/github/doc.go index 403a6ecc6fa..8adfdc1d49b 100644 --- a/github/doc.go +++ b/github/doc.go @@ -8,7 +8,7 @@ Package github provides a client for using the GitHub API. Usage: - import "github.com/google/go-github/v29/github" // with go modules enabled (GO111MODULE=on or outside GOPATH) + import "github.com/google/go-github/v28/github" // with go modules enabled (GO111MODULE=on or outside GOPATH) import "github.com/google/go-github/github" // with go modules disabled Construct a new GitHub client, then use the various services on the client to diff --git a/github/examples_test.go b/github/examples_test.go index 3035f0ccf7f..a47f927ec60 100644 --- a/github/examples_test.go +++ b/github/examples_test.go @@ -12,7 +12,7 @@ import ( "fmt" "log" - "github.com/google/go-github/v29/github" + "github.com/google/go-github/v28/github" ) func ExampleClient_Markdown() { diff --git a/go.mod b/go.mod index bb82bb43edb..23ce41ca4bb 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module github.com/google/go-github/v29 +module github.com/google/go-github/v28 require ( github.com/golang/protobuf v1.3.2 // indirect diff --git a/test/fields/fields.go b/test/fields/fields.go index 59a2c6476bd..6c7eac6b886 100644 --- a/test/fields/fields.go +++ b/test/fields/fields.go @@ -25,7 +25,7 @@ import ( "reflect" "strings" - "github.com/google/go-github/v29/github" + "github.com/google/go-github/v28/github" "golang.org/x/oauth2" ) diff --git a/test/integration/activity_test.go b/test/integration/activity_test.go index 15daf5d067b..0ec78056e5a 100644 --- a/test/integration/activity_test.go +++ b/test/integration/activity_test.go @@ -11,7 +11,7 @@ import ( "context" "testing" - "github.com/google/go-github/v29/github" + "github.com/google/go-github/v28/github" ) const ( diff --git a/test/integration/authorizations_test.go b/test/integration/authorizations_test.go index 7eaeca392b8..f6f065d3692 100644 --- a/test/integration/authorizations_test.go +++ b/test/integration/authorizations_test.go @@ -16,7 +16,7 @@ import ( "testing" "time" - "github.com/google/go-github/v29/github" + "github.com/google/go-github/v28/github" ) const msgEnvMissing = "Skipping test because the required environment variable (%v) is not present." diff --git a/test/integration/github_test.go b/test/integration/github_test.go index a9aace3ff47..e68a56c44cf 100644 --- a/test/integration/github_test.go +++ b/test/integration/github_test.go @@ -14,7 +14,7 @@ import ( "net/http" "os" - "github.com/google/go-github/v29/github" + "github.com/google/go-github/v28/github" "golang.org/x/oauth2" ) diff --git a/test/integration/repos_test.go b/test/integration/repos_test.go index e4a09bfbf08..c722fabdf3e 100644 --- a/test/integration/repos_test.go +++ b/test/integration/repos_test.go @@ -13,7 +13,7 @@ import ( "reflect" "testing" - "github.com/google/go-github/v29/github" + "github.com/google/go-github/v28/github" ) func TestRepositories_CRUD(t *testing.T) { diff --git a/test/integration/users_test.go b/test/integration/users_test.go index bb8c5e23692..3d587b694a6 100644 --- a/test/integration/users_test.go +++ b/test/integration/users_test.go @@ -13,7 +13,7 @@ import ( "math/rand" "testing" - "github.com/google/go-github/v29/github" + "github.com/google/go-github/v28/github" ) func TestUsers_Get(t *testing.T) { From a3f3689e805a0a288cce41174a197b07174f09e4 Mon Sep 17 00:00:00 2001 From: Glenn Lewis <6598971+gmlewis@users.noreply.github.com> Date: Wed, 8 Jan 2020 19:19:21 -0500 Subject: [PATCH 0105/1468] Bump major version to v29 (take 2) (#1367) Fixes #1365. --- README.md | 2 +- example/appengine/app.go | 2 +- example/basicauth/main.go | 2 +- example/commitpr/main.go | 2 +- example/migrations/main.go | 2 +- example/newrepo/main.go | 2 +- example/simple/main.go | 2 +- example/topics/main.go | 2 +- github/doc.go | 2 +- github/examples_test.go | 2 +- go.mod | 2 +- test/fields/fields.go | 2 +- test/integration/activity_test.go | 2 +- test/integration/authorizations_test.go | 2 +- test/integration/github_test.go | 2 +- test/integration/repos_test.go | 2 +- test/integration/users_test.go | 2 +- 17 files changed, 17 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index c6f5792454c..8a496fb058b 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ If you're interested in using the [GraphQL API v4][], the recommended library is ## Usage ## ```go -import "github.com/google/go-github/v28/github" // with go modules enabled (GO111MODULE=on or outside GOPATH) +import "github.com/google/go-github/v29/github" // with go modules enabled (GO111MODULE=on or outside GOPATH) import "github.com/google/go-github/github" // with go modules disabled ``` diff --git a/example/appengine/app.go b/example/appengine/app.go index 8f567496bb5..ba2818423f6 100644 --- a/example/appengine/app.go +++ b/example/appengine/app.go @@ -12,7 +12,7 @@ import ( "net/http" "os" - "github.com/google/go-github/v28/github" + "github.com/google/go-github/v29/github" "golang.org/x/oauth2" "google.golang.org/appengine" "google.golang.org/appengine/log" diff --git a/example/basicauth/main.go b/example/basicauth/main.go index 33b118ba61c..4c31a30c427 100644 --- a/example/basicauth/main.go +++ b/example/basicauth/main.go @@ -16,7 +16,7 @@ import ( "strings" "syscall" - "github.com/google/go-github/v28/github" + "github.com/google/go-github/v29/github" "golang.org/x/crypto/ssh/terminal" ) diff --git a/example/commitpr/main.go b/example/commitpr/main.go index 53061841aab..188424dc0eb 100644 --- a/example/commitpr/main.go +++ b/example/commitpr/main.go @@ -31,7 +31,7 @@ import ( "strings" "time" - "github.com/google/go-github/v28/github" + "github.com/google/go-github/v29/github" "golang.org/x/oauth2" ) diff --git a/example/migrations/main.go b/example/migrations/main.go index e0d30530758..d73380a7192 100644 --- a/example/migrations/main.go +++ b/example/migrations/main.go @@ -12,7 +12,7 @@ import ( "context" "fmt" - "github.com/google/go-github/v28/github" + "github.com/google/go-github/v29/github" "golang.org/x/oauth2" ) diff --git a/example/newrepo/main.go b/example/newrepo/main.go index 82eccf5eedd..4b03a4407f9 100644 --- a/example/newrepo/main.go +++ b/example/newrepo/main.go @@ -16,7 +16,7 @@ import ( "log" "os" - "github.com/google/go-github/v28/github" + "github.com/google/go-github/v29/github" "golang.org/x/oauth2" ) diff --git a/example/simple/main.go b/example/simple/main.go index 8bab9603635..33af5e5eaef 100644 --- a/example/simple/main.go +++ b/example/simple/main.go @@ -12,7 +12,7 @@ import ( "context" "fmt" - "github.com/google/go-github/v28/github" + "github.com/google/go-github/v29/github" ) // Fetch all the public organizations' membership of a user. diff --git a/example/topics/main.go b/example/topics/main.go index 96098efe14f..da814a4abfb 100644 --- a/example/topics/main.go +++ b/example/topics/main.go @@ -12,7 +12,7 @@ import ( "context" "fmt" - "github.com/google/go-github/v28/github" + "github.com/google/go-github/v29/github" ) // Fetch all the public organizations' membership of a user. diff --git a/github/doc.go b/github/doc.go index 8adfdc1d49b..403a6ecc6fa 100644 --- a/github/doc.go +++ b/github/doc.go @@ -8,7 +8,7 @@ Package github provides a client for using the GitHub API. Usage: - import "github.com/google/go-github/v28/github" // with go modules enabled (GO111MODULE=on or outside GOPATH) + import "github.com/google/go-github/v29/github" // with go modules enabled (GO111MODULE=on or outside GOPATH) import "github.com/google/go-github/github" // with go modules disabled Construct a new GitHub client, then use the various services on the client to diff --git a/github/examples_test.go b/github/examples_test.go index a47f927ec60..3035f0ccf7f 100644 --- a/github/examples_test.go +++ b/github/examples_test.go @@ -12,7 +12,7 @@ import ( "fmt" "log" - "github.com/google/go-github/v28/github" + "github.com/google/go-github/v29/github" ) func ExampleClient_Markdown() { diff --git a/go.mod b/go.mod index 23ce41ca4bb..bb82bb43edb 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module github.com/google/go-github/v28 +module github.com/google/go-github/v29 require ( github.com/golang/protobuf v1.3.2 // indirect diff --git a/test/fields/fields.go b/test/fields/fields.go index 6c7eac6b886..59a2c6476bd 100644 --- a/test/fields/fields.go +++ b/test/fields/fields.go @@ -25,7 +25,7 @@ import ( "reflect" "strings" - "github.com/google/go-github/v28/github" + "github.com/google/go-github/v29/github" "golang.org/x/oauth2" ) diff --git a/test/integration/activity_test.go b/test/integration/activity_test.go index 0ec78056e5a..15daf5d067b 100644 --- a/test/integration/activity_test.go +++ b/test/integration/activity_test.go @@ -11,7 +11,7 @@ import ( "context" "testing" - "github.com/google/go-github/v28/github" + "github.com/google/go-github/v29/github" ) const ( diff --git a/test/integration/authorizations_test.go b/test/integration/authorizations_test.go index f6f065d3692..7eaeca392b8 100644 --- a/test/integration/authorizations_test.go +++ b/test/integration/authorizations_test.go @@ -16,7 +16,7 @@ import ( "testing" "time" - "github.com/google/go-github/v28/github" + "github.com/google/go-github/v29/github" ) const msgEnvMissing = "Skipping test because the required environment variable (%v) is not present." diff --git a/test/integration/github_test.go b/test/integration/github_test.go index e68a56c44cf..a9aace3ff47 100644 --- a/test/integration/github_test.go +++ b/test/integration/github_test.go @@ -14,7 +14,7 @@ import ( "net/http" "os" - "github.com/google/go-github/v28/github" + "github.com/google/go-github/v29/github" "golang.org/x/oauth2" ) diff --git a/test/integration/repos_test.go b/test/integration/repos_test.go index c722fabdf3e..e4a09bfbf08 100644 --- a/test/integration/repos_test.go +++ b/test/integration/repos_test.go @@ -13,7 +13,7 @@ import ( "reflect" "testing" - "github.com/google/go-github/v28/github" + "github.com/google/go-github/v29/github" ) func TestRepositories_CRUD(t *testing.T) { diff --git a/test/integration/users_test.go b/test/integration/users_test.go index 3d587b694a6..bb8c5e23692 100644 --- a/test/integration/users_test.go +++ b/test/integration/users_test.go @@ -13,7 +13,7 @@ import ( "math/rand" "testing" - "github.com/google/go-github/v28/github" + "github.com/google/go-github/v29/github" ) func TestUsers_Get(t *testing.T) { From 78e8856b7e8c0ad992326adf860a41434ce46ee5 Mon Sep 17 00:00:00 2001 From: Glenn Lewis <6598971+gmlewis@users.noreply.github.com> Date: Thu, 9 Jan 2020 07:41:20 -0500 Subject: [PATCH 0106/1468] Update AUTHORS with recent contributors (#1368) --- AUTHORS | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/AUTHORS b/AUTHORS index fa0f1abc935..91ef2d84a20 100644 --- a/AUTHORS +++ b/AUTHORS @@ -9,6 +9,7 @@ # their employer, as appropriate). 178inaba +413x Abhinav Gupta adrienzieba Ahmed Hagy @@ -56,6 +57,7 @@ chandresh-pancholi Charles Fenwick Elliott Charlie Yan Chris King +Chris Raborg Chris Roche Chris Schaefer chrisforrette @@ -67,11 +69,14 @@ Cristian Maglie Daehyeok Mun Daniel Leavitt Daniel Nilsson +Daoq Dave Du Cros Dave Henderson +Dave Protasowski David Deng David Jannotta David Ji +David Lopez Reyes Davide Zipeto Dennis Webb Dhi Aurrahman @@ -81,6 +86,7 @@ dmnlk Don Petersen Doug Turner Drew Fradette +Eivind Eli Uriegas Elliott Beach Emerson Wood @@ -94,10 +100,12 @@ Filippo Valsorda Florian Forster Francesc Gil Francis +Francisco Guimarães Fredrik Jönsson Garrett Squire George Kontridze Georgy Buranov +Glen Mailer Gnahz Google Inc. Grachev Mikhail @@ -107,13 +115,16 @@ Guz Alexander Guðmundur Bjarni Ólafsson Hanno Hecker Hari haran +haya14busa haya14busa Huy Tr huydx i2bskn +Ioannis Georgoulas Isao Jonas isqua Jameel Haffejee +James Cockbain Jan Kosecki Javier Campanini Jens Rantil @@ -179,6 +190,7 @@ Nikhita Raghunath Noah Zoschke ns-cweber Oleg Kovalov +Ole Orhagen Ondřej Kupka Palash Nigam Panagiotis Moustafellos @@ -190,11 +202,13 @@ Pete Wagner Petr Shevtsov Pierre Carrier Piotr Zurek +Quang Le Hong Quentin Leffray Quinn Slack Rackspace US, Inc. Radek Simko Radliński Ignacy +Rajat Jindal Rajendra arora Ranbir Singh RaviTeja Pothana @@ -207,10 +221,12 @@ Ronak Jain Ruben Vereecken Ryan Leung Ryan Lower +Safwan Olaimat Sahil Dua saisi Sam Minnée Sandeep Sukhani +Sander Knape Sander van Harmelen Sanket Payghan Sarasa Kisaragi @@ -218,21 +234,27 @@ Sean Wang Sebastian Mandrean Sebastian Mæland Pedersen Sergey Romanov +Sergio Garcia Sevki Shagun Khemka shakeelrao Shawn Catanzarite Shawn Smith +Shibasis Patel Shrikrishna Singh sona-tar SoundCloud, Ltd. Sridhar Mocherla SriVignessh Pss Stian Eikeland +Suhaib Mujahid Szymon Kodrebski +Takayuki Watanabe +Taketoshi Fujiwara Tasya Aditya Rukmana Thomas Bruyelle Timothée Peignier +tkhandel Trey Tacon ttacon Vaibhav Singh @@ -242,6 +264,7 @@ Victor Vrantchan Vlad Ungureanu Wasim Thabraze Will Maier +Willem D'Haeseleer William Bailey William Cooke xibz From 4b2f23048c242c6401504f66ae52c2cccf53d9e2 Mon Sep 17 00:00:00 2001 From: haya14busa Date: Fri, 10 Jan 2020 10:18:11 +0900 Subject: [PATCH 0107/1468] Fix JSON unmarshal error of App.app.events (#1370) --- github/apps.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/github/apps.go b/github/apps.go index 251ac631053..5bd76338dca 100644 --- a/github/apps.go +++ b/github/apps.go @@ -30,7 +30,7 @@ type App struct { CreatedAt *Timestamp `json:"created_at,omitempty"` UpdatedAt *Timestamp `json:"updated_at,omitempty"` Permissions *InstallationPermissions `json:"permissions,omitempty"` - Events []*Event `json:"events,omitempty"` + Events []string `json:"events,omitempty"` } // InstallationToken represents an installation token. From ab35a4779b48b6089e8d3a80cc99c544695853eb Mon Sep 17 00:00:00 2001 From: Glenn Lewis <6598971+gmlewis@users.noreply.github.com> Date: Fri, 10 Jan 2020 07:31:30 -0500 Subject: [PATCH 0108/1468] Implement file deletion for CreateTree (#1372) --- github/git_trees.go | 35 ++++++++++++++++++++++++++--- github/git_trees_test.go | 48 +++++++++++++++++++--------------------- 2 files changed, 55 insertions(+), 28 deletions(-) diff --git a/github/git_trees.go b/github/git_trees.go index df843f4de9a..7714946cf96 100644 --- a/github/git_trees.go +++ b/github/git_trees.go @@ -44,6 +44,20 @@ func (t TreeEntry) String() string { return Stringify(t) } +// treeEntryWithFileDelete is used internally to delete a file whose +// Content and SHA fields are empty. It does this by removing the "omitempty" +// tag modifier on the SHA field which causes the GitHub API to receive +// {"sha":null} and thereby delete the file. +type treeEntryWithFileDelete struct { + SHA *string `json:"sha"` + Path *string `json:"path,omitempty"` + Mode *string `json:"mode,omitempty"` + Type *string `json:"type,omitempty"` + Size *int `json:"size,omitempty"` + Content *string `json:"content,omitempty"` + URL *string `json:"url,omitempty"` +} + func (t *TreeEntry) MarshalJSON() ([]byte, error) { if t.SHA == nil && t.Content == nil { return json.Marshal(struct { @@ -102,8 +116,8 @@ func (s *GitService) GetTree(ctx context.Context, owner string, repo string, sha // createTree represents the body of a CreateTree request. type createTree struct { - BaseTree string `json:"base_tree,omitempty"` - Entries []TreeEntry `json:"tree"` + BaseTree string `json:"base_tree,omitempty"` + Entries []interface{} `json:"tree"` } // CreateTree creates a new tree in a repository. If both a tree and a nested @@ -114,9 +128,24 @@ type createTree struct { func (s *GitService) CreateTree(ctx context.Context, owner string, repo string, baseTree string, entries []TreeEntry) (*Tree, *Response, error) { u := fmt.Sprintf("repos/%v/%v/git/trees", owner, repo) + newEntries := make([]interface{}, 0, len(entries)) + for _, entry := range entries { + if entry.Content == nil && entry.SHA == nil { + newEntries = append(newEntries, treeEntryWithFileDelete{ + Path: entry.Path, + Mode: entry.Mode, + Type: entry.Type, + Size: entry.Size, + URL: entry.URL, + }) + continue + } + newEntries = append(newEntries, entry) + } + body := &createTree{ BaseTree: baseTree, - Entries: entries, + Entries: newEntries, } req, err := s.client.NewRequest("POST", u, body) if err != nil { diff --git a/github/git_trees_test.go b/github/git_trees_test.go index 1d1b789cd6f..3e76527403c 100644 --- a/github/git_trees_test.go +++ b/github/git_trees_test.go @@ -6,9 +6,10 @@ package github import ( + "bytes" "context" - "encoding/json" "fmt" + "io/ioutil" "net/http" "reflect" "testing" @@ -68,17 +69,16 @@ func TestGitService_CreateTree(t *testing.T) { } mux.HandleFunc("/repos/o/r/git/trees", func(w http.ResponseWriter, r *http.Request) { - v := new(createTree) - json.NewDecoder(r.Body).Decode(v) + got, err := ioutil.ReadAll(r.Body) + if err != nil { + t.Fatalf("unable to read body: %v", err) + } testMethod(t, r, "POST") - want := &createTree{ - BaseTree: "b", - Entries: input, - } - if !reflect.DeepEqual(v, want) { - t.Errorf("Git.CreateTree request body: %+v, want %+v", v, want) + want := []byte(`{"base_tree":"b","tree":[{"sha":"7c258a9869f33c1e1e1f74fbb32f07c86cb5a75b","path":"file.rb","mode":"100644","type":"blob"}]}` + "\n") + if !bytes.Equal(got, want) { + t.Errorf("Git.CreateTree request body: %s, want %s", got, want) } fmt.Fprint(w, `{ @@ -132,17 +132,16 @@ func TestGitService_CreateTree_Content(t *testing.T) { } mux.HandleFunc("/repos/o/r/git/trees", func(w http.ResponseWriter, r *http.Request) { - v := new(createTree) - json.NewDecoder(r.Body).Decode(v) + got, err := ioutil.ReadAll(r.Body) + if err != nil { + t.Fatalf("unable to read body: %v", err) + } testMethod(t, r, "POST") - want := &createTree{ - BaseTree: "b", - Entries: input, - } - if !reflect.DeepEqual(v, want) { - t.Errorf("Git.CreateTree request body: %+v, want %+v", v, want) + want := []byte(`{"base_tree":"b","tree":[{"path":"content.md","mode":"100644","content":"file content"}]}` + "\n") + if !bytes.Equal(got, want) { + t.Errorf("Git.CreateTree request body: %s, want %s", got, want) } fmt.Fprint(w, `{ @@ -198,17 +197,16 @@ func TestGitService_CreateTree_Delete(t *testing.T) { } mux.HandleFunc("/repos/o/r/git/trees", func(w http.ResponseWriter, r *http.Request) { - v := new(createTree) - json.NewDecoder(r.Body).Decode(v) + got, err := ioutil.ReadAll(r.Body) + if err != nil { + t.Fatalf("unable to read body: %v", err) + } testMethod(t, r, "POST") - want := &createTree{ - BaseTree: "b", - Entries: input, - } - if !reflect.DeepEqual(v, want) { - t.Errorf("Git.CreateTree request body: %+v, want %+v", v, want) + want := []byte(`{"base_tree":"b","tree":[{"sha":null,"path":"content.md","mode":"100644"}]}` + "\n") + if !bytes.Equal(got, want) { + t.Errorf("Git.CreateTree request body: %s, want %s", got, want) } fmt.Fprint(w, `{ From ac9200d19f35fee922744b768dd393140a9939c8 Mon Sep 17 00:00:00 2001 From: Carlos Tadeu Panato Junior Date: Mon, 13 Jan 2020 13:55:21 +0100 Subject: [PATCH 0109/1468] remove deprecated custom preview header (#1374) Fixes: #1373. --- github/github.go | 3 --- github/migrations_source_import.go | 24 ------------------------ github/migrations_source_import_test.go | 8 -------- 3 files changed, 35 deletions(-) diff --git a/github/github.go b/github/github.go index 3ea1f6adcde..b752c37b753 100644 --- a/github/github.go +++ b/github/github.go @@ -58,9 +58,6 @@ const ( // https://developer.github.com/changes/2018-10-16-deployments-environments-states-and-auto-inactive-updates/ mediaTypeExpandDeploymentStatusPreview = "application/vnd.github.flash-preview+json" - // https://developer.github.com/changes/2016-02-19-source-import-preview-api/ - mediaTypeImportPreview = "application/vnd.github.barred-rock-preview" - // https://developer.github.com/changes/2016-05-12-reactions-api-preview/ mediaTypeReactionsPreview = "application/vnd.github.squirrel-girl-preview" diff --git a/github/migrations_source_import.go b/github/migrations_source_import.go index fd45e780065..080a5503f6b 100644 --- a/github/migrations_source_import.go +++ b/github/migrations_source_import.go @@ -154,9 +154,6 @@ func (s *MigrationService) StartImport(ctx context.Context, owner, repo string, return nil, nil, err } - // TODO: remove custom Accept header when this API fully launches - req.Header.Set("Accept", mediaTypeImportPreview) - out := new(Import) resp, err := s.client.Do(ctx, req, out) if err != nil { @@ -176,9 +173,6 @@ func (s *MigrationService) ImportProgress(ctx context.Context, owner, repo strin return nil, nil, err } - // TODO: remove custom Accept header when this API fully launches - req.Header.Set("Accept", mediaTypeImportPreview) - out := new(Import) resp, err := s.client.Do(ctx, req, out) if err != nil { @@ -198,9 +192,6 @@ func (s *MigrationService) UpdateImport(ctx context.Context, owner, repo string, return nil, nil, err } - // TODO: remove custom Accept header when this API fully launches - req.Header.Set("Accept", mediaTypeImportPreview) - out := new(Import) resp, err := s.client.Do(ctx, req, out) if err != nil { @@ -230,9 +221,6 @@ func (s *MigrationService) CommitAuthors(ctx context.Context, owner, repo string return nil, nil, err } - // TODO: remove custom Accept header when this API fully launches - req.Header.Set("Accept", mediaTypeImportPreview) - var authors []*SourceImportAuthor resp, err := s.client.Do(ctx, req, &authors) if err != nil { @@ -254,9 +242,6 @@ func (s *MigrationService) MapCommitAuthor(ctx context.Context, owner, repo stri return nil, nil, err } - // TODO: remove custom Accept header when this API fully launches - req.Header.Set("Accept", mediaTypeImportPreview) - out := new(SourceImportAuthor) resp, err := s.client.Do(ctx, req, out) if err != nil { @@ -278,9 +263,6 @@ func (s *MigrationService) SetLFSPreference(ctx context.Context, owner, repo str return nil, nil, err } - // TODO: remove custom Accept header when this API fully launches - req.Header.Set("Accept", mediaTypeImportPreview) - out := new(Import) resp, err := s.client.Do(ctx, req, out) if err != nil { @@ -300,9 +282,6 @@ func (s *MigrationService) LargeFiles(ctx context.Context, owner, repo string) ( return nil, nil, err } - // TODO: remove custom Accept header when this API fully launches - req.Header.Set("Accept", mediaTypeImportPreview) - var files []*LargeFile resp, err := s.client.Do(ctx, req, &files) if err != nil { @@ -322,8 +301,5 @@ func (s *MigrationService) CancelImport(ctx context.Context, owner, repo string) return nil, err } - // TODO: remove custom Accept header when this API fully launches - req.Header.Set("Accept", mediaTypeImportPreview) - return s.client.Do(ctx, req, nil) } diff --git a/github/migrations_source_import_test.go b/github/migrations_source_import_test.go index e9e9be062be..ea76aabfd43 100644 --- a/github/migrations_source_import_test.go +++ b/github/migrations_source_import_test.go @@ -30,7 +30,6 @@ func TestMigrationService_StartImport(t *testing.T) { json.NewDecoder(r.Body).Decode(v) testMethod(t, r, "PUT") - testHeader(t, r, "Accept", mediaTypeImportPreview) if !reflect.DeepEqual(v, input) { t.Errorf("Request body = %+v, want %+v", v, input) } @@ -55,7 +54,6 @@ func TestMigrationService_ImportProgress(t *testing.T) { mux.HandleFunc("/repos/o/r/import", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") - testHeader(t, r, "Accept", mediaTypeImportPreview) fmt.Fprint(w, `{"status":"complete"}`) }) @@ -85,7 +83,6 @@ func TestMigrationService_UpdateImport(t *testing.T) { json.NewDecoder(r.Body).Decode(v) testMethod(t, r, "PATCH") - testHeader(t, r, "Accept", mediaTypeImportPreview) if !reflect.DeepEqual(v, input) { t.Errorf("Request body = %+v, want %+v", v, input) } @@ -110,7 +107,6 @@ func TestMigrationService_CommitAuthors(t *testing.T) { mux.HandleFunc("/repos/o/r/import/authors", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") - testHeader(t, r, "Accept", mediaTypeImportPreview) fmt.Fprint(w, `[{"id":1,"name":"a"},{"id":2,"name":"b"}]`) }) @@ -138,7 +134,6 @@ func TestMigrationService_MapCommitAuthor(t *testing.T) { json.NewDecoder(r.Body).Decode(v) testMethod(t, r, "PATCH") - testHeader(t, r, "Accept", mediaTypeImportPreview) if !reflect.DeepEqual(v, input) { t.Errorf("Request body = %+v, want %+v", v, input) } @@ -167,7 +162,6 @@ func TestMigrationService_SetLFSPreference(t *testing.T) { json.NewDecoder(r.Body).Decode(v) testMethod(t, r, "PATCH") - testHeader(t, r, "Accept", mediaTypeImportPreview) if !reflect.DeepEqual(v, input) { t.Errorf("Request body = %+v, want %+v", v, input) } @@ -192,7 +186,6 @@ func TestMigrationService_LargeFiles(t *testing.T) { mux.HandleFunc("/repos/o/r/import/large_files", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") - testHeader(t, r, "Accept", mediaTypeImportPreview) fmt.Fprint(w, `[{"oid":"a"},{"oid":"b"}]`) }) @@ -215,7 +208,6 @@ func TestMigrationService_CancelImport(t *testing.T) { mux.HandleFunc("/repos/o/r/import", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "DELETE") - testHeader(t, r, "Accept", mediaTypeImportPreview) w.WriteHeader(http.StatusNoContent) }) From c74e92b2275cbb12471ed0fd6204dac07e130943 Mon Sep 17 00:00:00 2001 From: James <40496186+kuwas@users.noreply.github.com> Date: Wed, 15 Jan 2020 19:19:29 -0500 Subject: [PATCH 0110/1468] Remove IDPGroupList.Groups omitempty (#1379) --- github/teams.go | 2 +- github/teams_test.go | 26 ++++++++++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/github/teams.go b/github/teams.go index 2f7c6cb76e9..ff2f0bc283c 100644 --- a/github/teams.go +++ b/github/teams.go @@ -496,7 +496,7 @@ func (s *TeamsService) RemoveTeamProject(ctx context.Context, teamID int64, proj // IDPGroupList represents a list of external identity provider (IDP) groups. type IDPGroupList struct { - Groups []*IDPGroup `json:"groups,omitempty"` + Groups []*IDPGroup `json:"groups"` } // IDPGroup represents an external identity provider (IDP) group. diff --git a/github/teams_test.go b/github/teams_test.go index d65b7ffa882..5cd160ec655 100644 --- a/github/teams_test.go +++ b/github/teams_test.go @@ -732,3 +732,29 @@ func TestTeamsService_CreateOrUpdateIDPGroupConnections(t *testing.T) { t.Errorf("Teams.CreateOrUpdateIDPGroupConnections returned %+v. want %+v", groups, want) } } + +func TestTeamsService_CreateOrUpdateIDPGroupConnections_empty(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/teams/1/team-sync/group-mappings", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "PATCH") + fmt.Fprint(w, `{"groups": []}`) + }) + + input := IDPGroupList{ + Groups: []*IDPGroup{}, + } + + groups, _, err := client.Teams.CreateOrUpdateIDPGroupConnections(context.Background(), "1", input) + if err != nil { + t.Errorf("Teams.CreateOrUpdateIDPGroupConnections returned error: %v", err) + } + + want := &IDPGroupList{ + Groups: []*IDPGroup{}, + } + if !reflect.DeepEqual(groups, want) { + t.Errorf("Teams.CreateOrUpdateIDPGroupConnections returned %+v. want %+v", groups, want) + } +} From 200fc50fc0cb1cb3c92a77465565173594be0b50 Mon Sep 17 00:00:00 2001 From: vikkyomkar Date: Mon, 20 Jan 2020 00:30:12 +0530 Subject: [PATCH 0111/1468] Added support to revoke apps installation token (#1386) * added support to revoke apps installation token * updated testcase message --- github/apps_installation.go | 14 ++++++++++++++ github/apps_installation_test.go | 16 ++++++++++++++++ github/github.go | 3 +++ 3 files changed, 33 insertions(+) diff --git a/github/apps_installation.go b/github/apps_installation.go index 09d4043fe64..c2e3b4ca9eb 100644 --- a/github/apps_installation.go +++ b/github/apps_installation.go @@ -101,3 +101,17 @@ func (s *AppsService) RemoveRepository(ctx context.Context, instID, repoID int64 return s.client.Do(ctx, req, nil) } + +// RevokeInstallationToken revokes an installation token. +// +// GitHub docs: https://developer.github.com/v3/apps/installations/#revoke-an-installation-token +func (s *AppsService) RevokeInstallationToken(ctx context.Context) (*Response, error) { + u := "installation/token" + req, err := s.client.NewRequest("DELETE", u, nil) + if err != nil { + return nil, err + } + req.Header.Set("Accept", mediaTypeRevokeTokenPreview) + + return s.client.Do(ctx, req, nil) +} diff --git a/github/apps_installation_test.go b/github/apps_installation_test.go index 745e1e5dc4d..10955bf55f2 100644 --- a/github/apps_installation_test.go +++ b/github/apps_installation_test.go @@ -101,3 +101,19 @@ func TestAppsService_RemoveRepository(t *testing.T) { t.Errorf("Apps.RemoveRepository returned error: %v", err) } } + +func TestAppsService_RevokeInstallationToken(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/installation/token", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "DELETE") + testHeader(t, r, "Accept", mediaTypeRevokeTokenPreview) + w.WriteHeader(http.StatusNoContent) + }) + + _, err := client.Apps.RevokeInstallationToken(context.Background()) + if err != nil { + t.Errorf("Apps.RevokeInstallationToken returned error: %v", err) + } +} diff --git a/github/github.go b/github/github.go index b752c37b753..7013610511e 100644 --- a/github/github.go +++ b/github/github.go @@ -46,6 +46,9 @@ const ( // Media Type values to access preview APIs + // https://developer.github.com/changes/2020-01-10-revoke-installation-token/ + mediaTypeRevokeTokenPreview = "application/vnd.github.gambit-preview+json" + // https://developer.github.com/changes/2014-12-09-new-attributes-for-stars-api/ mediaTypeStarringPreview = "application/vnd.github.v3.star+json" From 75ddd505ad1c4d7c2d0bd0c5e0ef4e753907fe6a Mon Sep 17 00:00:00 2001 From: Anders Janmyr Date: Sun, 19 Jan 2020 20:02:03 +0100 Subject: [PATCH 0112/1468] Allow DownloadReleaseAsset to follow redirects (#1381) Fixes #1378. --- github/repos_releases.go | 29 ++++++++++++++++++++++++++- github/repos_releases_test.go | 36 +++++++++++++++++++++++++++++++--- test/integration/repos_test.go | 18 +++++++++++++++++ 3 files changed, 79 insertions(+), 4 deletions(-) diff --git a/github/repos_releases.go b/github/repos_releases.go index 5c0a1cea84f..0a43457263e 100644 --- a/github/repos_releases.go +++ b/github/repos_releases.go @@ -266,8 +266,13 @@ func (s *RepositoriesService) GetReleaseAsset(ctx context.Context, owner, repo s // If a redirect is returned, the redirect URL will be returned as a string instead // of the io.ReadCloser. Exactly one of rc and redirectURL will be zero. // +// followRedirectsClient can be passed to download the asset from a redirected +// location. Passing http.DefaultClient is recommended unless special circumstances +// exist, but it's possible to pass any http.Client. If nil is passed the +// redirectURL will be returned instead. +// // GitHub API docs: https://developer.github.com/v3/repos/releases/#get-a-single-release-asset -func (s *RepositoriesService) DownloadReleaseAsset(ctx context.Context, owner, repo string, id int64) (rc io.ReadCloser, redirectURL string, err error) { +func (s *RepositoriesService) DownloadReleaseAsset(ctx context.Context, owner, repo string, id int64, followRedirectsClient *http.Client) (rc io.ReadCloser, redirectURL string, err error) { u := fmt.Sprintf("repos/%s/%s/releases/assets/%d", owner, repo, id) req, err := s.client.NewRequest("GET", u, nil) @@ -293,6 +298,10 @@ func (s *RepositoriesService) DownloadReleaseAsset(ctx context.Context, owner, r if !strings.Contains(err.Error(), "disable redirect") { return nil, "", err } + if followRedirectsClient != nil { + rc, err := s.downloadReleaseAssetFromURL(ctx, followRedirectsClient, loc) + return rc, "", err + } return nil, loc, nil // Intentionally return no error with valid redirect URL. } @@ -304,6 +313,24 @@ func (s *RepositoriesService) DownloadReleaseAsset(ctx context.Context, owner, r return resp.Body, "", nil } +func (s *RepositoriesService) downloadReleaseAssetFromURL(ctx context.Context, followRedirectsClient *http.Client, url string) (rc io.ReadCloser, err error) { + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return nil, err + } + req = withContext(ctx, req) + req.Header.Set("Accept", "*/*") + resp, err := followRedirectsClient.Do(req) + if err != nil { + return nil, err + } + if err := CheckResponse(resp); err != nil { + resp.Body.Close() + return nil, err + } + return resp.Body, nil +} + // EditReleaseAsset edits a repository release asset. // // GitHub API docs: https://developer.github.com/v3/repos/releases/#edit-a-release-asset diff --git a/github/repos_releases_test.go b/github/repos_releases_test.go index 9e38d2d63e1..9ccf9ac451d 100644 --- a/github/repos_releases_test.go +++ b/github/repos_releases_test.go @@ -252,7 +252,7 @@ func TestRepositoriesService_DownloadReleaseAsset_Stream(t *testing.T) { fmt.Fprint(w, "Hello World") }) - reader, _, err := client.Repositories.DownloadReleaseAsset(context.Background(), "o", "r", 1) + reader, _, err := client.Repositories.DownloadReleaseAsset(context.Background(), "o", "r", 1, nil) if err != nil { t.Errorf("Repositories.DownloadReleaseAsset returned error: %v", err) } @@ -276,7 +276,7 @@ func TestRepositoriesService_DownloadReleaseAsset_Redirect(t *testing.T) { http.Redirect(w, r, "/yo", http.StatusFound) }) - _, got, err := client.Repositories.DownloadReleaseAsset(context.Background(), "o", "r", 1) + _, got, err := client.Repositories.DownloadReleaseAsset(context.Background(), "o", "r", 1, nil) if err != nil { t.Errorf("Repositories.DownloadReleaseAsset returned error: %v", err) } @@ -286,6 +286,36 @@ func TestRepositoriesService_DownloadReleaseAsset_Redirect(t *testing.T) { } } +func TestRepositoriesService_DownloadReleaseAsset_FollowRedirect(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/repos/o/r/releases/assets/1", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + testHeader(t, r, "Accept", defaultMediaType) + // /yo, below will be served as baseURLPath/yo + http.Redirect(w, r, baseURLPath+"/yo", http.StatusFound) + }) + mux.HandleFunc("/yo", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + testHeader(t, r, "Accept", "*/*") + w.Header().Set("Content-Type", "application/octet-stream") + w.Header().Set("Content-Disposition", "attachment; filename=hello-world.txt") + fmt.Fprint(w, "Hello World") + }) + + reader, _, err := client.Repositories.DownloadReleaseAsset(context.Background(), "o", "r", 1, http.DefaultClient) + content, err := ioutil.ReadAll(reader) + if err != nil { + t.Errorf("Repositories.DownloadReleaseAsset returned error: %v", err) + } + reader.Close() + want := []byte("Hello World") + if !bytes.Equal(want, content) { + t.Errorf("Repositories.DownloadReleaseAsset returned %+v, want %+v", content, want) + } +} + func TestRepositoriesService_DownloadReleaseAsset_APIError(t *testing.T) { client, mux, _, teardown := setup() defer teardown() @@ -297,7 +327,7 @@ func TestRepositoriesService_DownloadReleaseAsset_APIError(t *testing.T) { fmt.Fprint(w, `{"message":"Not Found","documentation_url":"https://developer.github.com/v3"}`) }) - resp, loc, err := client.Repositories.DownloadReleaseAsset(context.Background(), "o", "r", 1) + resp, loc, err := client.Repositories.DownloadReleaseAsset(context.Background(), "o", "r", 1, nil) if err == nil { t.Error("Repositories.DownloadReleaseAsset did not return an error") } diff --git a/test/integration/repos_test.go b/test/integration/repos_test.go index e4a09bfbf08..0cd2a87a572 100644 --- a/test/integration/repos_test.go +++ b/test/integration/repos_test.go @@ -9,6 +9,8 @@ package integration import ( "context" + "io" + "io/ioutil" "net/http" "reflect" "testing" @@ -179,3 +181,19 @@ func TestRepositories_List(t *testing.T) { } } } + +func TestRepositories_DownloadReleaseAsset(t *testing.T) { + if !checkAuth("TestRepositories_DownloadReleaseAsset") { + return + } + + rc, _, err := client.Repositories.DownloadReleaseAsset(context.Background(), "andersjanmyr", "goose", 484892, http.DefaultClient) + if err != nil { + t.Fatalf("Repositories.DownloadReleaseAsset(andersjanmyr, goose, 484892, true) returned error: %v", err) + } + defer func() { _ = rc.Close() }() + _, err = io.Copy(ioutil.Discard, rc) + if err != nil { + t.Fatalf("Repositories.DownloadReleaseAsset(andersjanmyr, goose, 484892, true) returned error: %v", err) + } +} From 2078be4104d1a976f43db3da2e8063b4e0bd5b5a Mon Sep 17 00:00:00 2001 From: Glenn Lewis <6598971+gmlewis@users.noreply.github.com> Date: Mon, 20 Jan 2020 13:01:00 -0500 Subject: [PATCH 0113/1468] Support cursor pagination (#1384) --- github/github.go | 33 ++++++++++++++++++++++++++++++--- github/github_test.go | 35 +++++++++++++++++++++++++++++++++++ github/teams.go | 2 +- github/teams_test.go | 4 ++-- 4 files changed, 68 insertions(+), 6 deletions(-) diff --git a/github/github.go b/github/github.go index 7013610511e..589cda53134 100644 --- a/github/github.go +++ b/github/github.go @@ -190,7 +190,7 @@ type service struct { } // ListOptions specifies the optional parameters to various List methods that -// support pagination. +// support offset pagination. type ListOptions struct { // For paginated result sets, page of results to retrieve. Page int `url:"page,omitempty"` @@ -199,6 +199,16 @@ type ListOptions struct { PerPage int `url:"per_page,omitempty"` } +// ListCursorOptions specifies the optional parameters to various List methods that +// support cursor pagination. +type ListCursorOptions struct { + // For paginated result sets, page of results to retrieve. + Page string `url:"page,omitempty"` + + // For paginated result sets, the number of results to include per page. + PerPage int `url:"per_page,omitempty"` +} + // UploadOptions specifies the parameters to methods that support uploads. type UploadOptions struct { Name string `url:"name,omitempty"` @@ -398,12 +408,27 @@ type Response struct { // results. Any or all of these may be set to the zero value for // responses that are not part of a paginated set, or for which there // are no additional pages. - + // + // These fields support what is called "offset pagination" and should + // be used with the ListOptions struct. NextPage int PrevPage int FirstPage int LastPage int + // Additionally, some APIs support "cursor pagination" instead of offset. + // This means that a token points directly to the next record which + // can lead to O(1) performance compared to O(n) performance provided + // by offset pagination. + // + // For APIs that support cursor pagination (such as + // TeamsService.ListIDPGroupsInOrganization), the following field + // will be populated to point to the next page. + // + // To use this token, set ListCursorOptions.Page to this value before + // calling the endpoint again. + NextPageToken string + // Explicitly specify the Rate type so Rate's String() receiver doesn't // propagate to Response. Rate Rate @@ -448,7 +473,9 @@ func (r *Response) populatePageValues() { for _, segment := range segments[1:] { switch strings.TrimSpace(segment) { case `rel="next"`: - r.NextPage, _ = strconv.Atoi(page) + if r.NextPage, err = strconv.Atoi(page); err != nil { + r.NextPageToken = page + } case `rel="prev"`: r.PrevPage, _ = strconv.Atoi(page) case `rel="first"`: diff --git a/github/github_test.go b/github/github_test.go index 0780d14db50..8381280b784 100644 --- a/github/github_test.go +++ b/github/github_test.go @@ -91,6 +91,7 @@ func openTestFile(name, content string) (file *os.File, dir string, err error) { } func testMethod(t *testing.T, r *http.Request, want string) { + t.Helper() if got := r.Method; got != want { t.Errorf("Request method: %v, want %v", got, want) } @@ -99,6 +100,7 @@ func testMethod(t *testing.T, r *http.Request, want string) { type values map[string]string func testFormValues(t *testing.T, r *http.Request, values values) { + t.Helper() want := url.Values{} for k, v := range values { want.Set(k, v) @@ -111,12 +113,14 @@ func testFormValues(t *testing.T, r *http.Request, values values) { } func testHeader(t *testing.T, r *http.Request, header string, want string) { + t.Helper() if got := r.Header.Get(header); got != want { t.Errorf("Header.Get(%q) returned %q, want %q", header, got, want) } } func testURLParseError(t *testing.T, err error) { + t.Helper() if err == nil { t.Errorf("Expected error to be returned") } @@ -126,6 +130,7 @@ func testURLParseError(t *testing.T, err error) { } func testBody(t *testing.T, r *http.Request, want string) { + t.Helper() b, err := ioutil.ReadAll(r.Body) if err != nil { t.Errorf("Error reading request body: %v", err) @@ -138,6 +143,7 @@ func testBody(t *testing.T, r *http.Request, want string) { // Test whether the marshaling of v produces JSON that corresponds // to the want string. func testJSONMarshal(t *testing.T, v interface{}, want string) { + t.Helper() // Unmarshal the wanted JSON, to verify its correctness, and marshal it back // to sort the keys. u := reflect.New(reflect.TypeOf(v)).Interface() @@ -414,6 +420,35 @@ func TestResponse_populatePageValues(t *testing.T) { if got, want := response.LastPage, 5; want != got { t.Errorf("response.LastPage: %v, want %v", got, want) } + if got, want := response.NextPageToken, ""; want != got { + t.Errorf("response.NextPageToken: %v, want %v", got, want) + } +} + +func TestResponse_cursorPagination(t *testing.T) { + r := http.Response{ + Header: http.Header{ + "Status": {"200 OK"}, + "Link": {`; rel="next"`}, + }, + } + + response := newResponse(&r) + if got, want := response.FirstPage, 0; got != want { + t.Errorf("response.FirstPage: %v, want %v", got, want) + } + if got, want := response.PrevPage, 0; want != got { + t.Errorf("response.PrevPage: %v, want %v", got, want) + } + if got, want := response.NextPage, 0; want != got { + t.Errorf("response.NextPage: %v, want %v", got, want) + } + if got, want := response.LastPage, 0; want != got { + t.Errorf("response.LastPage: %v, want %v", got, want) + } + if got, want := response.NextPageToken, "url-encoded-next-page-token"; want != got { + t.Errorf("response.NextPageToken: %v, want %v", got, want) + } } func TestResponse_populatePageValues_invalid(t *testing.T) { diff --git a/github/teams.go b/github/teams.go index ff2f0bc283c..03284874466 100644 --- a/github/teams.go +++ b/github/teams.go @@ -509,7 +509,7 @@ type IDPGroup struct { // ListIDPGroupsInOrganization lists IDP groups available in an organization. // // GitHub API docs: https://developer.github.com/v3/teams/team_sync/#list-idp-groups-in-an-organization -func (s *TeamsService) ListIDPGroupsInOrganization(ctx context.Context, org string, opt *ListOptions) (*IDPGroupList, *Response, error) { +func (s *TeamsService) ListIDPGroupsInOrganization(ctx context.Context, org string, opt *ListCursorOptions) (*IDPGroupList, *Response, error) { u := fmt.Sprintf("orgs/%v/team-sync/groups", org) u, err := addOptions(u, opt) if err != nil { diff --git a/github/teams_test.go b/github/teams_test.go index 5cd160ec655..ce7ece54b06 100644 --- a/github/teams_test.go +++ b/github/teams_test.go @@ -642,12 +642,12 @@ func TestTeamsService_ListIDPGroupsInOrganization(t *testing.T) { mux.HandleFunc("/orgs/o/team-sync/groups", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") testFormValues(t, r, values{ - "page": "2", + "page": "url-encoded-next-page-token", }) fmt.Fprint(w, `{"groups": [{"group_id": "1", "group_name": "n", "group_description": "d"}]}`) }) - opt := &ListOptions{Page: 2} + opt := &ListCursorOptions{Page: "url-encoded-next-page-token"} groups, _, err := client.Teams.ListIDPGroupsInOrganization(context.Background(), "o", opt) if err != nil { t.Errorf("Teams.ListIDPGroupsInOrganization returned error: %v", err) From e7361de8ed67054f389e38e2af044c534037d849 Mon Sep 17 00:00:00 2001 From: Ryo Nakao Date: Wed, 22 Jan 2020 23:04:11 +0900 Subject: [PATCH 0114/1468] Support new fields in PullRequestEvent for "synchronize" action (#1389) Fixes #1243. --- github/event_types.go | 4 ++++ github/github-accessors.go | 16 ++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/github/event_types.go b/github/event_types.go index df12821c430..4211f54bf1a 100644 --- a/github/event_types.go +++ b/github/event_types.go @@ -599,6 +599,10 @@ type PullRequestEvent struct { // The following field is only present when the webhook is triggered on // a repository belonging to an organization. Organization *Organization `json:"organization,omitempty"` + + // The following fields are only populated when the Action is "synchronize". + Before *string `json:"before,omitempty"` + After *string `json:"after,omitempty"` } // PullRequestReviewEvent is triggered when a review is submitted on a pull diff --git a/github/github-accessors.go b/github/github-accessors.go index 4ff4a3f5a46..d069076dfc9 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -8492,6 +8492,14 @@ func (p *PullRequestEvent) GetAction() string { return *p.Action } +// GetAfter returns the After field if it's non-nil, zero value otherwise. +func (p *PullRequestEvent) GetAfter() string { + if p == nil || p.After == nil { + return "" + } + return *p.After +} + // GetAssignee returns the Assignee field. func (p *PullRequestEvent) GetAssignee() *User { if p == nil { @@ -8500,6 +8508,14 @@ func (p *PullRequestEvent) GetAssignee() *User { return p.Assignee } +// GetBefore returns the Before field if it's non-nil, zero value otherwise. +func (p *PullRequestEvent) GetBefore() string { + if p == nil || p.Before == nil { + return "" + } + return *p.Before +} + // GetChanges returns the Changes field. func (p *PullRequestEvent) GetChanges() *EditChange { if p == nil { From 8f818bcdd1e6387812c16c315ba1fb9b64a3acf7 Mon Sep 17 00:00:00 2001 From: Thibault Jamet Date: Fri, 24 Jan 2020 14:04:46 +0100 Subject: [PATCH 0115/1468] Add new branch protection values (#1393) Fixes #1345. Closes #1354. --- github/github-accessors.go | 48 ++++++++++++++++++++++++++++++++++++++ github/repos.go | 24 +++++++++++++++++++ 2 files changed, 72 insertions(+) diff --git a/github/github-accessors.go b/github/github-accessors.go index d069076dfc9..a0a64ef323d 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -7796,6 +7796,22 @@ func (p *ProjectPermissionLevel) GetUser() *User { return p.User } +// GetAllowDeletions returns the AllowDeletions field. +func (p *Protection) GetAllowDeletions() *AllowDeletions { + if p == nil { + return nil + } + return p.AllowDeletions +} + +// GetAllowForcePushes returns the AllowForcePushes field. +func (p *Protection) GetAllowForcePushes() *AllowForcePushes { + if p == nil { + return nil + } + return p.AllowForcePushes +} + // GetEnforceAdmins returns the EnforceAdmins field. func (p *Protection) GetEnforceAdmins() *AdminEnforcement { if p == nil { @@ -7820,6 +7836,14 @@ func (p *Protection) GetRequiredStatusChecks() *RequiredStatusChecks { return p.RequiredStatusChecks } +// GetRequireLinearHistory returns the RequireLinearHistory field. +func (p *Protection) GetRequireLinearHistory() *RequireLinearHistory { + if p == nil { + return nil + } + return p.RequireLinearHistory +} + // GetRestrictions returns the Restrictions field. func (p *Protection) GetRestrictions() *BranchRestrictions { if p == nil { @@ -7828,6 +7852,22 @@ func (p *Protection) GetRestrictions() *BranchRestrictions { return p.Restrictions } +// GetAllowDeletions returns the AllowDeletions field if it's non-nil, zero value otherwise. +func (p *ProtectionRequest) GetAllowDeletions() bool { + if p == nil || p.AllowDeletions == nil { + return false + } + return *p.AllowDeletions +} + +// GetAllowForcePushes returns the AllowForcePushes field if it's non-nil, zero value otherwise. +func (p *ProtectionRequest) GetAllowForcePushes() bool { + if p == nil || p.AllowForcePushes == nil { + return false + } + return *p.AllowForcePushes +} + // GetRequiredPullRequestReviews returns the RequiredPullRequestReviews field. func (p *ProtectionRequest) GetRequiredPullRequestReviews() *PullRequestReviewsEnforcementRequest { if p == nil { @@ -7844,6 +7884,14 @@ func (p *ProtectionRequest) GetRequiredStatusChecks() *RequiredStatusChecks { return p.RequiredStatusChecks } +// GetRequireLinearHistory returns the RequireLinearHistory field if it's non-nil, zero value otherwise. +func (p *ProtectionRequest) GetRequireLinearHistory() bool { + if p == nil || p.RequireLinearHistory == nil { + return false + } + return *p.RequireLinearHistory +} + // GetRestrictions returns the Restrictions field. func (p *ProtectionRequest) GetRestrictions() *BranchRestrictionsRequest { if p == nil { diff --git a/github/repos.go b/github/repos.go index c695d8c0bb5..153f8919f8c 100644 --- a/github/repos.go +++ b/github/repos.go @@ -727,6 +727,9 @@ type Protection struct { RequiredPullRequestReviews *PullRequestReviewsEnforcement `json:"required_pull_request_reviews"` EnforceAdmins *AdminEnforcement `json:"enforce_admins"` Restrictions *BranchRestrictions `json:"restrictions"` + RequireLinearHistory *RequireLinearHistory `json:"required_linear_history"` + AllowForcePushes *AllowForcePushes `json:"allow_force_pushes"` + AllowDeletions *AllowDeletions `json:"allow_deletions"` } // ProtectionRequest represents a request to create/edit a branch's protection. @@ -735,6 +738,12 @@ type ProtectionRequest struct { RequiredPullRequestReviews *PullRequestReviewsEnforcementRequest `json:"required_pull_request_reviews"` EnforceAdmins bool `json:"enforce_admins"` Restrictions *BranchRestrictionsRequest `json:"restrictions"` + // Enforces a linear commit Git history, which prevents anyone from pushing merge commits to a branch. + RequireLinearHistory *bool `json:"required_linear_history,omitempty"` + // Permits force pushes to the protected branch by anyone with write access to the repository. + AllowForcePushes *bool `json:"allow_force_pushes,omitempty"` + // Allows deletion of the protected branch by anyone with write access to the repository. + AllowDeletions *bool `json:"allow_deletions,omitempty"` } // RequiredStatusChecks represents the protection status of a individual branch. @@ -797,6 +806,21 @@ type PullRequestReviewsEnforcementUpdate struct { RequiredApprovingReviewCount int `json:"required_approving_review_count"` } +// RequireLinearHistory represents the configuration to enfore branches with no merge commit. +type RequireLinearHistory struct { + Enabled bool `json:"enabled"` +} + +// AllowDeletions represents the configuration to accept deletion of protected branches. +type AllowDeletions struct { + Enabled bool `json:"enabled"` +} + +// AllowForcePushes represents the configuration to accept forced pushes on protected branches. +type AllowForcePushes struct { + Enabled bool `json:"enabled"` +} + // AdminEnforcement represents the configuration to enforce required status checks for repository administrators. type AdminEnforcement struct { URL *string `json:"url,omitempty"` From d14f9fb01a85ee4165adbaedbbecb2ca1648d2cc Mon Sep 17 00:00:00 2001 From: Ravi Shekhar Jethani Date: Sat, 25 Jan 2020 19:18:07 +0100 Subject: [PATCH 0116/1468] Replace new() (#1395) --- github/github.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/github/github.go b/github/github.go index 589cda53134..52c5eb0ed35 100644 --- a/github/github.go +++ b/github/github.go @@ -347,7 +347,7 @@ func (c *Client) NewRequest(method, urlStr string, body interface{}) (*http.Requ var buf io.ReadWriter if body != nil { - buf = new(bytes.Buffer) + buf = &bytes.Buffer{} enc := json.NewEncoder(buf) enc.SetEscapeHTML(false) err := enc.Encode(body) From 8e32804546126b905d80e37190ea1ec080f3849b Mon Sep 17 00:00:00 2001 From: vikkyomkar Date: Tue, 28 Jan 2020 00:28:19 +0530 Subject: [PATCH 0117/1468] Remove everest custom preview header (#1391) Fixes #1390. --- github/github.go | 3 --- github/repos.go | 3 --- github/repos_test.go | 1 - 3 files changed, 7 deletions(-) diff --git a/github/github.go b/github/github.go index 52c5eb0ed35..794ee9c168c 100644 --- a/github/github.go +++ b/github/github.go @@ -135,9 +135,6 @@ const ( // https://developer.github.com/changes/2019-10-03-multi-line-comments/ mediaTypeMultiLineCommentsPreview = "application/vnd.github.comfort-fade-preview+json" - - // https://developer.github.com/v3/repos/#create-a-repository-dispatch-event - mediaTypeRepositoryDispatchPreview = "application/vnd.github.everest-preview+json" ) // A Client manages communication with the GitHub API. diff --git a/github/repos.go b/github/repos.go index 153f8919f8c..8c456130036 100644 --- a/github/repos.go +++ b/github/repos.go @@ -1473,9 +1473,6 @@ func (s *RepositoriesService) Dispatch(ctx context.Context, owner, repo string, return nil, nil, err } - // TODO: remove custom Accept header when this API fully launches. - req.Header.Set("Accept", mediaTypeRepositoryDispatchPreview) - r := new(Repository) resp, err := s.client.Do(ctx, req, r) if err != nil { diff --git a/github/repos_test.go b/github/repos_test.go index 1e48b7e2534..d1c60cb010b 100644 --- a/github/repos_test.go +++ b/github/repos_test.go @@ -1808,7 +1808,6 @@ func TestRepositoriesService_Dispatch(t *testing.T) { json.NewDecoder(r.Body).Decode(&v) testMethod(t, r, "POST") - testHeader(t, r, "Accept", mediaTypeRepositoryDispatchPreview) if !reflect.DeepEqual(v, input) { t.Errorf("Request body = %+v, want %+v", v, input) } From dadb49c5967ee0082d4ef3e36f4163b95232de11 Mon Sep 17 00:00:00 2001 From: Will Norris Date: Sun, 26 Jan 2020 22:54:18 +0000 Subject: [PATCH 0118/1468] update github actions config - combine windows and linux configs into a single matrix, now that actions/cache handles file paths properly - update to latest actions/checkout and codecov actions --- .github/workflows/tests.yml | 42 ++++++++++++------------------------- 1 file changed, 13 insertions(+), 29 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index d89f367e715..928ca47aa7e 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -4,66 +4,50 @@ env: GO111MODULE: on jobs: - linux: + test: strategy: matrix: go-version: [1.x, 1.12.x] - runs-on: ubuntu-latest + platform: [ubuntu-latest, windows-latest] + runs-on: ${{ matrix.platform }} steps: - uses: actions/setup-go@v1 with: go-version: ${{ matrix.go-version }} - - uses: actions/checkout@v1 + - uses: actions/checkout@v2 - name: Cache go modules - uses: actions/cache@preview + uses: actions/cache@v1 with: path: ~/go/pkg/mod key: ${{ runner.os }}-go-${{ hashFiles('go.sum') }} restore-keys: ${{ runner.os }}-go- - name: Run go fmt + if: runner.os != 'Windows' run: diff -u <(echo -n) <(gofmt -d -s .) - name: Ensure go generate produces a zero diff + shell: bash run: go generate -x ./... && git diff --exit-code; code=$?; git checkout -- .; (exit $code) - name: Run go vet run: go vet ./... - name: Run go test - run: go test -v -race -coverprofile=coverage.txt -covermode=atomic ./... + run: go test -v -race -coverprofile coverage.txt -covermode atomic ./... - name: Ensure integration tests build # don't actually run tests since they hit live GitHub API run: go test -v -tags=integration -run=^$ ./test/integration - name: Run scrape tests - run: cd scrape && go test ./... + run: | + cd scrape + go test ./... - name: Upload coverage to Codecov - env: - CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} - run: bash <(curl -s https://codecov.io/bash) - - # On Windows, just run the local tests. Don't bother with checking gofmt, go - # vet, or uploading results to Codecov - windows: - strategy: - matrix: - go-version: [1.x, 1.12.x] - runs-on: windows-latest - - steps: - - uses: actions/setup-go@v1 + uses: codecov/codecov-action@v1 with: - go-version: ${{ matrix.go-version }} - - uses: actions/checkout@v1 - - name: Cache go modules - uses: actions/cache@preview - with: - path: ~/go/pkg/mod - key: ${{ runner.os }}-go-${{ hashFiles('go.sum') }} - restore-keys: ${{ runner.os }}-go- - - run: go test ./... + token: ${{ secrets.CODECOV_TOKEN }} From 7077c41dcb08732b471e6e1dfd2694eee9a54cc6 Mon Sep 17 00:00:00 2001 From: Will Norris Date: Sun, 26 Jan 2020 18:47:07 +0000 Subject: [PATCH 0119/1468] use pkg.go.dev for documentation pkg.go.dev understands modules, whereas godoc.org does not. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8a496fb058b..326cfe38190 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # go-github # -[![GoDoc](https://godoc.org/github.com/google/go-github/github?status.svg)](https://godoc.org/github.com/google/go-github/github) +[![GoDoc](https://img.shields.io/static/v1?label=godoc&message=reference&color=blue)](https://pkg.go.dev/github.com/google/go-github/v29/github) [![Test Status](https://github.com/google/go-github/workflows/tests/badge.svg)](https://github.com/google/go-github/actions?query=workflow%3Atests) [![Test Coverage](https://codecov.io/gh/google/go-github/branch/master/graph/badge.svg)](https://codecov.io/gh/google/go-github) [![Discuss at go-github@googlegroups.com](https://img.shields.io/badge/discuss-go--github%40googlegroups.com-blue.svg)](https://groups.google.com/group/go-github) From 8025ca22a26f4b4e633945d73d61d0adaaf8a716 Mon Sep 17 00:00:00 2001 From: Stefan Sedich Date: Mon, 27 Jan 2020 13:45:46 -0800 Subject: [PATCH 0120/1468] Add delete_branch_on_merge support for repos (#1388) Fixes #1245. --- github/github-accessors.go | 8 ++ github/github-stringify_test.go | 177 ++++++++++++++++---------------- github/repos.go | 125 +++++++++++----------- 3 files changed, 161 insertions(+), 149 deletions(-) diff --git a/github/github-accessors.go b/github/github-accessors.go index a0a64ef323d..2c5f8bf12a9 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -9980,6 +9980,14 @@ func (r *Repository) GetDefaultBranch() string { return *r.DefaultBranch } +// GetDeleteBranchOnMerge returns the DeleteBranchOnMerge field if it's non-nil, zero value otherwise. +func (r *Repository) GetDeleteBranchOnMerge() bool { + if r == nil || r.DeleteBranchOnMerge == nil { + return false + } + return *r.DeleteBranchOnMerge +} + // GetDeploymentsURL returns the DeploymentsURL field if it's non-nil, zero value otherwise. func (r *Repository) GetDeploymentsURL() string { if r == nil || r.DeploymentsURL == nil { diff --git a/github/github-stringify_test.go b/github/github-stringify_test.go index 97a13ee2a55..b156cc1db92 100644 --- a/github/github-stringify_test.go +++ b/github/github-stringify_test.go @@ -1212,94 +1212,95 @@ func TestRepoStatus_String(t *testing.T) { func TestRepository_String(t *testing.T) { v := Repository{ - ID: Int64(0), - NodeID: String(""), - Owner: &User{}, - Name: String(""), - FullName: String(""), - Description: String(""), - Homepage: String(""), - CodeOfConduct: &CodeOfConduct{}, - DefaultBranch: String(""), - MasterBranch: String(""), - CreatedAt: &Timestamp{}, - PushedAt: &Timestamp{}, - UpdatedAt: &Timestamp{}, - HTMLURL: String(""), - CloneURL: String(""), - GitURL: String(""), - MirrorURL: String(""), - SSHURL: String(""), - SVNURL: String(""), - Language: String(""), - Fork: Bool(false), - ForksCount: Int(0), - NetworkCount: Int(0), - OpenIssuesCount: Int(0), - StargazersCount: Int(0), - SubscribersCount: Int(0), - WatchersCount: Int(0), - Size: Int(0), - AutoInit: Bool(false), - Parent: &Repository{}, - Source: &Repository{}, - TemplateRepository: &Repository{}, - Organization: &Organization{}, - AllowRebaseMerge: Bool(false), - AllowSquashMerge: Bool(false), - AllowMergeCommit: Bool(false), - Archived: Bool(false), - Disabled: Bool(false), - License: &License{}, - Private: Bool(false), - HasIssues: Bool(false), - HasWiki: Bool(false), - HasPages: Bool(false), - HasProjects: Bool(false), - HasDownloads: Bool(false), - IsTemplate: Bool(false), - LicenseTemplate: String(""), - GitignoreTemplate: String(""), - TeamID: Int64(0), - URL: String(""), - ArchiveURL: String(""), - AssigneesURL: String(""), - BlobsURL: String(""), - BranchesURL: String(""), - CollaboratorsURL: String(""), - CommentsURL: String(""), - CommitsURL: String(""), - CompareURL: String(""), - ContentsURL: String(""), - ContributorsURL: String(""), - DeploymentsURL: String(""), - DownloadsURL: String(""), - EventsURL: String(""), - ForksURL: String(""), - GitCommitsURL: String(""), - GitRefsURL: String(""), - GitTagsURL: String(""), - HooksURL: String(""), - IssueCommentURL: String(""), - IssueEventsURL: String(""), - IssuesURL: String(""), - KeysURL: String(""), - LabelsURL: String(""), - LanguagesURL: String(""), - MergesURL: String(""), - MilestonesURL: String(""), - NotificationsURL: String(""), - PullsURL: String(""), - ReleasesURL: String(""), - StargazersURL: String(""), - StatusesURL: String(""), - SubscribersURL: String(""), - SubscriptionURL: String(""), - TagsURL: String(""), - TreesURL: String(""), - TeamsURL: String(""), - } - want := `github.Repository{ID:0, NodeID:"", Owner:github.User{}, Name:"", FullName:"", Description:"", Homepage:"", CodeOfConduct:github.CodeOfConduct{}, DefaultBranch:"", MasterBranch:"", CreatedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, PushedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, UpdatedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, HTMLURL:"", CloneURL:"", GitURL:"", MirrorURL:"", SSHURL:"", SVNURL:"", Language:"", Fork:false, ForksCount:0, NetworkCount:0, OpenIssuesCount:0, StargazersCount:0, SubscribersCount:0, WatchersCount:0, Size:0, AutoInit:false, Parent:github.Repository{}, Source:github.Repository{}, TemplateRepository:github.Repository{}, Organization:github.Organization{}, AllowRebaseMerge:false, AllowSquashMerge:false, AllowMergeCommit:false, Archived:false, Disabled:false, License:github.License{}, Private:false, HasIssues:false, HasWiki:false, HasPages:false, HasProjects:false, HasDownloads:false, IsTemplate:false, LicenseTemplate:"", GitignoreTemplate:"", TeamID:0, URL:"", ArchiveURL:"", AssigneesURL:"", BlobsURL:"", BranchesURL:"", CollaboratorsURL:"", CommentsURL:"", CommitsURL:"", CompareURL:"", ContentsURL:"", ContributorsURL:"", DeploymentsURL:"", DownloadsURL:"", EventsURL:"", ForksURL:"", GitCommitsURL:"", GitRefsURL:"", GitTagsURL:"", HooksURL:"", IssueCommentURL:"", IssueEventsURL:"", IssuesURL:"", KeysURL:"", LabelsURL:"", LanguagesURL:"", MergesURL:"", MilestonesURL:"", NotificationsURL:"", PullsURL:"", ReleasesURL:"", StargazersURL:"", StatusesURL:"", SubscribersURL:"", SubscriptionURL:"", TagsURL:"", TreesURL:"", TeamsURL:""}` + ID: Int64(0), + NodeID: String(""), + Owner: &User{}, + Name: String(""), + FullName: String(""), + Description: String(""), + Homepage: String(""), + CodeOfConduct: &CodeOfConduct{}, + DefaultBranch: String(""), + MasterBranch: String(""), + CreatedAt: &Timestamp{}, + PushedAt: &Timestamp{}, + UpdatedAt: &Timestamp{}, + HTMLURL: String(""), + CloneURL: String(""), + GitURL: String(""), + MirrorURL: String(""), + SSHURL: String(""), + SVNURL: String(""), + Language: String(""), + Fork: Bool(false), + ForksCount: Int(0), + NetworkCount: Int(0), + OpenIssuesCount: Int(0), + StargazersCount: Int(0), + SubscribersCount: Int(0), + WatchersCount: Int(0), + Size: Int(0), + AutoInit: Bool(false), + Parent: &Repository{}, + Source: &Repository{}, + TemplateRepository: &Repository{}, + Organization: &Organization{}, + AllowRebaseMerge: Bool(false), + AllowSquashMerge: Bool(false), + AllowMergeCommit: Bool(false), + DeleteBranchOnMerge: Bool(false), + Archived: Bool(false), + Disabled: Bool(false), + License: &License{}, + Private: Bool(false), + HasIssues: Bool(false), + HasWiki: Bool(false), + HasPages: Bool(false), + HasProjects: Bool(false), + HasDownloads: Bool(false), + IsTemplate: Bool(false), + LicenseTemplate: String(""), + GitignoreTemplate: String(""), + TeamID: Int64(0), + URL: String(""), + ArchiveURL: String(""), + AssigneesURL: String(""), + BlobsURL: String(""), + BranchesURL: String(""), + CollaboratorsURL: String(""), + CommentsURL: String(""), + CommitsURL: String(""), + CompareURL: String(""), + ContentsURL: String(""), + ContributorsURL: String(""), + DeploymentsURL: String(""), + DownloadsURL: String(""), + EventsURL: String(""), + ForksURL: String(""), + GitCommitsURL: String(""), + GitRefsURL: String(""), + GitTagsURL: String(""), + HooksURL: String(""), + IssueCommentURL: String(""), + IssueEventsURL: String(""), + IssuesURL: String(""), + KeysURL: String(""), + LabelsURL: String(""), + LanguagesURL: String(""), + MergesURL: String(""), + MilestonesURL: String(""), + NotificationsURL: String(""), + PullsURL: String(""), + ReleasesURL: String(""), + StargazersURL: String(""), + StatusesURL: String(""), + SubscribersURL: String(""), + SubscriptionURL: String(""), + TagsURL: String(""), + TreesURL: String(""), + TeamsURL: String(""), + } + want := `github.Repository{ID:0, NodeID:"", Owner:github.User{}, Name:"", FullName:"", Description:"", Homepage:"", CodeOfConduct:github.CodeOfConduct{}, DefaultBranch:"", MasterBranch:"", CreatedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, PushedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, UpdatedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, HTMLURL:"", CloneURL:"", GitURL:"", MirrorURL:"", SSHURL:"", SVNURL:"", Language:"", Fork:false, ForksCount:0, NetworkCount:0, OpenIssuesCount:0, StargazersCount:0, SubscribersCount:0, WatchersCount:0, Size:0, AutoInit:false, Parent:github.Repository{}, Source:github.Repository{}, TemplateRepository:github.Repository{}, Organization:github.Organization{}, AllowRebaseMerge:false, AllowSquashMerge:false, AllowMergeCommit:false, DeleteBranchOnMerge:false, Archived:false, Disabled:false, License:github.License{}, Private:false, HasIssues:false, HasWiki:false, HasPages:false, HasProjects:false, HasDownloads:false, IsTemplate:false, LicenseTemplate:"", GitignoreTemplate:"", TeamID:0, URL:"", ArchiveURL:"", AssigneesURL:"", BlobsURL:"", BranchesURL:"", CollaboratorsURL:"", CommentsURL:"", CommitsURL:"", CompareURL:"", ContentsURL:"", ContributorsURL:"", DeploymentsURL:"", DownloadsURL:"", EventsURL:"", ForksURL:"", GitCommitsURL:"", GitRefsURL:"", GitTagsURL:"", HooksURL:"", IssueCommentURL:"", IssueEventsURL:"", IssuesURL:"", KeysURL:"", LabelsURL:"", LanguagesURL:"", MergesURL:"", MilestonesURL:"", NotificationsURL:"", PullsURL:"", ReleasesURL:"", StargazersURL:"", StatusesURL:"", SubscribersURL:"", SubscriptionURL:"", TagsURL:"", TreesURL:"", TeamsURL:""}` if got := v.String(); got != want { t.Errorf("Repository.String = %v, want %v", got, want) } diff --git a/github/repos.go b/github/repos.go index 8c456130036..8f9409e6b6c 100644 --- a/github/repos.go +++ b/github/repos.go @@ -20,46 +20,47 @@ type RepositoriesService service // Repository represents a GitHub repository. type Repository struct { - ID *int64 `json:"id,omitempty"` - NodeID *string `json:"node_id,omitempty"` - Owner *User `json:"owner,omitempty"` - Name *string `json:"name,omitempty"` - FullName *string `json:"full_name,omitempty"` - Description *string `json:"description,omitempty"` - Homepage *string `json:"homepage,omitempty"` - CodeOfConduct *CodeOfConduct `json:"code_of_conduct,omitempty"` - DefaultBranch *string `json:"default_branch,omitempty"` - MasterBranch *string `json:"master_branch,omitempty"` - CreatedAt *Timestamp `json:"created_at,omitempty"` - PushedAt *Timestamp `json:"pushed_at,omitempty"` - UpdatedAt *Timestamp `json:"updated_at,omitempty"` - HTMLURL *string `json:"html_url,omitempty"` - CloneURL *string `json:"clone_url,omitempty"` - GitURL *string `json:"git_url,omitempty"` - MirrorURL *string `json:"mirror_url,omitempty"` - SSHURL *string `json:"ssh_url,omitempty"` - SVNURL *string `json:"svn_url,omitempty"` - Language *string `json:"language,omitempty"` - Fork *bool `json:"fork,omitempty"` - ForksCount *int `json:"forks_count,omitempty"` - NetworkCount *int `json:"network_count,omitempty"` - OpenIssuesCount *int `json:"open_issues_count,omitempty"` - StargazersCount *int `json:"stargazers_count,omitempty"` - SubscribersCount *int `json:"subscribers_count,omitempty"` - WatchersCount *int `json:"watchers_count,omitempty"` - Size *int `json:"size,omitempty"` - AutoInit *bool `json:"auto_init,omitempty"` - Parent *Repository `json:"parent,omitempty"` - Source *Repository `json:"source,omitempty"` - TemplateRepository *Repository `json:"template_repository,omitempty"` - Organization *Organization `json:"organization,omitempty"` - Permissions *map[string]bool `json:"permissions,omitempty"` - AllowRebaseMerge *bool `json:"allow_rebase_merge,omitempty"` - AllowSquashMerge *bool `json:"allow_squash_merge,omitempty"` - AllowMergeCommit *bool `json:"allow_merge_commit,omitempty"` - Topics []string `json:"topics,omitempty"` - Archived *bool `json:"archived,omitempty"` - Disabled *bool `json:"disabled,omitempty"` + ID *int64 `json:"id,omitempty"` + NodeID *string `json:"node_id,omitempty"` + Owner *User `json:"owner,omitempty"` + Name *string `json:"name,omitempty"` + FullName *string `json:"full_name,omitempty"` + Description *string `json:"description,omitempty"` + Homepage *string `json:"homepage,omitempty"` + CodeOfConduct *CodeOfConduct `json:"code_of_conduct,omitempty"` + DefaultBranch *string `json:"default_branch,omitempty"` + MasterBranch *string `json:"master_branch,omitempty"` + CreatedAt *Timestamp `json:"created_at,omitempty"` + PushedAt *Timestamp `json:"pushed_at,omitempty"` + UpdatedAt *Timestamp `json:"updated_at,omitempty"` + HTMLURL *string `json:"html_url,omitempty"` + CloneURL *string `json:"clone_url,omitempty"` + GitURL *string `json:"git_url,omitempty"` + MirrorURL *string `json:"mirror_url,omitempty"` + SSHURL *string `json:"ssh_url,omitempty"` + SVNURL *string `json:"svn_url,omitempty"` + Language *string `json:"language,omitempty"` + Fork *bool `json:"fork,omitempty"` + ForksCount *int `json:"forks_count,omitempty"` + NetworkCount *int `json:"network_count,omitempty"` + OpenIssuesCount *int `json:"open_issues_count,omitempty"` + StargazersCount *int `json:"stargazers_count,omitempty"` + SubscribersCount *int `json:"subscribers_count,omitempty"` + WatchersCount *int `json:"watchers_count,omitempty"` + Size *int `json:"size,omitempty"` + AutoInit *bool `json:"auto_init,omitempty"` + Parent *Repository `json:"parent,omitempty"` + Source *Repository `json:"source,omitempty"` + TemplateRepository *Repository `json:"template_repository,omitempty"` + Organization *Organization `json:"organization,omitempty"` + Permissions *map[string]bool `json:"permissions,omitempty"` + AllowRebaseMerge *bool `json:"allow_rebase_merge,omitempty"` + AllowSquashMerge *bool `json:"allow_squash_merge,omitempty"` + AllowMergeCommit *bool `json:"allow_merge_commit,omitempty"` + DeleteBranchOnMerge *bool `json:"delete_branch_on_merge,omitempty"` + Topics []string `json:"topics,omitempty"` + Archived *bool `json:"archived,omitempty"` + Disabled *bool `json:"disabled,omitempty"` // Only provided when using RepositoriesService.Get while in preview License *License `json:"license,omitempty"` @@ -303,12 +304,13 @@ type createRepoRequest struct { // Creating an organization repository. Required for non-owners. TeamID *int64 `json:"team_id,omitempty"` - AutoInit *bool `json:"auto_init,omitempty"` - GitignoreTemplate *string `json:"gitignore_template,omitempty"` - LicenseTemplate *string `json:"license_template,omitempty"` - AllowSquashMerge *bool `json:"allow_squash_merge,omitempty"` - AllowMergeCommit *bool `json:"allow_merge_commit,omitempty"` - AllowRebaseMerge *bool `json:"allow_rebase_merge,omitempty"` + AutoInit *bool `json:"auto_init,omitempty"` + GitignoreTemplate *string `json:"gitignore_template,omitempty"` + LicenseTemplate *string `json:"license_template,omitempty"` + AllowSquashMerge *bool `json:"allow_squash_merge,omitempty"` + AllowMergeCommit *bool `json:"allow_merge_commit,omitempty"` + AllowRebaseMerge *bool `json:"allow_rebase_merge,omitempty"` + DeleteBranchOnMerge *bool `json:"delete_branch_on_merge,omitempty"` } // Create a new repository. If an organization is specified, the new @@ -328,21 +330,22 @@ func (s *RepositoriesService) Create(ctx context.Context, org string, repo *Repo } repoReq := &createRepoRequest{ - Name: repo.Name, - Description: repo.Description, - Homepage: repo.Homepage, - Private: repo.Private, - HasIssues: repo.HasIssues, - HasProjects: repo.HasProjects, - HasWiki: repo.HasWiki, - IsTemplate: repo.IsTemplate, - TeamID: repo.TeamID, - AutoInit: repo.AutoInit, - GitignoreTemplate: repo.GitignoreTemplate, - LicenseTemplate: repo.LicenseTemplate, - AllowSquashMerge: repo.AllowSquashMerge, - AllowMergeCommit: repo.AllowMergeCommit, - AllowRebaseMerge: repo.AllowRebaseMerge, + Name: repo.Name, + Description: repo.Description, + Homepage: repo.Homepage, + Private: repo.Private, + HasIssues: repo.HasIssues, + HasProjects: repo.HasProjects, + HasWiki: repo.HasWiki, + IsTemplate: repo.IsTemplate, + TeamID: repo.TeamID, + AutoInit: repo.AutoInit, + GitignoreTemplate: repo.GitignoreTemplate, + LicenseTemplate: repo.LicenseTemplate, + AllowSquashMerge: repo.AllowSquashMerge, + AllowMergeCommit: repo.AllowMergeCommit, + AllowRebaseMerge: repo.AllowRebaseMerge, + DeleteBranchOnMerge: repo.DeleteBranchOnMerge, } req, err := s.client.NewRequest("POST", u, repoReq) From 503890120f2cd566c403c8a73ea051bc3acd1a57 Mon Sep 17 00:00:00 2001 From: "lynn [they]" Date: Wed, 29 Jan 2020 18:44:35 -0800 Subject: [PATCH 0121/1468] Add archived and disabled to PushEventRepository (#1403) Fixes #1380. --- github/event_types.go | 2 ++ github/github-accessors.go | 16 ++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/github/event_types.go b/github/event_types.go index 4211f54bf1a..4f537c8db90 100644 --- a/github/event_types.go +++ b/github/event_types.go @@ -723,6 +723,8 @@ type PushEventRepository struct { HasWiki *bool `json:"has_wiki,omitempty"` HasPages *bool `json:"has_pages,omitempty"` ForksCount *int `json:"forks_count,omitempty"` + Archived *bool `json:"archived,omitempty"` + Disabled *bool `json:"disabled,omitempty"` OpenIssuesCount *int `json:"open_issues_count,omitempty"` DefaultBranch *string `json:"default_branch,omitempty"` MasterBranch *string `json:"master_branch,omitempty"` diff --git a/github/github-accessors.go b/github/github-accessors.go index 2c5f8bf12a9..f300b117ab5 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -9236,6 +9236,14 @@ func (p *PushEventRepoOwner) GetName() string { return *p.Name } +// GetArchived returns the Archived field if it's non-nil, zero value otherwise. +func (p *PushEventRepository) GetArchived() bool { + if p == nil || p.Archived == nil { + return false + } + return *p.Archived +} + // GetArchiveURL returns the ArchiveURL field if it's non-nil, zero value otherwise. func (p *PushEventRepository) GetArchiveURL() string { if p == nil || p.ArchiveURL == nil { @@ -9276,6 +9284,14 @@ func (p *PushEventRepository) GetDescription() string { return *p.Description } +// GetDisabled returns the Disabled field if it's non-nil, zero value otherwise. +func (p *PushEventRepository) GetDisabled() bool { + if p == nil || p.Disabled == nil { + return false + } + return *p.Disabled +} + // GetFork returns the Fork field if it's non-nil, zero value otherwise. func (p *PushEventRepository) GetFork() bool { if p == nil || p.Fork == nil { From 60d309e0e8dc333c40fa53d3d669f7f0e424095c Mon Sep 17 00:00:00 2001 From: Carl Johnson Date: Fri, 31 Jan 2020 12:41:57 -0500 Subject: [PATCH 0122/1468] RepositoryContent.GetContent(): Check nil before decoding (#1405) --- github/repos_contents.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/github/repos_contents.go b/github/repos_contents.go index eed0420ab84..66b556d21b8 100644 --- a/github/repos_contents.go +++ b/github/repos_contents.go @@ -12,6 +12,7 @@ import ( "context" "encoding/base64" "encoding/json" + "errors" "fmt" "io" "net/http" @@ -76,6 +77,9 @@ func (r *RepositoryContent) GetContent() (string, error) { switch encoding { case "base64": + if r.Content == nil { + return "", errors.New("malformed response: base64 encoding of null content") + } c, err := base64.StdEncoding.DecodeString(*r.Content) return string(c), err case "": From 9cc7246617ae88078681ce7570893acb279c49fc Mon Sep 17 00:00:00 2001 From: Patrick DeVivo Date: Sun, 2 Feb 2020 10:43:26 -0500 Subject: [PATCH 0123/1468] Add TODOs badge to the README (#1407) Fixes: #1406. --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 326cfe38190..2d134ce0c2e 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,7 @@ [![Test Coverage](https://codecov.io/gh/google/go-github/branch/master/graph/badge.svg)](https://codecov.io/gh/google/go-github) [![Discuss at go-github@googlegroups.com](https://img.shields.io/badge/discuss-go--github%40googlegroups.com-blue.svg)](https://groups.google.com/group/go-github) [![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/796/badge)](https://bestpractices.coreinfrastructure.org/projects/796) +[![TODOs](https://img.shields.io/endpoint?url=https://todos.tickgit.com/badge?repo=github.com/google/go-github)](https://todos.tickgit.com/browse?repo=github.com/google/go-github) go-github is a Go client library for accessing the [GitHub API v3][]. From e5ba070b6d1580c2daf8e0747ebace3252e6be4e Mon Sep 17 00:00:00 2001 From: Glenn Lewis <6598971+gmlewis@users.noreply.github.com> Date: Mon, 3 Feb 2020 21:15:07 -0500 Subject: [PATCH 0124/1468] Revert "Add TODOs badge to the README (#1407)" (#1410) This reverts commit 9cc7246617ae88078681ce7570893acb279c49fc. --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 2d134ce0c2e..326cfe38190 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,6 @@ [![Test Coverage](https://codecov.io/gh/google/go-github/branch/master/graph/badge.svg)](https://codecov.io/gh/google/go-github) [![Discuss at go-github@googlegroups.com](https://img.shields.io/badge/discuss-go--github%40googlegroups.com-blue.svg)](https://groups.google.com/group/go-github) [![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/796/badge)](https://bestpractices.coreinfrastructure.org/projects/796) -[![TODOs](https://img.shields.io/endpoint?url=https://todos.tickgit.com/badge?repo=github.com/google/go-github)](https://todos.tickgit.com/browse?repo=github.com/google/go-github) go-github is a Go client library for accessing the [GitHub API v3][]. From cd0a96f774b7a52eaaf8568a0a1e6c1e361c7db0 Mon Sep 17 00:00:00 2001 From: Matt Gaunt Date: Tue, 4 Feb 2020 10:18:16 -0800 Subject: [PATCH 0125/1468] Adding Node ID to contributor struct (#1394) * Adding Node ID to contributor struct --- github/github-accessors.go | 8 ++++++++ github/repos.go | 1 + github/repos_stats_test.go | 6 ++++-- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/github/github-accessors.go b/github/github-accessors.go index f300b117ab5..72d200be32d 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -1940,6 +1940,14 @@ func (c *Contributor) GetLogin() string { return *c.Login } +// GetNodeID returns the NodeID field if it's non-nil, zero value otherwise. +func (c *Contributor) GetNodeID() string { + if c == nil || c.NodeID == nil { + return "" + } + return *c.NodeID +} + // GetOrganizationsURL returns the OrganizationsURL field if it's non-nil, zero value otherwise. func (c *Contributor) GetOrganizationsURL() string { if c == nil || c.OrganizationsURL == nil { diff --git a/github/repos.go b/github/repos.go index 8f9409e6b6c..133a9ef9360 100644 --- a/github/repos.go +++ b/github/repos.go @@ -496,6 +496,7 @@ func (s *RepositoriesService) Delete(ctx context.Context, owner, repo string) (* type Contributor struct { Login *string `json:"login,omitempty"` ID *int64 `json:"id,omitempty"` + NodeID *string `json:"node_id,omitempty"` AvatarURL *string `json:"avatar_url,omitempty"` GravatarID *string `json:"gravatar_id,omitempty"` URL *string `json:"url,omitempty"` diff --git a/github/repos_stats_test.go b/github/repos_stats_test.go index 055504d7027..4668cf18629 100644 --- a/github/repos_stats_test.go +++ b/github/repos_stats_test.go @@ -25,7 +25,8 @@ func TestRepositoriesService_ListContributorsStats(t *testing.T) { [ { "author": { - "id": 1 + "id": 1, + "node_id": "nodeid-1" }, "total": 135, "weeks": [ @@ -49,7 +50,8 @@ func TestRepositoriesService_ListContributorsStats(t *testing.T) { want := []*ContributorStats{ { Author: &Contributor{ - ID: Int64(1), + ID: Int64(1), + NodeID: String("nodeid-1"), }, Total: Int(135), Weeks: []WeeklyStats{ From 85084c0ce71a3d798a13cf693714cb9b7719a98e Mon Sep 17 00:00:00 2001 From: Qais Patankar Date: Sat, 8 Feb 2020 23:41:23 +0000 Subject: [PATCH 0126/1468] Add the AuthorAssociation field to PullRequestReview (#1413) --- github/github-accessors.go | 8 ++++++++ github/github-stringify_test.go | 19 ++++++++++--------- github/pulls_reviews.go | 3 +++ 3 files changed, 21 insertions(+), 9 deletions(-) diff --git a/github/github-accessors.go b/github/github-accessors.go index 72d200be32d..a17114ec914 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -8708,6 +8708,14 @@ func (p *PullRequestMergeResult) GetSHA() string { return *p.SHA } +// GetAuthorAssociation returns the AuthorAssociation field if it's non-nil, zero value otherwise. +func (p *PullRequestReview) GetAuthorAssociation() string { + if p == nil || p.AuthorAssociation == nil { + return "" + } + return *p.AuthorAssociation +} + // GetBody returns the Body field if it's non-nil, zero value otherwise. func (p *PullRequestReview) GetBody() string { if p == nil || p.Body == nil { diff --git a/github/github-stringify_test.go b/github/github-stringify_test.go index b156cc1db92..a8050964e61 100644 --- a/github/github-stringify_test.go +++ b/github/github-stringify_test.go @@ -1012,16 +1012,17 @@ func TestPullRequestComment_String(t *testing.T) { func TestPullRequestReview_String(t *testing.T) { v := PullRequestReview{ - ID: Int64(0), - NodeID: String(""), - User: &User{}, - Body: String(""), - CommitID: String(""), - HTMLURL: String(""), - PullRequestURL: String(""), - State: String(""), + ID: Int64(0), + NodeID: String(""), + User: &User{}, + Body: String(""), + CommitID: String(""), + HTMLURL: String(""), + PullRequestURL: String(""), + State: String(""), + AuthorAssociation: String(""), } - want := `github.PullRequestReview{ID:0, NodeID:"", User:github.User{}, Body:"", CommitID:"", HTMLURL:"", PullRequestURL:"", State:""}` + want := `github.PullRequestReview{ID:0, NodeID:"", User:github.User{}, Body:"", CommitID:"", HTMLURL:"", PullRequestURL:"", State:"", AuthorAssociation:""}` if got := v.String(); got != want { t.Errorf("PullRequestReview.String = %v, want %v", got, want) } diff --git a/github/pulls_reviews.go b/github/pulls_reviews.go index 88b82982f6d..aee49147ae1 100644 --- a/github/pulls_reviews.go +++ b/github/pulls_reviews.go @@ -22,6 +22,9 @@ type PullRequestReview struct { HTMLURL *string `json:"html_url,omitempty"` PullRequestURL *string `json:"pull_request_url,omitempty"` State *string `json:"state,omitempty"` + // AuthorAssociation is the comment author's relationship to the issue's repository. + // Possible values are "COLLABORATOR", "CONTRIBUTOR", "FIRST_TIMER", "FIRST_TIME_CONTRIBUTOR", "MEMBER", "OWNER", or "NONE". + AuthorAssociation *string `json:"author_association,omitempty"` } func (p PullRequestReview) String() string { From ac008bdb97b956632aeab6cab7e8f07cfb230756 Mon Sep 17 00:00:00 2001 From: Patrick Marabeas Date: Mon, 10 Feb 2020 11:53:25 +1100 Subject: [PATCH 0127/1468] Support specification of parameters for enable pages API (#1409) Fixes #1408. --- github/repos_pages.go | 15 +++++++++++++-- github/repos_pages_test.go | 19 ++++++++++++++++++- 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/github/repos_pages.go b/github/repos_pages.go index 7eb32a9df00..c0892fdc7de 100644 --- a/github/repos_pages.go +++ b/github/repos_pages.go @@ -43,12 +43,23 @@ type PagesBuild struct { UpdatedAt *Timestamp `json:"updated_at,omitempty"` } +// createPagesRequest is a subset of Pages and is used internally +// by EnablePages to pass only the known fields for the endpoint. +type createPagesRequest struct { + Source *PagesSource `json:"source,omitempty"` +} + // EnablePages enables GitHub Pages for the named repo. // // GitHub API docs: https://developer.github.com/v3/repos/pages/#enable-a-pages-site -func (s *RepositoriesService) EnablePages(ctx context.Context, owner, repo string) (*Pages, *Response, error) { +func (s *RepositoriesService) EnablePages(ctx context.Context, owner, repo string, pages *Pages) (*Pages, *Response, error) { u := fmt.Sprintf("repos/%v/%v/pages", owner, repo) - req, err := s.client.NewRequest("POST", u, nil) + + pagesReq := &createPagesRequest{ + Source: pages.Source, + } + + req, err := s.client.NewRequest("POST", u, pagesReq) if err != nil { return nil, nil, err } diff --git a/github/repos_pages_test.go b/github/repos_pages_test.go index ec77f717a69..8fe38eb3e24 100644 --- a/github/repos_pages_test.go +++ b/github/repos_pages_test.go @@ -7,6 +7,7 @@ package github import ( "context" + "encoding/json" "fmt" "net/http" "reflect" @@ -17,13 +18,29 @@ func TestRepositoriesService_EnablePages(t *testing.T) { client, mux, _, teardown := setup() defer teardown() + input := &Pages{ + Source: &PagesSource{ + Branch: String("master"), + Path: String("/"), + }, + CNAME: String("www.my-domain.com"), // not passed along. + } + mux.HandleFunc("/repos/o/r/pages", func(w http.ResponseWriter, r *http.Request) { + v := new(createPagesRequest) + json.NewDecoder(r.Body).Decode(v) + testMethod(t, r, "POST") testHeader(t, r, "Accept", mediaTypeEnablePagesAPIPreview) + want := &createPagesRequest{Source: &PagesSource{Branch: String("master"), Path: String("/")}} + if !reflect.DeepEqual(v, want) { + t.Errorf("Request body = %+v, want %+v", v, want) + } + fmt.Fprint(w, `{"url":"u","status":"s","cname":"c","custom_404":false,"html_url":"h", "source": {"branch":"master", "path":"/"}}`) }) - page, _, err := client.Repositories.EnablePages(context.Background(), "o", "r") + page, _, err := client.Repositories.EnablePages(context.Background(), "o", "r", input) if err != nil { t.Errorf("Repositories.EnablePages returned error: %v", err) } From 69231319df5dca3bd18097063872b3d71be004af Mon Sep 17 00:00:00 2001 From: kadern0 Date: Mon, 10 Feb 2020 12:01:54 +1100 Subject: [PATCH 0128/1468] Change opt param to opts (#1417) Fixes #1415. --- github/activity_events.go | 32 ++++++++++---------- github/activity_notifications.go | 8 ++--- github/activity_star.go | 8 ++--- github/activity_watching.go | 8 ++--- github/admin_users.go | 4 +-- github/apps.go | 12 ++++---- github/apps_installation.go | 8 ++--- github/apps_marketplace.go | 16 +++++----- github/authorizations.go | 8 ++--- github/checks.go | 32 ++++++++++---------- github/gists.go | 20 ++++++------- github/gists_comments.go | 4 +-- github/git_refs.go | 8 ++--- github/git_refs_test.go | 4 +-- github/github.go | 6 ++-- github/issues.go | 22 +++++++------- github/issues_assignees.go | 4 +-- github/issues_comments.go | 4 +-- github/issues_events.go | 8 ++--- github/issues_labels.go | 12 ++++---- github/issues_milestones.go | 4 +-- github/issues_timeline.go | 4 +-- github/migrations.go | 8 ++--- github/migrations_user.go | 8 ++--- github/misc.go | 12 ++++---- github/orgs.go | 12 ++++---- github/orgs_hooks.go | 4 +-- github/orgs_members.go | 22 +++++++------- github/orgs_outside_collaborators.go | 4 +-- github/orgs_projects.go | 8 ++--- github/orgs_users_blocking.go | 4 +-- github/projects.go | 44 ++++++++++++++-------------- github/pulls.go | 22 +++++++------- github/pulls_comments.go | 4 +-- github/pulls_reviewers.go | 4 +-- github/pulls_reviews.go | 8 ++--- github/pulls_test.go | 16 +++++----- github/reactions.go | 24 +++++++-------- github/repos.go | 28 +++++++++--------- github/repos_collaborators.go | 8 ++--- github/repos_comments.go | 8 ++--- github/repos_commits.go | 10 +++---- github/repos_contents.go | 30 +++++++++---------- github/repos_deployments.go | 8 ++--- github/repos_forks.go | 8 ++--- github/repos_hooks.go | 4 +-- github/repos_invitations.go | 4 +-- github/repos_keys.go | 4 +-- github/repos_pages.go | 4 +-- github/repos_prereceive_hooks.go | 4 +-- github/repos_projects.go | 8 ++--- github/repos_releases.go | 16 +++++----- github/repos_statuses.go | 8 ++--- github/repos_traffic.go | 8 ++--- github/search.go | 34 ++++++++++----------- github/teams.go | 32 ++++++++++---------- github/teams_members.go | 12 ++++---- github/users.go | 12 ++++---- github/users_administration.go | 4 +-- github/users_blocking.go | 4 +-- github/users_emails.go | 4 +-- github/users_followers.go | 8 ++--- github/users_gpg_keys.go | 4 +-- github/users_keys.go | 4 +-- github/users_projects.go | 8 ++--- 65 files changed, 363 insertions(+), 363 deletions(-) diff --git a/github/activity_events.go b/github/activity_events.go index 1754b78e9da..115bcc97d3a 100644 --- a/github/activity_events.go +++ b/github/activity_events.go @@ -13,8 +13,8 @@ import ( // ListEvents drinks from the firehose of all public events across GitHub. // // GitHub API docs: https://developer.github.com/v3/activity/events/#list-public-events -func (s *ActivityService) ListEvents(ctx context.Context, opt *ListOptions) ([]*Event, *Response, error) { - u, err := addOptions("events", opt) +func (s *ActivityService) ListEvents(ctx context.Context, opts *ListOptions) ([]*Event, *Response, error) { + u, err := addOptions("events", opts) if err != nil { return nil, nil, err } @@ -36,9 +36,9 @@ func (s *ActivityService) ListEvents(ctx context.Context, opt *ListOptions) ([]* // ListRepositoryEvents lists events for a repository. // // GitHub API docs: https://developer.github.com/v3/activity/events/#list-repository-events -func (s *ActivityService) ListRepositoryEvents(ctx context.Context, owner, repo string, opt *ListOptions) ([]*Event, *Response, error) { +func (s *ActivityService) ListRepositoryEvents(ctx context.Context, owner, repo string, opts *ListOptions) ([]*Event, *Response, error) { u := fmt.Sprintf("repos/%v/%v/events", owner, repo) - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } @@ -60,9 +60,9 @@ func (s *ActivityService) ListRepositoryEvents(ctx context.Context, owner, repo // ListIssueEventsForRepository lists issue events for a repository. // // GitHub API docs: https://developer.github.com/v3/activity/events/#list-issue-events-for-a-repository -func (s *ActivityService) ListIssueEventsForRepository(ctx context.Context, owner, repo string, opt *ListOptions) ([]*IssueEvent, *Response, error) { +func (s *ActivityService) ListIssueEventsForRepository(ctx context.Context, owner, repo string, opts *ListOptions) ([]*IssueEvent, *Response, error) { u := fmt.Sprintf("repos/%v/%v/issues/events", owner, repo) - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } @@ -84,9 +84,9 @@ func (s *ActivityService) ListIssueEventsForRepository(ctx context.Context, owne // ListEventsForRepoNetwork lists public events for a network of repositories. // // GitHub API docs: https://developer.github.com/v3/activity/events/#list-public-events-for-a-network-of-repositories -func (s *ActivityService) ListEventsForRepoNetwork(ctx context.Context, owner, repo string, opt *ListOptions) ([]*Event, *Response, error) { +func (s *ActivityService) ListEventsForRepoNetwork(ctx context.Context, owner, repo string, opts *ListOptions) ([]*Event, *Response, error) { u := fmt.Sprintf("networks/%v/%v/events", owner, repo) - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } @@ -108,9 +108,9 @@ func (s *ActivityService) ListEventsForRepoNetwork(ctx context.Context, owner, r // ListEventsForOrganization lists public events for an organization. // // GitHub API docs: https://developer.github.com/v3/activity/events/#list-public-events-for-an-organization -func (s *ActivityService) ListEventsForOrganization(ctx context.Context, org string, opt *ListOptions) ([]*Event, *Response, error) { +func (s *ActivityService) ListEventsForOrganization(ctx context.Context, org string, opts *ListOptions) ([]*Event, *Response, error) { u := fmt.Sprintf("orgs/%v/events", org) - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } @@ -133,14 +133,14 @@ func (s *ActivityService) ListEventsForOrganization(ctx context.Context, org str // true, only public events will be returned. // // GitHub API docs: https://developer.github.com/v3/activity/events/#list-events-performed-by-a-user -func (s *ActivityService) ListEventsPerformedByUser(ctx context.Context, user string, publicOnly bool, opt *ListOptions) ([]*Event, *Response, error) { +func (s *ActivityService) ListEventsPerformedByUser(ctx context.Context, user string, publicOnly bool, opts *ListOptions) ([]*Event, *Response, error) { var u string if publicOnly { u = fmt.Sprintf("users/%v/events/public", user) } else { u = fmt.Sprintf("users/%v/events", user) } - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } @@ -163,14 +163,14 @@ func (s *ActivityService) ListEventsPerformedByUser(ctx context.Context, user st // true, only public events will be returned. // // GitHub API docs: https://developer.github.com/v3/activity/events/#list-events-that-a-user-has-received -func (s *ActivityService) ListEventsReceivedByUser(ctx context.Context, user string, publicOnly bool, opt *ListOptions) ([]*Event, *Response, error) { +func (s *ActivityService) ListEventsReceivedByUser(ctx context.Context, user string, publicOnly bool, opts *ListOptions) ([]*Event, *Response, error) { var u string if publicOnly { u = fmt.Sprintf("users/%v/received_events/public", user) } else { u = fmt.Sprintf("users/%v/received_events", user) } - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } @@ -193,9 +193,9 @@ func (s *ActivityService) ListEventsReceivedByUser(ctx context.Context, user str // must be authenticated as the user to view this. // // GitHub API docs: https://developer.github.com/v3/activity/events/#list-events-for-an-organization -func (s *ActivityService) ListUserEventsForOrganization(ctx context.Context, org, user string, opt *ListOptions) ([]*Event, *Response, error) { +func (s *ActivityService) ListUserEventsForOrganization(ctx context.Context, org, user string, opts *ListOptions) ([]*Event, *Response, error) { u := fmt.Sprintf("users/%v/events/orgs/%v", user, org) - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } diff --git a/github/activity_notifications.go b/github/activity_notifications.go index 45c8b2aeced..983da6f82f1 100644 --- a/github/activity_notifications.go +++ b/github/activity_notifications.go @@ -50,9 +50,9 @@ type NotificationListOptions struct { // ListNotifications lists all notifications for the authenticated user. // // GitHub API docs: https://developer.github.com/v3/activity/notifications/#list-your-notifications -func (s *ActivityService) ListNotifications(ctx context.Context, opt *NotificationListOptions) ([]*Notification, *Response, error) { +func (s *ActivityService) ListNotifications(ctx context.Context, opts *NotificationListOptions) ([]*Notification, *Response, error) { u := fmt.Sprintf("notifications") - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } @@ -75,9 +75,9 @@ func (s *ActivityService) ListNotifications(ctx context.Context, opt *Notificati // for the authenticated user. // // GitHub API docs: https://developer.github.com/v3/activity/notifications/#list-your-notifications-in-a-repository -func (s *ActivityService) ListRepositoryNotifications(ctx context.Context, owner, repo string, opt *NotificationListOptions) ([]*Notification, *Response, error) { +func (s *ActivityService) ListRepositoryNotifications(ctx context.Context, owner, repo string, opts *NotificationListOptions) ([]*Notification, *Response, error) { u := fmt.Sprintf("repos/%v/%v/notifications", owner, repo) - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } diff --git a/github/activity_star.go b/github/activity_star.go index 5ae5c101651..1e9850f9e13 100644 --- a/github/activity_star.go +++ b/github/activity_star.go @@ -26,9 +26,9 @@ type Stargazer struct { // ListStargazers lists people who have starred the specified repo. // // GitHub API docs: https://developer.github.com/v3/activity/starring/#list-stargazers -func (s *ActivityService) ListStargazers(ctx context.Context, owner, repo string, opt *ListOptions) ([]*Stargazer, *Response, error) { +func (s *ActivityService) ListStargazers(ctx context.Context, owner, repo string, opts *ListOptions) ([]*Stargazer, *Response, error) { u := fmt.Sprintf("repos/%s/%s/stargazers", owner, repo) - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } @@ -68,14 +68,14 @@ type ActivityListStarredOptions struct { // will list the starred repositories for the authenticated user. // // GitHub API docs: https://developer.github.com/v3/activity/starring/#list-repositories-being-starred -func (s *ActivityService) ListStarred(ctx context.Context, user string, opt *ActivityListStarredOptions) ([]*StarredRepository, *Response, error) { +func (s *ActivityService) ListStarred(ctx context.Context, user string, opts *ActivityListStarredOptions) ([]*StarredRepository, *Response, error) { var u string if user != "" { u = fmt.Sprintf("users/%v/starred", user) } else { u = "user/starred" } - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } diff --git a/github/activity_watching.go b/github/activity_watching.go index c749ca86e7c..608647a6ce5 100644 --- a/github/activity_watching.go +++ b/github/activity_watching.go @@ -28,9 +28,9 @@ type Subscription struct { // ListWatchers lists watchers of a particular repo. // // GitHub API docs: https://developer.github.com/v3/activity/watching/#list-watchers -func (s *ActivityService) ListWatchers(ctx context.Context, owner, repo string, opt *ListOptions) ([]*User, *Response, error) { +func (s *ActivityService) ListWatchers(ctx context.Context, owner, repo string, opts *ListOptions) ([]*User, *Response, error) { u := fmt.Sprintf("repos/%s/%s/subscribers", owner, repo) - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } @@ -53,14 +53,14 @@ func (s *ActivityService) ListWatchers(ctx context.Context, owner, repo string, // the empty string will fetch watched repos for the authenticated user. // // GitHub API docs: https://developer.github.com/v3/activity/watching/#list-repositories-being-watched -func (s *ActivityService) ListWatched(ctx context.Context, user string, opt *ListOptions) ([]*Repository, *Response, error) { +func (s *ActivityService) ListWatched(ctx context.Context, user string, opts *ListOptions) ([]*Repository, *Response, error) { var u string if user != "" { u = fmt.Sprintf("users/%v/subscriptions", user) } else { u = "user/subscriptions" } - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } diff --git a/github/admin_users.go b/github/admin_users.go index 742855501ea..d756a77e20d 100644 --- a/github/admin_users.go +++ b/github/admin_users.go @@ -96,10 +96,10 @@ type UserAuthorization struct { // CreateUserImpersonation creates an impersonation OAuth token. // // GitHub Enterprise API docs: https://developer.github.com/enterprise/v3/enterprise-admin/users/#create-an-impersonation-oauth-token -func (s *AdminService) CreateUserImpersonation(ctx context.Context, username string, opt *ImpersonateUserOptions) (*UserAuthorization, *Response, error) { +func (s *AdminService) CreateUserImpersonation(ctx context.Context, username string, opts *ImpersonateUserOptions) (*UserAuthorization, *Response, error) { u := fmt.Sprintf("admin/users/%s/authorizations", username) - req, err := s.client.NewRequest("POST", u, opt) + req, err := s.client.NewRequest("POST", u, opts) if err != nil { return nil, nil, err } diff --git a/github/apps.go b/github/apps.go index 5bd76338dca..75d9177fa9a 100644 --- a/github/apps.go +++ b/github/apps.go @@ -152,8 +152,8 @@ func (s *AppsService) Get(ctx context.Context, appSlug string) (*App, *Response, // ListInstallations lists the installations that the current GitHub App has. // // GitHub API docs: https://developer.github.com/v3/apps/#list-installations -func (s *AppsService) ListInstallations(ctx context.Context, opt *ListOptions) ([]*Installation, *Response, error) { - u, err := addOptions("app/installations", opt) +func (s *AppsService) ListInstallations(ctx context.Context, opts *ListOptions) ([]*Installation, *Response, error) { + u, err := addOptions("app/installations", opts) if err != nil { return nil, nil, err } @@ -185,8 +185,8 @@ func (s *AppsService) GetInstallation(ctx context.Context, id int64) (*Installat // ListUserInstallations lists installations that are accessible to the authenticated user. // // GitHub API docs: https://developer.github.com/v3/apps/#list-installations-for-user -func (s *AppsService) ListUserInstallations(ctx context.Context, opt *ListOptions) ([]*Installation, *Response, error) { - u, err := addOptions("user/installations", opt) +func (s *AppsService) ListUserInstallations(ctx context.Context, opts *ListOptions) ([]*Installation, *Response, error) { + u, err := addOptions("user/installations", opts) if err != nil { return nil, nil, err } @@ -213,10 +213,10 @@ func (s *AppsService) ListUserInstallations(ctx context.Context, opt *ListOption // CreateInstallationToken creates a new installation token. // // GitHub API docs: https://developer.github.com/v3/apps/#create-a-new-installation-token -func (s *AppsService) CreateInstallationToken(ctx context.Context, id int64, opt *InstallationTokenOptions) (*InstallationToken, *Response, error) { +func (s *AppsService) CreateInstallationToken(ctx context.Context, id int64, opts *InstallationTokenOptions) (*InstallationToken, *Response, error) { u := fmt.Sprintf("app/installations/%v/access_tokens", id) - req, err := s.client.NewRequest("POST", u, opt) + req, err := s.client.NewRequest("POST", u, opts) if err != nil { return nil, nil, err } diff --git a/github/apps_installation.go b/github/apps_installation.go index c2e3b4ca9eb..59a90c15a99 100644 --- a/github/apps_installation.go +++ b/github/apps_installation.go @@ -13,8 +13,8 @@ import ( // ListRepos lists the repositories that are accessible to the authenticated installation. // // GitHub API docs: https://developer.github.com/v3/apps/installations/#list-repositories -func (s *AppsService) ListRepos(ctx context.Context, opt *ListOptions) ([]*Repository, *Response, error) { - u, err := addOptions("installation/repositories", opt) +func (s *AppsService) ListRepos(ctx context.Context, opts *ListOptions) ([]*Repository, *Response, error) { + u, err := addOptions("installation/repositories", opts) if err != nil { return nil, nil, err } @@ -42,9 +42,9 @@ func (s *AppsService) ListRepos(ctx context.Context, opt *ListOptions) ([]*Repos // to the authenticated user for an installation. // // GitHub API docs: https://developer.github.com/v3/apps/installations/#list-repositories-accessible-to-the-user-for-an-installation -func (s *AppsService) ListUserRepos(ctx context.Context, id int64, opt *ListOptions) ([]*Repository, *Response, error) { +func (s *AppsService) ListUserRepos(ctx context.Context, id int64, opts *ListOptions) ([]*Repository, *Response, error) { u := fmt.Sprintf("user/installations/%v/repositories", id) - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } diff --git a/github/apps_marketplace.go b/github/apps_marketplace.go index 863ba934cbc..053d451dc60 100644 --- a/github/apps_marketplace.go +++ b/github/apps_marketplace.go @@ -79,9 +79,9 @@ type MarketplacePlanAccount struct { // ListPlans lists all plans for your Marketplace listing. // // GitHub API docs: https://developer.github.com/v3/apps/marketplace/#list-all-plans-for-your-marketplace-listing -func (s *MarketplaceService) ListPlans(ctx context.Context, opt *ListOptions) ([]*MarketplacePlan, *Response, error) { +func (s *MarketplaceService) ListPlans(ctx context.Context, opts *ListOptions) ([]*MarketplacePlan, *Response, error) { uri := s.marketplaceURI("plans") - u, err := addOptions(uri, opt) + u, err := addOptions(uri, opts) if err != nil { return nil, nil, err } @@ -103,9 +103,9 @@ func (s *MarketplaceService) ListPlans(ctx context.Context, opt *ListOptions) ([ // ListPlanAccountsForPlan lists all GitHub accounts (user or organization) on a specific plan. // // GitHub API docs: https://developer.github.com/v3/apps/marketplace/#list-all-github-accounts-user-or-organization-on-a-specific-plan -func (s *MarketplaceService) ListPlanAccountsForPlan(ctx context.Context, planID int64, opt *ListOptions) ([]*MarketplacePlanAccount, *Response, error) { +func (s *MarketplaceService) ListPlanAccountsForPlan(ctx context.Context, planID int64, opts *ListOptions) ([]*MarketplacePlanAccount, *Response, error) { uri := s.marketplaceURI(fmt.Sprintf("plans/%v/accounts", planID)) - u, err := addOptions(uri, opt) + u, err := addOptions(uri, opts) if err != nil { return nil, nil, err } @@ -127,9 +127,9 @@ func (s *MarketplaceService) ListPlanAccountsForPlan(ctx context.Context, planID // ListPlanAccountsForAccount lists all GitHub accounts (user or organization) associated with an account. // // GitHub API docs: https://developer.github.com/v3/apps/marketplace/#check-if-a-github-account-is-associated-with-any-marketplace-listing -func (s *MarketplaceService) ListPlanAccountsForAccount(ctx context.Context, accountID int64, opt *ListOptions) ([]*MarketplacePlanAccount, *Response, error) { +func (s *MarketplaceService) ListPlanAccountsForAccount(ctx context.Context, accountID int64, opts *ListOptions) ([]*MarketplacePlanAccount, *Response, error) { uri := s.marketplaceURI(fmt.Sprintf("accounts/%v", accountID)) - u, err := addOptions(uri, opt) + u, err := addOptions(uri, opts) if err != nil { return nil, nil, err } @@ -151,13 +151,13 @@ func (s *MarketplaceService) ListPlanAccountsForAccount(ctx context.Context, acc // ListMarketplacePurchasesForUser lists all GitHub marketplace purchases made by a user. // // GitHub API docs: https://developer.github.com/v3/apps/marketplace/#get-a-users-marketplace-purchases -func (s *MarketplaceService) ListMarketplacePurchasesForUser(ctx context.Context, opt *ListOptions) ([]*MarketplacePurchase, *Response, error) { +func (s *MarketplaceService) ListMarketplacePurchasesForUser(ctx context.Context, opts *ListOptions) ([]*MarketplacePurchase, *Response, error) { uri := "user/marketplace_purchases" if s.Stubbed { uri = "user/marketplace_purchases/stubbed" } - u, err := addOptions(uri, opt) + u, err := addOptions(uri, opts) if err != nil { return nil, nil, err } diff --git a/github/authorizations.go b/github/authorizations.go index 8ad14328e94..a73c37fd079 100644 --- a/github/authorizations.go +++ b/github/authorizations.go @@ -137,9 +137,9 @@ func (a AuthorizationUpdateRequest) String() string { // List the authorizations for the authenticated user. // // GitHub API docs: https://developer.github.com/v3/oauth_authorizations/#list-your-authorizations -func (s *AuthorizationsService) List(ctx context.Context, opt *ListOptions) ([]*Authorization, *Response, error) { +func (s *AuthorizationsService) List(ctx context.Context, opts *ListOptions) ([]*Authorization, *Response, error) { u := "authorizations" - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } @@ -343,8 +343,8 @@ func (s *AuthorizationsService) Revoke(ctx context.Context, clientID string, tok // tokens an application has generated for the user. // // GitHub API docs: https://developer.github.com/v3/oauth_authorizations/#list-your-grants -func (s *AuthorizationsService) ListGrants(ctx context.Context, opt *ListOptions) ([]*Grant, *Response, error) { - u, err := addOptions("applications/grants", opt) +func (s *AuthorizationsService) ListGrants(ctx context.Context, opts *ListOptions) ([]*Grant, *Response, error) { + u, err := addOptions("applications/grants", opts) if err != nil { return nil, nil, err } diff --git a/github/checks.go b/github/checks.go index 1acc26e9935..55adf14ea16 100644 --- a/github/checks.go +++ b/github/checks.go @@ -161,9 +161,9 @@ type CheckRunAction struct { // CreateCheckRun creates a check run for repository. // // GitHub API docs: https://developer.github.com/v3/checks/runs/#create-a-check-run -func (s *ChecksService) CreateCheckRun(ctx context.Context, owner, repo string, opt CreateCheckRunOptions) (*CheckRun, *Response, error) { +func (s *ChecksService) CreateCheckRun(ctx context.Context, owner, repo string, opts CreateCheckRunOptions) (*CheckRun, *Response, error) { u := fmt.Sprintf("repos/%v/%v/check-runs", owner, repo) - req, err := s.client.NewRequest("POST", u, opt) + req, err := s.client.NewRequest("POST", u, opts) if err != nil { return nil, nil, err } @@ -195,9 +195,9 @@ type UpdateCheckRunOptions struct { // UpdateCheckRun updates a check run for a specific commit in a repository. // // GitHub API docs: https://developer.github.com/v3/checks/runs/#update-a-check-run -func (s *ChecksService) UpdateCheckRun(ctx context.Context, owner, repo string, checkRunID int64, opt UpdateCheckRunOptions) (*CheckRun, *Response, error) { +func (s *ChecksService) UpdateCheckRun(ctx context.Context, owner, repo string, checkRunID int64, opts UpdateCheckRunOptions) (*CheckRun, *Response, error) { u := fmt.Sprintf("repos/%v/%v/check-runs/%v", owner, repo, checkRunID) - req, err := s.client.NewRequest("PATCH", u, opt) + req, err := s.client.NewRequest("PATCH", u, opts) if err != nil { return nil, nil, err } @@ -216,9 +216,9 @@ func (s *ChecksService) UpdateCheckRun(ctx context.Context, owner, repo string, // ListCheckRunAnnotations lists the annotations for a check run. // // GitHub API docs: https://developer.github.com/v3/checks/runs/#list-annotations-for-a-check-run -func (s *ChecksService) ListCheckRunAnnotations(ctx context.Context, owner, repo string, checkRunID int64, opt *ListOptions) ([]*CheckRunAnnotation, *Response, error) { +func (s *ChecksService) ListCheckRunAnnotations(ctx context.Context, owner, repo string, checkRunID int64, opts *ListOptions) ([]*CheckRunAnnotation, *Response, error) { u := fmt.Sprintf("repos/%v/%v/check-runs/%v/annotations", owner, repo, checkRunID) - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } @@ -257,9 +257,9 @@ type ListCheckRunsResults struct { // ListCheckRunsForRef lists check runs for a specific ref. // // GitHub API docs: https://developer.github.com/v3/checks/runs/#list-check-runs-for-a-specific-ref -func (s *ChecksService) ListCheckRunsForRef(ctx context.Context, owner, repo, ref string, opt *ListCheckRunsOptions) (*ListCheckRunsResults, *Response, error) { +func (s *ChecksService) ListCheckRunsForRef(ctx context.Context, owner, repo, ref string, opts *ListCheckRunsOptions) (*ListCheckRunsResults, *Response, error) { u := fmt.Sprintf("repos/%v/%v/commits/%v/check-runs", owner, repo, url.QueryEscape(ref)) - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } @@ -283,9 +283,9 @@ func (s *ChecksService) ListCheckRunsForRef(ctx context.Context, owner, repo, re // ListCheckRunsCheckSuite lists check runs for a check suite. // // GitHub API docs: https://developer.github.com/v3/checks/runs/#list-check-runs-in-a-check-suite -func (s *ChecksService) ListCheckRunsCheckSuite(ctx context.Context, owner, repo string, checkSuiteID int64, opt *ListCheckRunsOptions) (*ListCheckRunsResults, *Response, error) { +func (s *ChecksService) ListCheckRunsCheckSuite(ctx context.Context, owner, repo string, checkSuiteID int64, opts *ListCheckRunsOptions) (*ListCheckRunsResults, *Response, error) { u := fmt.Sprintf("repos/%v/%v/check-suites/%v/check-runs", owner, repo, checkSuiteID) - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } @@ -323,9 +323,9 @@ type ListCheckSuiteResults struct { // ListCheckSuitesForRef lists check suite for a specific ref. // // GitHub API docs: https://developer.github.com/v3/checks/suites/#list-check-suites-for-a-specific-ref -func (s *ChecksService) ListCheckSuitesForRef(ctx context.Context, owner, repo, ref string, opt *ListCheckSuiteOptions) (*ListCheckSuiteResults, *Response, error) { +func (s *ChecksService) ListCheckSuitesForRef(ctx context.Context, owner, repo, ref string, opts *ListCheckSuiteOptions) (*ListCheckSuiteResults, *Response, error) { u := fmt.Sprintf("repos/%v/%v/commits/%v/check-suites", owner, repo, url.QueryEscape(ref)) - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } @@ -371,9 +371,9 @@ type PreferenceList struct { // SetCheckSuitePreferences changes the default automatic flow when creating check suites. // // GitHub API docs: https://developer.github.com/v3/checks/suites/#set-preferences-for-check-suites-on-a-repository -func (s *ChecksService) SetCheckSuitePreferences(ctx context.Context, owner, repo string, opt CheckSuitePreferenceOptions) (*CheckSuitePreferenceResults, *Response, error) { +func (s *ChecksService) SetCheckSuitePreferences(ctx context.Context, owner, repo string, opts CheckSuitePreferenceOptions) (*CheckSuitePreferenceResults, *Response, error) { u := fmt.Sprintf("repos/%v/%v/check-suites/preferences", owner, repo) - req, err := s.client.NewRequest("PATCH", u, opt) + req, err := s.client.NewRequest("PATCH", u, opts) if err != nil { return nil, nil, err } @@ -398,9 +398,9 @@ type CreateCheckSuiteOptions struct { // CreateCheckSuite manually creates a check suite for a repository. // // GitHub API docs: https://developer.github.com/v3/checks/suites/#create-a-check-suite -func (s *ChecksService) CreateCheckSuite(ctx context.Context, owner, repo string, opt CreateCheckSuiteOptions) (*CheckSuite, *Response, error) { +func (s *ChecksService) CreateCheckSuite(ctx context.Context, owner, repo string, opts CreateCheckSuiteOptions) (*CheckSuite, *Response, error) { u := fmt.Sprintf("repos/%v/%v/check-suites", owner, repo) - req, err := s.client.NewRequest("POST", u, opt) + req, err := s.client.NewRequest("POST", u, opts) if err != nil { return nil, nil, err } diff --git a/github/gists.go b/github/gists.go index 36d9361967c..0f326055421 100644 --- a/github/gists.go +++ b/github/gists.go @@ -97,14 +97,14 @@ type GistListOptions struct { // user. // // GitHub API docs: https://developer.github.com/v3/gists/#list-gists -func (s *GistsService) List(ctx context.Context, user string, opt *GistListOptions) ([]*Gist, *Response, error) { +func (s *GistsService) List(ctx context.Context, user string, opts *GistListOptions) ([]*Gist, *Response, error) { var u string if user != "" { u = fmt.Sprintf("users/%v/gists", user) } else { u = "gists" } - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } @@ -126,8 +126,8 @@ func (s *GistsService) List(ctx context.Context, user string, opt *GistListOptio // ListAll lists all public gists. // // GitHub API docs: https://developer.github.com/v3/gists/#list-gists -func (s *GistsService) ListAll(ctx context.Context, opt *GistListOptions) ([]*Gist, *Response, error) { - u, err := addOptions("gists/public", opt) +func (s *GistsService) ListAll(ctx context.Context, opts *GistListOptions) ([]*Gist, *Response, error) { + u, err := addOptions("gists/public", opts) if err != nil { return nil, nil, err } @@ -149,8 +149,8 @@ func (s *GistsService) ListAll(ctx context.Context, opt *GistListOptions) ([]*Gi // ListStarred lists starred gists of authenticated user. // // GitHub API docs: https://developer.github.com/v3/gists/#list-gists -func (s *GistsService) ListStarred(ctx context.Context, opt *GistListOptions) ([]*Gist, *Response, error) { - u, err := addOptions("gists/starred", opt) +func (s *GistsService) ListStarred(ctx context.Context, opts *GistListOptions) ([]*Gist, *Response, error) { + u, err := addOptions("gists/starred", opts) if err != nil { return nil, nil, err } @@ -248,9 +248,9 @@ func (s *GistsService) Edit(ctx context.Context, id string, gist *Gist) (*Gist, // ListCommits lists commits of a gist. // // GitHub API docs: https://developer.github.com/v3/gists/#list-gist-commits -func (s *GistsService) ListCommits(ctx context.Context, id string, opt *ListOptions) ([]*GistCommit, *Response, error) { +func (s *GistsService) ListCommits(ctx context.Context, id string, opts *ListOptions) ([]*GistCommit, *Response, error) { u := fmt.Sprintf("gists/%v/commits", id) - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } @@ -341,9 +341,9 @@ func (s *GistsService) Fork(ctx context.Context, id string) (*Gist, *Response, e // ListForks lists forks of a gist. // // GitHub API docs: https://developer.github.com/v3/gists/#list-gist-forks -func (s *GistsService) ListForks(ctx context.Context, id string, opt *ListOptions) ([]*GistFork, *Response, error) { +func (s *GistsService) ListForks(ctx context.Context, id string, opts *ListOptions) ([]*GistFork, *Response, error) { u := fmt.Sprintf("gists/%v/forks", id) - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } diff --git a/github/gists_comments.go b/github/gists_comments.go index d5322e3d852..33913e22fd7 100644 --- a/github/gists_comments.go +++ b/github/gists_comments.go @@ -27,9 +27,9 @@ func (g GistComment) String() string { // ListComments lists all comments for a gist. // // GitHub API docs: https://developer.github.com/v3/gists/comments/#list-comments-on-a-gist -func (s *GistsService) ListComments(ctx context.Context, gistID string, opt *ListOptions) ([]*GistComment, *Response, error) { +func (s *GistsService) ListComments(ctx context.Context, gistID string, opts *ListOptions) ([]*GistComment, *Response, error) { u := fmt.Sprintf("gists/%v/comments", gistID) - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } diff --git a/github/git_refs.go b/github/git_refs.go index b51bcbf1deb..18494dae33e 100644 --- a/github/git_refs.go +++ b/github/git_refs.go @@ -135,14 +135,14 @@ type ReferenceListOptions struct { // ListRefs lists all refs in a repository. // // GitHub API docs: https://developer.github.com/v3/git/refs/#get-all-references -func (s *GitService) ListRefs(ctx context.Context, owner, repo string, opt *ReferenceListOptions) ([]*Reference, *Response, error) { +func (s *GitService) ListRefs(ctx context.Context, owner, repo string, opts *ReferenceListOptions) ([]*Reference, *Response, error) { var u string - if opt != nil && opt.Type != "" { - u = fmt.Sprintf("repos/%v/%v/git/refs/%v", owner, repo, opt.Type) + if opts != nil && opts.Type != "" { + u = fmt.Sprintf("repos/%v/%v/git/refs/%v", owner, repo, opts.Type) } else { u = fmt.Sprintf("repos/%v/%v/git/refs", owner, repo) } - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } diff --git a/github/git_refs_test.go b/github/git_refs_test.go index 6c8a1d87951..fb91c043316 100644 --- a/github/git_refs_test.go +++ b/github/git_refs_test.go @@ -290,8 +290,8 @@ func TestGitService_ListRefs_options(t *testing.T) { fmt.Fprint(w, `[{"ref": "r"}]`) }) - opt := &ReferenceListOptions{Type: "t", ListOptions: ListOptions{Page: 2}} - refs, _, err := client.Git.ListRefs(context.Background(), "o", "r", opt) + opts := &ReferenceListOptions{Type: "t", ListOptions: ListOptions{Page: 2}} + refs, _, err := client.Git.ListRefs(context.Background(), "o", "r", opts) if err != nil { t.Errorf("Git.ListRefs returned error: %v", err) } diff --git a/github/github.go b/github/github.go index 794ee9c168c..b1b9afa2ff9 100644 --- a/github/github.go +++ b/github/github.go @@ -231,8 +231,8 @@ type RawOptions struct { // addOptions adds the parameters in opt as URL query parameters to s. opt // must be a struct whose fields may contain "url" tags. -func addOptions(s string, opt interface{}) (string, error) { - v := reflect.ValueOf(opt) +func addOptions(s string, opts interface{}) (string, error) { + v := reflect.ValueOf(opts) if v.Kind() == reflect.Ptr && v.IsNil() { return s, nil } @@ -242,7 +242,7 @@ func addOptions(s string, opt interface{}) (string, error) { return s, err } - qs, err := query.Values(opt) + qs, err := query.Values(opts) if err != nil { return s, err } diff --git a/github/issues.go b/github/issues.go index b08934c3e52..63a5fde75c8 100644 --- a/github/issues.go +++ b/github/issues.go @@ -129,27 +129,27 @@ type PullRequestLinks struct { // repositories. // // GitHub API docs: https://developer.github.com/v3/issues/#list-issues -func (s *IssuesService) List(ctx context.Context, all bool, opt *IssueListOptions) ([]*Issue, *Response, error) { +func (s *IssuesService) List(ctx context.Context, all bool, opts *IssueListOptions) ([]*Issue, *Response, error) { var u string if all { u = "issues" } else { u = "user/issues" } - return s.listIssues(ctx, u, opt) + return s.listIssues(ctx, u, opts) } // ListByOrg fetches the issues in the specified organization for the // authenticated user. // // GitHub API docs: https://developer.github.com/v3/issues/#list-issues -func (s *IssuesService) ListByOrg(ctx context.Context, org string, opt *IssueListOptions) ([]*Issue, *Response, error) { +func (s *IssuesService) ListByOrg(ctx context.Context, org string, opts *IssueListOptions) ([]*Issue, *Response, error) { u := fmt.Sprintf("orgs/%v/issues", org) - return s.listIssues(ctx, u, opt) + return s.listIssues(ctx, u, opts) } -func (s *IssuesService) listIssues(ctx context.Context, u string, opt *IssueListOptions) ([]*Issue, *Response, error) { - u, err := addOptions(u, opt) +func (s *IssuesService) listIssues(ctx context.Context, u string, opts *IssueListOptions) ([]*Issue, *Response, error) { + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } @@ -215,9 +215,9 @@ type IssueListByRepoOptions struct { // ListByRepo lists the issues for the specified repository. // // GitHub API docs: https://developer.github.com/v3/issues/#list-issues-for-a-repository -func (s *IssuesService) ListByRepo(ctx context.Context, owner string, repo string, opt *IssueListByRepoOptions) ([]*Issue, *Response, error) { +func (s *IssuesService) ListByRepo(ctx context.Context, owner string, repo string, opts *IssueListByRepoOptions) ([]*Issue, *Response, error) { u := fmt.Sprintf("repos/%v/%v/issues", owner, repo) - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } @@ -313,14 +313,14 @@ type LockIssueOptions struct { // 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, opt *LockIssueOptions) (*Response, error) { +func (s *IssuesService) Lock(ctx context.Context, owner string, repo string, number int, opts *LockIssueOptions) (*Response, error) { u := fmt.Sprintf("repos/%v/%v/issues/%d/lock", owner, repo, number) - req, err := s.client.NewRequest("PUT", u, opt) + req, err := s.client.NewRequest("PUT", u, opts) if err != nil { return nil, err } - if opt != nil { + if opts != nil { req.Header.Set("Accept", mediaTypeLockReasonPreview) } diff --git a/github/issues_assignees.go b/github/issues_assignees.go index 9cb366f50a3..c09806fd62e 100644 --- a/github/issues_assignees.go +++ b/github/issues_assignees.go @@ -14,9 +14,9 @@ import ( // which issues may be assigned. // // GitHub API docs: https://developer.github.com/v3/issues/assignees/#list-assignees -func (s *IssuesService) ListAssignees(ctx context.Context, owner, repo string, opt *ListOptions) ([]*User, *Response, error) { +func (s *IssuesService) ListAssignees(ctx context.Context, owner, repo string, opts *ListOptions) ([]*User, *Response, error) { u := fmt.Sprintf("repos/%v/%v/assignees", owner, repo) - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } diff --git a/github/issues_comments.go b/github/issues_comments.go index 42d6bc78898..56b24c19179 100644 --- a/github/issues_comments.go +++ b/github/issues_comments.go @@ -51,14 +51,14 @@ type IssueListCommentsOptions struct { // number of 0 will return all comments on all issues for the repository. // // GitHub API docs: https://developer.github.com/v3/issues/comments/#list-comments-on-an-issue -func (s *IssuesService) ListComments(ctx context.Context, owner string, repo string, number int, opt *IssueListCommentsOptions) ([]*IssueComment, *Response, error) { +func (s *IssuesService) ListComments(ctx context.Context, owner string, repo string, number int, opts *IssueListCommentsOptions) ([]*IssueComment, *Response, error) { var u string if number == 0 { u = fmt.Sprintf("repos/%v/%v/issues/comments", owner, repo) } else { u = fmt.Sprintf("repos/%v/%v/issues/%d/comments", owner, repo, number) } - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } diff --git a/github/issues_events.go b/github/issues_events.go index 4456d67e5c3..fa948596a31 100644 --- a/github/issues_events.go +++ b/github/issues_events.go @@ -96,9 +96,9 @@ type DismissedReview struct { // ListIssueEvents lists events for the specified issue. // // GitHub API docs: https://developer.github.com/v3/issues/events/#list-events-for-an-issue -func (s *IssuesService) ListIssueEvents(ctx context.Context, owner, repo string, number int, opt *ListOptions) ([]*IssueEvent, *Response, error) { +func (s *IssuesService) ListIssueEvents(ctx context.Context, owner, repo string, number int, opts *ListOptions) ([]*IssueEvent, *Response, error) { u := fmt.Sprintf("repos/%v/%v/issues/%v/events", owner, repo, number) - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } @@ -123,9 +123,9 @@ func (s *IssuesService) ListIssueEvents(ctx context.Context, owner, repo string, // ListRepositoryEvents lists events for the specified repository. // // GitHub API docs: https://developer.github.com/v3/issues/events/#list-events-for-a-repository -func (s *IssuesService) ListRepositoryEvents(ctx context.Context, owner, repo string, opt *ListOptions) ([]*IssueEvent, *Response, error) { +func (s *IssuesService) ListRepositoryEvents(ctx context.Context, owner, repo string, opts *ListOptions) ([]*IssueEvent, *Response, error) { u := fmt.Sprintf("repos/%v/%v/issues/events", owner, repo) - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } diff --git a/github/issues_labels.go b/github/issues_labels.go index 0771a28c8f8..fa3002599a8 100644 --- a/github/issues_labels.go +++ b/github/issues_labels.go @@ -28,9 +28,9 @@ func (l Label) String() string { // ListLabels lists all labels for a repository. // // GitHub API docs: https://developer.github.com/v3/issues/labels/#list-all-labels-for-this-repository -func (s *IssuesService) ListLabels(ctx context.Context, owner string, repo string, opt *ListOptions) ([]*Label, *Response, error) { +func (s *IssuesService) ListLabels(ctx context.Context, owner string, repo string, opts *ListOptions) ([]*Label, *Response, error) { u := fmt.Sprintf("repos/%v/%v/labels", owner, repo) - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } @@ -121,9 +121,9 @@ func (s *IssuesService) DeleteLabel(ctx context.Context, owner string, repo stri // ListLabelsByIssue lists all labels for an issue. // // GitHub API docs: https://developer.github.com/v3/issues/labels/#list-labels-on-an-issue -func (s *IssuesService) ListLabelsByIssue(ctx context.Context, owner string, repo string, number int, opt *ListOptions) ([]*Label, *Response, error) { +func (s *IssuesService) ListLabelsByIssue(ctx context.Context, owner string, repo string, number int, opts *ListOptions) ([]*Label, *Response, error) { u := fmt.Sprintf("repos/%v/%v/issues/%d/labels", owner, repo, number) - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } @@ -209,9 +209,9 @@ func (s *IssuesService) RemoveLabelsForIssue(ctx context.Context, owner string, // ListLabelsForMilestone lists labels for every issue in a milestone. // // GitHub API docs: https://developer.github.com/v3/issues/labels/#get-labels-for-every-issue-in-a-milestone -func (s *IssuesService) ListLabelsForMilestone(ctx context.Context, owner string, repo string, number int, opt *ListOptions) ([]*Label, *Response, error) { +func (s *IssuesService) ListLabelsForMilestone(ctx context.Context, owner string, repo string, number int, opts *ListOptions) ([]*Label, *Response, error) { u := fmt.Sprintf("repos/%v/%v/milestones/%d/labels", owner, repo, number) - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } diff --git a/github/issues_milestones.go b/github/issues_milestones.go index ffe9aae14ca..4e44350722f 100644 --- a/github/issues_milestones.go +++ b/github/issues_milestones.go @@ -56,9 +56,9 @@ type MilestoneListOptions struct { // ListMilestones lists all milestones for a repository. // // GitHub API docs: https://developer.github.com/v3/issues/milestones/#list-milestones-for-a-repository -func (s *IssuesService) ListMilestones(ctx context.Context, owner string, repo string, opt *MilestoneListOptions) ([]*Milestone, *Response, error) { +func (s *IssuesService) ListMilestones(ctx context.Context, owner string, repo string, opts *MilestoneListOptions) ([]*Milestone, *Response, error) { u := fmt.Sprintf("repos/%v/%v/milestones", owner, repo) - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } diff --git a/github/issues_timeline.go b/github/issues_timeline.go index d0e4a3a9428..58465e22285 100644 --- a/github/issues_timeline.go +++ b/github/issues_timeline.go @@ -132,9 +132,9 @@ type Source struct { // ListIssueTimeline lists events for the specified issue. // // GitHub API docs: https://developer.github.com/v3/issues/timeline/#list-events-for-an-issue -func (s *IssuesService) ListIssueTimeline(ctx context.Context, owner, repo string, number int, opt *ListOptions) ([]*Timeline, *Response, error) { +func (s *IssuesService) ListIssueTimeline(ctx context.Context, owner, repo string, number int, opts *ListOptions) ([]*Timeline, *Response, error) { u := fmt.Sprintf("repos/%v/%v/issues/%v/timeline", owner, repo, number) - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } diff --git a/github/migrations.go b/github/migrations.go index ef0095e0664..f4260bb77cc 100644 --- a/github/migrations.go +++ b/github/migrations.go @@ -75,13 +75,13 @@ type startMigration struct { // repos is a slice of repository names to migrate. // // GitHub API docs: https://developer.github.com/v3/migration/migrations/#start-a-migration -func (s *MigrationService) StartMigration(ctx context.Context, org string, repos []string, opt *MigrationOptions) (*Migration, *Response, error) { +func (s *MigrationService) StartMigration(ctx context.Context, org string, repos []string, opts *MigrationOptions) (*Migration, *Response, error) { u := fmt.Sprintf("orgs/%v/migrations", org) body := &startMigration{Repositories: repos} - if opt != nil { - body.LockRepositories = Bool(opt.LockRepositories) - body.ExcludeAttachments = Bool(opt.ExcludeAttachments) + if opts != nil { + body.LockRepositories = Bool(opts.LockRepositories) + body.ExcludeAttachments = Bool(opts.ExcludeAttachments) } req, err := s.client.NewRequest("POST", u, body) diff --git a/github/migrations_user.go b/github/migrations_user.go index d45555f216b..5b58d293544 100644 --- a/github/migrations_user.go +++ b/github/migrations_user.go @@ -68,13 +68,13 @@ type startUserMigration struct { // repos is a slice of repository names to migrate. // // GitHub API docs: https://developer.github.com/v3/migrations/users/#start-a-user-migration -func (s *MigrationService) StartUserMigration(ctx context.Context, repos []string, opt *UserMigrationOptions) (*UserMigration, *Response, error) { +func (s *MigrationService) StartUserMigration(ctx context.Context, repos []string, opts *UserMigrationOptions) (*UserMigration, *Response, error) { u := "user/migrations" body := &startUserMigration{Repositories: repos} - if opt != nil { - body.LockRepositories = Bool(opt.LockRepositories) - body.ExcludeAttachments = Bool(opt.ExcludeAttachments) + if opts != nil { + body.LockRepositories = Bool(opts.LockRepositories) + body.ExcludeAttachments = Bool(opts.ExcludeAttachments) } req, err := s.client.NewRequest("POST", u, body) diff --git a/github/misc.go b/github/misc.go index e9b0ea22a62..139a0dc66a9 100644 --- a/github/misc.go +++ b/github/misc.go @@ -40,14 +40,14 @@ type markdownRequest struct { // Markdown renders an arbitrary Markdown document. // // GitHub API docs: https://developer.github.com/v3/markdown/ -func (c *Client) Markdown(ctx context.Context, text string, opt *MarkdownOptions) (string, *Response, error) { +func (c *Client) Markdown(ctx context.Context, text string, opts *MarkdownOptions) (string, *Response, error) { request := &markdownRequest{Text: String(text)} - if opt != nil { - if opt.Mode != "" { - request.Mode = String(opt.Mode) + if opts != nil { + if opts.Mode != "" { + request.Mode = String(opts.Mode) } - if opt.Context != "" { - request.Context = String(opt.Context) + if opts.Context != "" { + request.Context = String(opts.Context) } } diff --git a/github/orgs.go b/github/orgs.go index bae67dad580..3c87ec84d4f 100644 --- a/github/orgs.go +++ b/github/orgs.go @@ -122,8 +122,8 @@ type OrganizationsListOptions struct { // as the opts.Since parameter for the next call. // // GitHub API docs: https://developer.github.com/v3/orgs/#list-all-organizations -func (s *OrganizationsService) ListAll(ctx context.Context, opt *OrganizationsListOptions) ([]*Organization, *Response, error) { - u, err := addOptions("organizations", opt) +func (s *OrganizationsService) ListAll(ctx context.Context, opts *OrganizationsListOptions) ([]*Organization, *Response, error) { + u, err := addOptions("organizations", opts) if err != nil { return nil, nil, err } @@ -145,14 +145,14 @@ func (s *OrganizationsService) ListAll(ctx context.Context, opt *OrganizationsLi // organizations for the authenticated user. // // GitHub API docs: https://developer.github.com/v3/orgs/#list-user-organizations -func (s *OrganizationsService) List(ctx context.Context, user string, opt *ListOptions) ([]*Organization, *Response, error) { +func (s *OrganizationsService) List(ctx context.Context, user string, opts *ListOptions) ([]*Organization, *Response, error) { var u string if user != "" { u = fmt.Sprintf("users/%v/orgs", user) } else { u = "user/orgs" } - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } @@ -237,10 +237,10 @@ func (s *OrganizationsService) Edit(ctx context.Context, name string, org *Organ // ListInstallations lists installations for an organization. // // GitHub API docs: https://developer.github.com/v3/orgs/#list-installations-for-an-organization -func (s *OrganizationsService) ListInstallations(ctx context.Context, org string, opt *ListOptions) (*OrganizationInstallations, *Response, error) { +func (s *OrganizationsService) ListInstallations(ctx context.Context, org string, opts *ListOptions) (*OrganizationInstallations, *Response, error) { u := fmt.Sprintf("orgs/%v/installations", org) - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } diff --git a/github/orgs_hooks.go b/github/orgs_hooks.go index 5357eb87840..0913fb83dac 100644 --- a/github/orgs_hooks.go +++ b/github/orgs_hooks.go @@ -13,9 +13,9 @@ import ( // ListHooks lists all Hooks for the specified organization. // // GitHub API docs: https://developer.github.com/v3/orgs/hooks/#list-hooks -func (s *OrganizationsService) ListHooks(ctx context.Context, org string, opt *ListOptions) ([]*Hook, *Response, error) { +func (s *OrganizationsService) ListHooks(ctx context.Context, org string, opts *ListOptions) ([]*Hook, *Response, error) { u := fmt.Sprintf("orgs/%v/hooks", org) - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } diff --git a/github/orgs_members.go b/github/orgs_members.go index a2fc9265dff..6b96d05f67c 100644 --- a/github/orgs_members.go +++ b/github/orgs_members.go @@ -72,14 +72,14 @@ type ListMembersOptions struct { // public members, otherwise it will only return public members. // // GitHub API docs: https://developer.github.com/v3/orgs/members/#members-list -func (s *OrganizationsService) ListMembers(ctx context.Context, org string, opt *ListMembersOptions) ([]*User, *Response, error) { +func (s *OrganizationsService) ListMembers(ctx context.Context, org string, opts *ListMembersOptions) ([]*User, *Response, error) { var u string - if opt != nil && opt.PublicOnly { + if opts != nil && opts.PublicOnly { u = fmt.Sprintf("orgs/%v/public_members", org) } else { u = fmt.Sprintf("orgs/%v/members", org) } - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } @@ -181,9 +181,9 @@ type ListOrgMembershipsOptions struct { // ListOrgMemberships lists the organization memberships for the authenticated user. // // GitHub API docs: https://developer.github.com/v3/orgs/members/#list-your-organization-memberships -func (s *OrganizationsService) ListOrgMemberships(ctx context.Context, opt *ListOrgMembershipsOptions) ([]*Membership, *Response, error) { +func (s *OrganizationsService) ListOrgMemberships(ctx context.Context, opts *ListOrgMembershipsOptions) ([]*Membership, *Response, error) { u := "user/memberships/orgs" - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } @@ -278,9 +278,9 @@ func (s *OrganizationsService) RemoveOrgMembership(ctx context.Context, user, or // ListPendingOrgInvitations returns a list of pending invitations. // // GitHub API docs: https://developer.github.com/v3/orgs/members/#list-pending-organization-invitations -func (s *OrganizationsService) ListPendingOrgInvitations(ctx context.Context, org string, opt *ListOptions) ([]*Invitation, *Response, error) { +func (s *OrganizationsService) ListPendingOrgInvitations(ctx context.Context, org string, opts *ListOptions) ([]*Invitation, *Response, error) { u := fmt.Sprintf("orgs/%v/invitations", org) - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } @@ -323,10 +323,10 @@ type CreateOrgInvitationOptions struct { // the authenticated user must be an organization owner. // // https://developer.github.com/v3/orgs/members/#create-organization-invitation -func (s *OrganizationsService) CreateOrgInvitation(ctx context.Context, org string, opt *CreateOrgInvitationOptions) (*Invitation, *Response, error) { +func (s *OrganizationsService) CreateOrgInvitation(ctx context.Context, org string, opts *CreateOrgInvitationOptions) (*Invitation, *Response, error) { u := fmt.Sprintf("orgs/%v/invitations", org) - req, err := s.client.NewRequest("POST", u, opt) + req, err := s.client.NewRequest("POST", u, opts) if err != nil { return nil, nil, err } @@ -343,9 +343,9 @@ func (s *OrganizationsService) CreateOrgInvitation(ctx context.Context, org stri // the authenticated user must be an organization owner. // // GitHub API docs: https://developer.github.com/v3/orgs/members/#list-organization-invitation-teams -func (s *OrganizationsService) ListOrgInvitationTeams(ctx context.Context, org, invitationID string, opt *ListOptions) ([]*Team, *Response, error) { +func (s *OrganizationsService) ListOrgInvitationTeams(ctx context.Context, org, invitationID string, opts *ListOptions) ([]*Team, *Response, error) { u := fmt.Sprintf("orgs/%v/invitations/%v/teams", org, invitationID) - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } diff --git a/github/orgs_outside_collaborators.go b/github/orgs_outside_collaborators.go index 85ffd05f61a..dde8e0b03ab 100644 --- a/github/orgs_outside_collaborators.go +++ b/github/orgs_outside_collaborators.go @@ -28,9 +28,9 @@ type ListOutsideCollaboratorsOptions struct { // Preview features are not supported for production use. // // GitHub API docs: https://developer.github.com/v3/orgs/outside_collaborators/#list-outside-collaborators -func (s *OrganizationsService) ListOutsideCollaborators(ctx context.Context, org string, opt *ListOutsideCollaboratorsOptions) ([]*User, *Response, error) { +func (s *OrganizationsService) ListOutsideCollaborators(ctx context.Context, org string, opts *ListOutsideCollaboratorsOptions) ([]*User, *Response, error) { u := fmt.Sprintf("orgs/%v/outside_collaborators", org) - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } diff --git a/github/orgs_projects.go b/github/orgs_projects.go index e57cba97829..cc3ed3b1bb6 100644 --- a/github/orgs_projects.go +++ b/github/orgs_projects.go @@ -13,9 +13,9 @@ import ( // ListProjects lists the projects for an organization. // // GitHub API docs: https://developer.github.com/v3/projects/#list-organization-projects -func (s *OrganizationsService) ListProjects(ctx context.Context, org string, opt *ProjectListOptions) ([]*Project, *Response, error) { +func (s *OrganizationsService) ListProjects(ctx context.Context, org string, opts *ProjectListOptions) ([]*Project, *Response, error) { u := fmt.Sprintf("orgs/%v/projects", org) - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } @@ -40,9 +40,9 @@ func (s *OrganizationsService) ListProjects(ctx context.Context, org string, opt // CreateProject creates a GitHub Project for the specified organization. // // GitHub API docs: https://developer.github.com/v3/projects/#create-an-organization-project -func (s *OrganizationsService) CreateProject(ctx context.Context, org string, opt *ProjectOptions) (*Project, *Response, error) { +func (s *OrganizationsService) CreateProject(ctx context.Context, org string, opts *ProjectOptions) (*Project, *Response, error) { u := fmt.Sprintf("orgs/%v/projects", org) - req, err := s.client.NewRequest("POST", u, opt) + req, err := s.client.NewRequest("POST", u, opts) if err != nil { return nil, nil, err } diff --git a/github/orgs_users_blocking.go b/github/orgs_users_blocking.go index b1aecf44532..bf48716d731 100644 --- a/github/orgs_users_blocking.go +++ b/github/orgs_users_blocking.go @@ -13,9 +13,9 @@ import ( // ListBlockedUsers lists all the users blocked by an organization. // // GitHub API docs: https://developer.github.com/v3/orgs/blocking/#list-blocked-users -func (s *OrganizationsService) ListBlockedUsers(ctx context.Context, org string, opt *ListOptions) ([]*User, *Response, error) { +func (s *OrganizationsService) ListBlockedUsers(ctx context.Context, org string, opts *ListOptions) ([]*User, *Response, error) { u := fmt.Sprintf("orgs/%v/blocks", org) - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } diff --git a/github/projects.go b/github/projects.go index 1e9620dfd9f..e11d74a559a 100644 --- a/github/projects.go +++ b/github/projects.go @@ -89,9 +89,9 @@ type ProjectOptions struct { // UpdateProject updates a repository project. // // GitHub API docs: https://developer.github.com/v3/projects/#update-a-project -func (s *ProjectsService) UpdateProject(ctx context.Context, id int64, opt *ProjectOptions) (*Project, *Response, error) { +func (s *ProjectsService) UpdateProject(ctx context.Context, id int64, opts *ProjectOptions) (*Project, *Response, error) { u := fmt.Sprintf("projects/%v", id) - req, err := s.client.NewRequest("PATCH", u, opt) + req, err := s.client.NewRequest("PATCH", u, opts) if err != nil { return nil, nil, err } @@ -141,9 +141,9 @@ type ProjectColumn struct { // ListProjectColumns lists the columns of a GitHub Project for a repo. // // GitHub API docs: https://developer.github.com/v3/projects/columns/#list-project-columns -func (s *ProjectsService) ListProjectColumns(ctx context.Context, projectID int64, opt *ListOptions) ([]*ProjectColumn, *Response, error) { +func (s *ProjectsService) ListProjectColumns(ctx context.Context, projectID int64, opts *ListOptions) ([]*ProjectColumn, *Response, error) { u := fmt.Sprintf("projects/%v/columns", projectID) - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } @@ -198,9 +198,9 @@ type ProjectColumnOptions struct { // CreateProjectColumn creates a column for the specified (by number) project. // // GitHub API docs: https://developer.github.com/v3/projects/columns/#create-a-project-column -func (s *ProjectsService) CreateProjectColumn(ctx context.Context, projectID int64, opt *ProjectColumnOptions) (*ProjectColumn, *Response, error) { +func (s *ProjectsService) CreateProjectColumn(ctx context.Context, projectID int64, opts *ProjectColumnOptions) (*ProjectColumn, *Response, error) { u := fmt.Sprintf("projects/%v/columns", projectID) - req, err := s.client.NewRequest("POST", u, opt) + req, err := s.client.NewRequest("POST", u, opts) if err != nil { return nil, nil, err } @@ -220,9 +220,9 @@ func (s *ProjectsService) CreateProjectColumn(ctx context.Context, projectID int // UpdateProjectColumn updates a column of a GitHub Project. // // GitHub API docs: https://developer.github.com/v3/projects/columns/#update-a-project-column -func (s *ProjectsService) UpdateProjectColumn(ctx context.Context, columnID int64, opt *ProjectColumnOptions) (*ProjectColumn, *Response, error) { +func (s *ProjectsService) UpdateProjectColumn(ctx context.Context, columnID int64, opts *ProjectColumnOptions) (*ProjectColumn, *Response, error) { u := fmt.Sprintf("projects/columns/%v", columnID) - req, err := s.client.NewRequest("PATCH", u, opt) + req, err := s.client.NewRequest("PATCH", u, opts) if err != nil { return nil, nil, err } @@ -266,9 +266,9 @@ type ProjectColumnMoveOptions struct { // MoveProjectColumn moves a column within a GitHub Project. // // GitHub API docs: https://developer.github.com/v3/projects/columns/#move-a-project-column -func (s *ProjectsService) MoveProjectColumn(ctx context.Context, columnID int64, opt *ProjectColumnMoveOptions) (*Response, error) { +func (s *ProjectsService) MoveProjectColumn(ctx context.Context, columnID int64, opts *ProjectColumnMoveOptions) (*Response, error) { u := fmt.Sprintf("projects/columns/%v/moves", columnID) - req, err := s.client.NewRequest("POST", u, opt) + req, err := s.client.NewRequest("POST", u, opts) if err != nil { return nil, err } @@ -317,9 +317,9 @@ type ProjectCardListOptions struct { // ListProjectCards lists the cards in a column of a GitHub Project. // // GitHub API docs: https://developer.github.com/v3/projects/cards/#list-project-cards -func (s *ProjectsService) ListProjectCards(ctx context.Context, columnID int64, opt *ProjectCardListOptions) ([]*ProjectCard, *Response, error) { +func (s *ProjectsService) ListProjectCards(ctx context.Context, columnID int64, opts *ProjectCardListOptions) ([]*ProjectCard, *Response, error) { u := fmt.Sprintf("projects/columns/%v/cards", columnID) - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } @@ -382,9 +382,9 @@ type ProjectCardOptions struct { // CreateProjectCard creates a card in the specified column of a GitHub Project. // // GitHub API docs: https://developer.github.com/v3/projects/cards/#create-a-project-card -func (s *ProjectsService) CreateProjectCard(ctx context.Context, columnID int64, opt *ProjectCardOptions) (*ProjectCard, *Response, error) { +func (s *ProjectsService) CreateProjectCard(ctx context.Context, columnID int64, opts *ProjectCardOptions) (*ProjectCard, *Response, error) { u := fmt.Sprintf("projects/columns/%v/cards", columnID) - req, err := s.client.NewRequest("POST", u, opt) + req, err := s.client.NewRequest("POST", u, opts) if err != nil { return nil, nil, err } @@ -404,9 +404,9 @@ func (s *ProjectsService) CreateProjectCard(ctx context.Context, columnID int64, // UpdateProjectCard updates a card of a GitHub Project. // // GitHub API docs: https://developer.github.com/v3/projects/cards/#update-a-project-card -func (s *ProjectsService) UpdateProjectCard(ctx context.Context, cardID int64, opt *ProjectCardOptions) (*ProjectCard, *Response, error) { +func (s *ProjectsService) UpdateProjectCard(ctx context.Context, cardID int64, opts *ProjectCardOptions) (*ProjectCard, *Response, error) { u := fmt.Sprintf("projects/columns/cards/%v", cardID) - req, err := s.client.NewRequest("PATCH", u, opt) + req, err := s.client.NewRequest("PATCH", u, opts) if err != nil { return nil, nil, err } @@ -454,9 +454,9 @@ type ProjectCardMoveOptions struct { // MoveProjectCard moves a card within a GitHub Project. // // GitHub API docs: https://developer.github.com/v3/projects/cards/#move-a-project-card -func (s *ProjectsService) MoveProjectCard(ctx context.Context, cardID int64, opt *ProjectCardMoveOptions) (*Response, error) { +func (s *ProjectsService) MoveProjectCard(ctx context.Context, cardID int64, opts *ProjectCardMoveOptions) (*Response, error) { u := fmt.Sprintf("projects/columns/cards/%v/moves", cardID) - req, err := s.client.NewRequest("POST", u, opt) + req, err := s.client.NewRequest("POST", u, opts) if err != nil { return nil, err } @@ -484,9 +484,9 @@ type ProjectCollaboratorOptions struct { // their permission level. You must be an organization owner or a project admin to add a collaborator. // // GitHub API docs: https://developer.github.com/v3/projects/collaborators/#add-user-as-a-collaborator -func (s *ProjectsService) AddProjectCollaborator(ctx context.Context, id int64, username string, opt *ProjectCollaboratorOptions) (*Response, error) { +func (s *ProjectsService) AddProjectCollaborator(ctx context.Context, id int64, username string, opts *ProjectCollaboratorOptions) (*Response, error) { u := fmt.Sprintf("projects/%v/collaborators/%v", id, username) - req, err := s.client.NewRequest("PUT", u, opt) + req, err := s.client.NewRequest("PUT", u, opts) if err != nil { return nil, err } @@ -537,9 +537,9 @@ type ListCollaboratorOptions struct { // organization owner or a project admin to list collaborators. // // GitHub API docs: https://developer.github.com/v3/projects/collaborators/#list-collaborators -func (s *ProjectsService) ListProjectCollaborators(ctx context.Context, id int64, opt *ListCollaboratorOptions) ([]*User, *Response, error) { +func (s *ProjectsService) ListProjectCollaborators(ctx context.Context, id int64, opts *ListCollaboratorOptions) ([]*User, *Response, error) { u := fmt.Sprintf("projects/%v/collaborators", id) - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } diff --git a/github/pulls.go b/github/pulls.go index 867455aeaf6..bd799cede13 100644 --- a/github/pulls.go +++ b/github/pulls.go @@ -136,9 +136,9 @@ type PullRequestListOptions struct { // List the pull requests for the specified repository. // // GitHub API docs: https://developer.github.com/v3/pulls/#list-pull-requests -func (s *PullRequestsService) List(ctx context.Context, owner string, repo string, opt *PullRequestListOptions) ([]*PullRequest, *Response, error) { +func (s *PullRequestsService) List(ctx context.Context, owner string, repo string, opts *PullRequestListOptions) ([]*PullRequest, *Response, error) { u := fmt.Sprintf("repos/%v/%v/pulls", owner, repo) - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } @@ -166,9 +166,9 @@ func (s *PullRequestsService) List(ctx context.Context, owner string, repo strin // 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) { +func (s *PullRequestsService) ListPullRequestsWithCommit(ctx context.Context, owner, repo, sha string, opts *PullRequestListOptions) ([]*PullRequest, *Response, error) { u := fmt.Sprintf("repos/%v/%v/commits/%v/pulls", owner, repo, sha) - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } @@ -214,20 +214,20 @@ func (s *PullRequestsService) Get(ctx context.Context, owner string, repo string } // GetRaw gets a single pull request in raw (diff or patch) format. -func (s *PullRequestsService) GetRaw(ctx context.Context, owner string, repo string, number int, opt RawOptions) (string, *Response, error) { +func (s *PullRequestsService) GetRaw(ctx context.Context, owner string, repo string, number int, opts RawOptions) (string, *Response, error) { u := fmt.Sprintf("repos/%v/%v/pulls/%d", owner, repo, number) req, err := s.client.NewRequest("GET", u, nil) if err != nil { return "", nil, err } - switch opt.Type { + switch opts.Type { case Diff: req.Header.Set("Accept", mediaTypeV3Diff) case Patch: req.Header.Set("Accept", mediaTypeV3Patch) default: - return "", nil, fmt.Errorf("unsupported raw type %d", opt.Type) + return "", nil, fmt.Errorf("unsupported raw type %d", opts.Type) } var buf bytes.Buffer @@ -372,9 +372,9 @@ func (s *PullRequestsService) Edit(ctx context.Context, owner string, repo strin // ListCommits lists the commits in a pull request. // // GitHub API docs: https://developer.github.com/v3/pulls/#list-commits-on-a-pull-request -func (s *PullRequestsService) ListCommits(ctx context.Context, owner string, repo string, number int, opt *ListOptions) ([]*RepositoryCommit, *Response, error) { +func (s *PullRequestsService) ListCommits(ctx context.Context, owner string, repo string, number int, opts *ListOptions) ([]*RepositoryCommit, *Response, error) { u := fmt.Sprintf("repos/%v/%v/pulls/%d/commits", owner, repo, number) - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } @@ -396,9 +396,9 @@ func (s *PullRequestsService) ListCommits(ctx context.Context, owner string, rep // ListFiles lists the files in a pull request. // // GitHub API docs: https://developer.github.com/v3/pulls/#list-pull-requests-files -func (s *PullRequestsService) ListFiles(ctx context.Context, owner string, repo string, number int, opt *ListOptions) ([]*CommitFile, *Response, error) { +func (s *PullRequestsService) ListFiles(ctx context.Context, owner string, repo string, number int, opts *ListOptions) ([]*CommitFile, *Response, error) { u := fmt.Sprintf("repos/%v/%v/pulls/%d/files", owner, repo, number) - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } diff --git a/github/pulls_comments.go b/github/pulls_comments.go index 3372e3383ef..88fb209b6fa 100644 --- a/github/pulls_comments.go +++ b/github/pulls_comments.go @@ -67,14 +67,14 @@ type PullRequestListCommentsOptions struct { // the repository. // // GitHub API docs: https://developer.github.com/v3/pulls/comments/#list-comments-on-a-pull-request -func (s *PullRequestsService) ListComments(ctx context.Context, owner string, repo string, number int, opt *PullRequestListCommentsOptions) ([]*PullRequestComment, *Response, error) { +func (s *PullRequestsService) ListComments(ctx context.Context, owner string, repo string, number int, opts *PullRequestListCommentsOptions) ([]*PullRequestComment, *Response, error) { var u string if number == 0 { u = fmt.Sprintf("repos/%v/%v/pulls/comments", owner, repo) } else { u = fmt.Sprintf("repos/%v/%v/pulls/%d/comments", owner, repo, number) } - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } diff --git a/github/pulls_reviewers.go b/github/pulls_reviewers.go index beae953c4c9..368f9680a8b 100644 --- a/github/pulls_reviewers.go +++ b/github/pulls_reviewers.go @@ -45,9 +45,9 @@ func (s *PullRequestsService) RequestReviewers(ctx context.Context, owner, repo // ListReviewers lists reviewers whose reviews have been requested on the specified pull request. // // GitHub API docs: https://developer.github.com/v3/pulls/review_requests/#list-review-requests -func (s *PullRequestsService) ListReviewers(ctx context.Context, owner, repo string, number int, opt *ListOptions) (*Reviewers, *Response, error) { +func (s *PullRequestsService) ListReviewers(ctx context.Context, owner, repo string, number int, opts *ListOptions) (*Reviewers, *Response, error) { u := fmt.Sprintf("repos/%v/%v/pulls/%d/requested_reviewers", owner, repo, number) - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } diff --git a/github/pulls_reviews.go b/github/pulls_reviews.go index aee49147ae1..5bceb61c4c3 100644 --- a/github/pulls_reviews.go +++ b/github/pulls_reviews.go @@ -71,9 +71,9 @@ func (r PullRequestReviewDismissalRequest) String() string { // Read more about it here - https://github.com/google/go-github/issues/540 // // GitHub API docs: https://developer.github.com/v3/pulls/reviews/#list-reviews-on-a-pull-request -func (s *PullRequestsService) ListReviews(ctx context.Context, owner, repo string, number int, opt *ListOptions) ([]*PullRequestReview, *Response, error) { +func (s *PullRequestsService) ListReviews(ctx context.Context, owner, repo string, number int, opts *ListOptions) ([]*PullRequestReview, *Response, error) { u := fmt.Sprintf("repos/%v/%v/pulls/%d/reviews", owner, repo, number) - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } @@ -147,9 +147,9 @@ func (s *PullRequestsService) DeletePendingReview(ctx context.Context, owner, re // Read more about it here - https://github.com/google/go-github/issues/540 // // GitHub API docs: https://developer.github.com/v3/pulls/reviews/#get-comments-for-a-single-review -func (s *PullRequestsService) ListReviewComments(ctx context.Context, owner, repo string, number int, reviewID int64, opt *ListOptions) ([]*PullRequestComment, *Response, error) { +func (s *PullRequestsService) ListReviewComments(ctx context.Context, owner, repo string, number int, reviewID int64, opts *ListOptions) ([]*PullRequestComment, *Response, error) { u := fmt.Sprintf("repos/%v/%v/pulls/%d/reviews/%d/comments", owner, repo, number, reviewID) - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } diff --git a/github/pulls_test.go b/github/pulls_test.go index b19921f5d34..4adabdbd53b 100644 --- a/github/pulls_test.go +++ b/github/pulls_test.go @@ -35,8 +35,8 @@ func TestPullRequestsService_List(t *testing.T) { fmt.Fprint(w, `[{"number":1}]`) }) - opt := &PullRequestListOptions{"closed", "h", "b", "created", "desc", ListOptions{Page: 2}} - pulls, _, err := client.PullRequests.List(context.Background(), "o", "r", opt) + opts := &PullRequestListOptions{"closed", "h", "b", "created", "desc", ListOptions{Page: 2}} + pulls, _, err := client.PullRequests.List(context.Background(), "o", "r", opts) if err != nil { t.Errorf("PullRequests.List returned error: %v", err) } @@ -66,8 +66,8 @@ func TestPullRequestsService_ListPullRequestsWithCommit(t *testing.T) { 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) + opts := &PullRequestListOptions{"closed", "h", "b", "created", "desc", ListOptions{Page: 2}} + pulls, _, err := client.PullRequests.ListPullRequestsWithCommit(context.Background(), "o", "r", "sha", opts) if err != nil { t.Errorf("PullRequests.ListPullRequestsWithCommit returned error: %v", err) } @@ -458,8 +458,8 @@ func TestPullRequestsService_ListCommits(t *testing.T) { ]`) }) - opt := &ListOptions{Page: 2} - commits, _, err := client.PullRequests.ListCommits(context.Background(), "o", "r", 1, opt) + opts := &ListOptions{Page: 2} + commits, _, err := client.PullRequests.ListCommits(context.Background(), "o", "r", 1, opts) if err != nil { t.Errorf("PullRequests.ListCommits returned error: %v", err) } @@ -517,8 +517,8 @@ func TestPullRequestsService_ListFiles(t *testing.T) { ]`) }) - opt := &ListOptions{Page: 2} - commitFiles, _, err := client.PullRequests.ListFiles(context.Background(), "o", "r", 1, opt) + opts := &ListOptions{Page: 2} + commitFiles, _, err := client.PullRequests.ListFiles(context.Background(), "o", "r", 1, opts) if err != nil { t.Errorf("PullRequests.ListFiles returned error: %v", err) } diff --git a/github/reactions.go b/github/reactions.go index 1935ce11174..43c863af61d 100644 --- a/github/reactions.go +++ b/github/reactions.go @@ -58,9 +58,9 @@ type ListCommentReactionOptions struct { // ListCommentReactions lists the reactions for a commit comment. // // GitHub API docs: https://developer.github.com/v3/reactions/#list-reactions-for-a-commit-comment -func (s *ReactionsService) ListCommentReactions(ctx context.Context, owner, repo string, id int64, opt *ListCommentReactionOptions) ([]*Reaction, *Response, error) { +func (s *ReactionsService) ListCommentReactions(ctx context.Context, owner, repo string, id int64, opts *ListCommentReactionOptions) ([]*Reaction, *Response, error) { u := fmt.Sprintf("repos/%v/%v/comments/%v/reactions", owner, repo, id) - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } @@ -112,9 +112,9 @@ func (s ReactionsService) CreateCommentReaction(ctx context.Context, owner, repo // ListIssueReactions lists the reactions for an issue. // // GitHub API docs: https://developer.github.com/v3/reactions/#list-reactions-for-an-issue -func (s *ReactionsService) ListIssueReactions(ctx context.Context, owner, repo string, number int, opt *ListOptions) ([]*Reaction, *Response, error) { +func (s *ReactionsService) ListIssueReactions(ctx context.Context, owner, repo string, number int, opts *ListOptions) ([]*Reaction, *Response, error) { u := fmt.Sprintf("repos/%v/%v/issues/%v/reactions", owner, repo, number) - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } @@ -166,9 +166,9 @@ func (s ReactionsService) CreateIssueReaction(ctx context.Context, owner, repo s // ListIssueCommentReactions lists the reactions for an issue comment. // // GitHub API docs: https://developer.github.com/v3/reactions/#list-reactions-for-an-issue-comment -func (s *ReactionsService) ListIssueCommentReactions(ctx context.Context, owner, repo string, id int64, opt *ListOptions) ([]*Reaction, *Response, error) { +func (s *ReactionsService) ListIssueCommentReactions(ctx context.Context, owner, repo string, id int64, opts *ListOptions) ([]*Reaction, *Response, error) { u := fmt.Sprintf("repos/%v/%v/issues/comments/%v/reactions", owner, repo, id) - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } @@ -220,9 +220,9 @@ func (s ReactionsService) CreateIssueCommentReaction(ctx context.Context, owner, // ListPullRequestCommentReactions lists the reactions for a pull request review comment. // // GitHub API docs: https://developer.github.com/v3/reactions/#list-reactions-for-an-issue-comment -func (s *ReactionsService) ListPullRequestCommentReactions(ctx context.Context, owner, repo string, id int64, opt *ListOptions) ([]*Reaction, *Response, error) { +func (s *ReactionsService) ListPullRequestCommentReactions(ctx context.Context, owner, repo string, id int64, opts *ListOptions) ([]*Reaction, *Response, error) { u := fmt.Sprintf("repos/%v/%v/pulls/comments/%v/reactions", owner, repo, id) - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } @@ -274,9 +274,9 @@ func (s ReactionsService) CreatePullRequestCommentReaction(ctx context.Context, // ListTeamDiscussionReactions lists the reactions for a team discussion. // // GitHub API docs: https://developer.github.com/v3/reactions/#list-reactions-for-a-team-discussion -func (s *ReactionsService) ListTeamDiscussionReactions(ctx context.Context, teamID int64, discussionNumber int, opt *ListOptions) ([]*Reaction, *Response, error) { +func (s *ReactionsService) ListTeamDiscussionReactions(ctx context.Context, teamID int64, discussionNumber int, opts *ListOptions) ([]*Reaction, *Response, error) { u := fmt.Sprintf("teams/%v/discussions/%v/reactions", teamID, discussionNumber) - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } @@ -324,9 +324,9 @@ func (s *ReactionsService) CreateTeamDiscussionReaction(ctx context.Context, tea // ListTeamDiscussionCommentReactions lists the reactions for a team discussion comment. // // GitHub API docs: https://developer.github.com/v3/reactions/#list-reactions-for-a-team-discussion-comment -func (s *ReactionsService) ListTeamDiscussionCommentReactions(ctx context.Context, teamID int64, discussionNumber, commentNumber int, opt *ListOptions) ([]*Reaction, *Response, error) { +func (s *ReactionsService) ListTeamDiscussionCommentReactions(ctx context.Context, teamID int64, discussionNumber, commentNumber int, opts *ListOptions) ([]*Reaction, *Response, error) { u := fmt.Sprintf("teams/%v/discussions/%v/comments/%v/reactions", teamID, discussionNumber, commentNumber) - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } diff --git a/github/repos.go b/github/repos.go index 133a9ef9360..5aa56006ee0 100644 --- a/github/repos.go +++ b/github/repos.go @@ -178,14 +178,14 @@ type RepositoryListOptions struct { // repositories for the authenticated user. // // GitHub API docs: https://developer.github.com/v3/repos/#list-user-repositories -func (s *RepositoriesService) List(ctx context.Context, user string, opt *RepositoryListOptions) ([]*Repository, *Response, error) { +func (s *RepositoriesService) List(ctx context.Context, user string, opts *RepositoryListOptions) ([]*Repository, *Response, error) { var u string if user != "" { u = fmt.Sprintf("users/%v/repos", user) } else { u = "user/repos" } - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } @@ -229,9 +229,9 @@ type RepositoryListByOrgOptions struct { // ListByOrg lists the repositories for an organization. // // GitHub API docs: https://developer.github.com/v3/repos/#list-organization-repositories -func (s *RepositoriesService) ListByOrg(ctx context.Context, org string, opt *RepositoryListByOrgOptions) ([]*Repository, *Response, error) { +func (s *RepositoriesService) ListByOrg(ctx context.Context, org string, opts *RepositoryListByOrgOptions) ([]*Repository, *Response, error) { u := fmt.Sprintf("orgs/%v/repos", org) - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } @@ -264,8 +264,8 @@ type RepositoryListAllOptions struct { // ListAll lists all GitHub repositories in the order that they were created. // // GitHub API docs: https://developer.github.com/v3/repos/#list-all-public-repositories -func (s *RepositoriesService) ListAll(ctx context.Context, opt *RepositoryListAllOptions) ([]*Repository, *Response, error) { - u, err := addOptions("repositories", opt) +func (s *RepositoriesService) ListAll(ctx context.Context, opts *RepositoryListAllOptions) ([]*Repository, *Response, error) { + u, err := addOptions("repositories", opts) if err != nil { return nil, nil, err } @@ -615,9 +615,9 @@ func (s *RepositoriesService) DisableAutomatedSecurityFixes(ctx context.Context, // ListContributors lists contributors for a repository. // // GitHub API docs: https://developer.github.com/v3/repos/#list-contributors -func (s *RepositoriesService) ListContributors(ctx context.Context, owner string, repository string, opt *ListContributorsOptions) ([]*Contributor, *Response, error) { +func (s *RepositoriesService) ListContributors(ctx context.Context, owner string, repository string, opts *ListContributorsOptions) ([]*Contributor, *Response, error) { u := fmt.Sprintf("repos/%v/%v/contributors", owner, repository) - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } @@ -665,9 +665,9 @@ func (s *RepositoriesService) ListLanguages(ctx context.Context, owner string, r // ListTeams lists the teams for the specified repository. // // GitHub API docs: https://developer.github.com/v3/repos/#list-teams -func (s *RepositoriesService) ListTeams(ctx context.Context, owner string, repo string, opt *ListOptions) ([]*Team, *Response, error) { +func (s *RepositoriesService) ListTeams(ctx context.Context, owner string, repo string, opts *ListOptions) ([]*Team, *Response, error) { u := fmt.Sprintf("repos/%v/%v/teams", owner, repo) - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } @@ -697,9 +697,9 @@ type RepositoryTag struct { // ListTags lists tags for the specified repository. // // GitHub API docs: https://developer.github.com/v3/repos/#list-tags -func (s *RepositoriesService) ListTags(ctx context.Context, owner string, repo string, opt *ListOptions) ([]*RepositoryTag, *Response, error) { +func (s *RepositoriesService) ListTags(ctx context.Context, owner string, repo string, opts *ListOptions) ([]*RepositoryTag, *Response, error) { u := fmt.Sprintf("repos/%v/%v/tags", owner, repo) - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } @@ -885,9 +885,9 @@ type SignaturesProtectedBranch struct { // ListBranches lists branches for the specified repository. // // GitHub API docs: https://developer.github.com/v3/repos/#list-branches -func (s *RepositoriesService) ListBranches(ctx context.Context, owner string, repo string, opt *BranchListOptions) ([]*Branch, *Response, error) { +func (s *RepositoriesService) ListBranches(ctx context.Context, owner string, repo string, opts *BranchListOptions) ([]*Branch, *Response, error) { u := fmt.Sprintf("repos/%v/%v/branches", owner, repo) - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } diff --git a/github/repos_collaborators.go b/github/repos_collaborators.go index 8254ac0661b..bdfe04f13f3 100644 --- a/github/repos_collaborators.go +++ b/github/repos_collaborators.go @@ -42,9 +42,9 @@ type CollaboratorInvitation struct { // ListCollaborators lists the GitHub users that have access to the repository. // // GitHub API docs: https://developer.github.com/v3/repos/collaborators/#list-collaborators -func (s *RepositoriesService) ListCollaborators(ctx context.Context, owner, repo string, opt *ListCollaboratorsOptions) ([]*User, *Response, error) { +func (s *RepositoriesService) ListCollaborators(ctx context.Context, owner, repo string, opts *ListCollaboratorsOptions) ([]*User, *Response, error) { u := fmt.Sprintf("repos/%v/%v/collaborators", owner, repo) - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } @@ -124,9 +124,9 @@ type RepositoryAddCollaboratorOptions struct { // to become a collaborator to the given repo. // // GitHub API docs: https://developer.github.com/v3/repos/collaborators/#add-user-as-a-collaborator -func (s *RepositoriesService) AddCollaborator(ctx context.Context, owner, repo, user string, opt *RepositoryAddCollaboratorOptions) (*CollaboratorInvitation, *Response, error) { +func (s *RepositoriesService) AddCollaborator(ctx context.Context, owner, repo, user string, opts *RepositoryAddCollaboratorOptions) (*CollaboratorInvitation, *Response, error) { u := fmt.Sprintf("repos/%v/%v/collaborators/%v", owner, repo, user) - req, err := s.client.NewRequest("PUT", u, opt) + req, err := s.client.NewRequest("PUT", u, opts) if err != nil { return nil, nil, err } diff --git a/github/repos_comments.go b/github/repos_comments.go index 380ca3d3b43..891825f965a 100644 --- a/github/repos_comments.go +++ b/github/repos_comments.go @@ -37,9 +37,9 @@ func (r RepositoryComment) String() string { // ListComments lists all the comments for the repository. // // GitHub API docs: https://developer.github.com/v3/repos/comments/#list-commit-comments-for-a-repository -func (s *RepositoriesService) ListComments(ctx context.Context, owner, repo string, opt *ListOptions) ([]*RepositoryComment, *Response, error) { +func (s *RepositoriesService) ListComments(ctx context.Context, owner, repo string, opts *ListOptions) ([]*RepositoryComment, *Response, error) { u := fmt.Sprintf("repos/%v/%v/comments", owner, repo) - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } @@ -64,9 +64,9 @@ func (s *RepositoriesService) ListComments(ctx context.Context, owner, repo stri // ListCommitComments lists all the comments for a given commit SHA. // // GitHub API docs: https://developer.github.com/v3/repos/comments/#list-comments-for-a-single-commit -func (s *RepositoriesService) ListCommitComments(ctx context.Context, owner, repo, sha string, opt *ListOptions) ([]*RepositoryComment, *Response, error) { +func (s *RepositoriesService) ListCommitComments(ctx context.Context, owner, repo, sha string, opts *ListOptions) ([]*RepositoryComment, *Response, error) { u := fmt.Sprintf("repos/%v/%v/commits/%v/comments", owner, repo, sha) - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } diff --git a/github/repos_commits.go b/github/repos_commits.go index f28ae9c6abe..a4ff2be4b9d 100644 --- a/github/repos_commits.go +++ b/github/repos_commits.go @@ -125,9 +125,9 @@ type BranchCommit struct { // ListCommits lists the commits of a repository. // // GitHub API docs: https://developer.github.com/v3/repos/commits/#list -func (s *RepositoriesService) ListCommits(ctx context.Context, owner, repo string, opt *CommitsListOptions) ([]*RepositoryCommit, *Response, error) { +func (s *RepositoriesService) ListCommits(ctx context.Context, owner, repo string, opts *CommitsListOptions) ([]*RepositoryCommit, *Response, error) { u := fmt.Sprintf("repos/%v/%v/commits", owner, repo) - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } @@ -168,20 +168,20 @@ func (s *RepositoriesService) GetCommit(ctx context.Context, owner, repo, sha st } // GetCommitRaw fetches the specified commit in raw (diff or patch) format. -func (s *RepositoriesService) GetCommitRaw(ctx context.Context, owner string, repo string, sha string, opt RawOptions) (string, *Response, error) { +func (s *RepositoriesService) GetCommitRaw(ctx context.Context, owner string, repo string, sha string, opts RawOptions) (string, *Response, error) { u := fmt.Sprintf("repos/%v/%v/commits/%v", owner, repo, sha) req, err := s.client.NewRequest("GET", u, nil) if err != nil { return "", nil, err } - switch opt.Type { + switch opts.Type { case Diff: req.Header.Set("Accept", mediaTypeV3Diff) case Patch: req.Header.Set("Accept", mediaTypeV3Patch) default: - return "", nil, fmt.Errorf("unsupported raw type %d", opt.Type) + return "", nil, fmt.Errorf("unsupported raw type %d", opts.Type) } var buf bytes.Buffer diff --git a/github/repos_contents.go b/github/repos_contents.go index 66b556d21b8..ede93e4f4b5 100644 --- a/github/repos_contents.go +++ b/github/repos_contents.go @@ -95,9 +95,9 @@ func (r *RepositoryContent) GetContent() (string, error) { // GetReadme gets the Readme file for the repository. // // GitHub API docs: https://developer.github.com/v3/repos/contents/#get-the-readme -func (s *RepositoriesService) GetReadme(ctx context.Context, owner, repo string, opt *RepositoryContentGetOptions) (*RepositoryContent, *Response, error) { +func (s *RepositoriesService) GetReadme(ctx context.Context, owner, repo string, opts *RepositoryContentGetOptions) (*RepositoryContent, *Response, error) { u := fmt.Sprintf("repos/%v/%v/readme", owner, repo) - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } @@ -117,10 +117,10 @@ func (s *RepositoriesService) GetReadme(ctx context.Context, owner, repo string, // specified file. This function will work with files of any size, as opposed // to GetContents which is limited to 1 Mb files. It is the caller's // responsibility to close the ReadCloser. -func (s *RepositoriesService) DownloadContents(ctx context.Context, owner, repo, filepath string, opt *RepositoryContentGetOptions) (io.ReadCloser, error) { +func (s *RepositoriesService) DownloadContents(ctx context.Context, owner, repo, filepath string, opts *RepositoryContentGetOptions) (io.ReadCloser, error) { dir := path.Dir(filepath) filename := path.Base(filepath) - _, dirContents, _, err := s.GetContents(ctx, owner, repo, dir, opt) + _, dirContents, _, err := s.GetContents(ctx, owner, repo, dir, opts) if err != nil { return nil, err } @@ -147,10 +147,10 @@ func (s *RepositoriesService) DownloadContents(ctx context.Context, owner, repo, // value and the other will be nil. // // GitHub API docs: https://developer.github.com/v3/repos/contents/#get-contents -func (s *RepositoriesService) GetContents(ctx context.Context, owner, repo, path string, opt *RepositoryContentGetOptions) (fileContent *RepositoryContent, directoryContent []*RepositoryContent, resp *Response, err error) { +func (s *RepositoriesService) GetContents(ctx context.Context, owner, repo, path string, opts *RepositoryContentGetOptions) (fileContent *RepositoryContent, directoryContent []*RepositoryContent, resp *Response, err error) { escapedPath := (&url.URL{Path: path}).String() u := fmt.Sprintf("repos/%s/%s/contents/%s", owner, repo, escapedPath) - u, err = addOptions(u, opt) + u, err = addOptions(u, opts) if err != nil { return nil, nil, nil, err } @@ -178,9 +178,9 @@ func (s *RepositoriesService) GetContents(ctx context.Context, owner, repo, path // the commit and file metadata. // // GitHub API docs: https://developer.github.com/v3/repos/contents/#create-a-file -func (s *RepositoriesService) CreateFile(ctx context.Context, owner, repo, path string, opt *RepositoryContentFileOptions) (*RepositoryContentResponse, *Response, error) { +func (s *RepositoriesService) CreateFile(ctx context.Context, owner, repo, path string, opts *RepositoryContentFileOptions) (*RepositoryContentResponse, *Response, error) { u := fmt.Sprintf("repos/%s/%s/contents/%s", owner, repo, path) - req, err := s.client.NewRequest("PUT", u, opt) + req, err := s.client.NewRequest("PUT", u, opts) if err != nil { return nil, nil, err } @@ -196,9 +196,9 @@ func (s *RepositoriesService) CreateFile(ctx context.Context, owner, repo, path // commit and file metadata. Requires the blob SHA of the file being updated. // // GitHub API docs: https://developer.github.com/v3/repos/contents/#update-a-file -func (s *RepositoriesService) UpdateFile(ctx context.Context, owner, repo, path string, opt *RepositoryContentFileOptions) (*RepositoryContentResponse, *Response, error) { +func (s *RepositoriesService) UpdateFile(ctx context.Context, owner, repo, path string, opts *RepositoryContentFileOptions) (*RepositoryContentResponse, *Response, error) { u := fmt.Sprintf("repos/%s/%s/contents/%s", owner, repo, path) - req, err := s.client.NewRequest("PUT", u, opt) + req, err := s.client.NewRequest("PUT", u, opts) if err != nil { return nil, nil, err } @@ -214,9 +214,9 @@ func (s *RepositoriesService) UpdateFile(ctx context.Context, owner, repo, path // Requires the blob SHA of the file to be deleted. // // GitHub API docs: https://developer.github.com/v3/repos/contents/#delete-a-file -func (s *RepositoriesService) DeleteFile(ctx context.Context, owner, repo, path string, opt *RepositoryContentFileOptions) (*RepositoryContentResponse, *Response, error) { +func (s *RepositoriesService) DeleteFile(ctx context.Context, owner, repo, path string, opts *RepositoryContentFileOptions) (*RepositoryContentResponse, *Response, error) { u := fmt.Sprintf("repos/%s/%s/contents/%s", owner, repo, path) - req, err := s.client.NewRequest("DELETE", u, opt) + req, err := s.client.NewRequest("DELETE", u, opts) if err != nil { return nil, nil, err } @@ -244,10 +244,10 @@ const ( // or github.Zipball constant. // // GitHub API docs: https://developer.github.com/v3/repos/contents/#get-archive-link -func (s *RepositoriesService) GetArchiveLink(ctx context.Context, owner, repo string, archiveformat archiveFormat, opt *RepositoryContentGetOptions, followRedirects bool) (*url.URL, *Response, error) { +func (s *RepositoriesService) GetArchiveLink(ctx context.Context, owner, repo string, archiveformat archiveFormat, opts *RepositoryContentGetOptions, followRedirects bool) (*url.URL, *Response, error) { u := fmt.Sprintf("repos/%s/%s/%s", owner, repo, archiveformat) - if opt != nil && opt.Ref != "" { - u += fmt.Sprintf("/%s", opt.Ref) + if opts != nil && opts.Ref != "" { + u += fmt.Sprintf("/%s", opts.Ref) } resp, err := s.getArchiveLinkFromURL(ctx, u, followRedirects) if err != nil { diff --git a/github/repos_deployments.go b/github/repos_deployments.go index 6453345e042..ace1778e9eb 100644 --- a/github/repos_deployments.go +++ b/github/repos_deployments.go @@ -64,9 +64,9 @@ type DeploymentsListOptions struct { // ListDeployments lists the deployments of a repository. // // GitHub API docs: https://developer.github.com/v3/repos/deployments/#list-deployments -func (s *RepositoriesService) ListDeployments(ctx context.Context, owner, repo string, opt *DeploymentsListOptions) ([]*Deployment, *Response, error) { +func (s *RepositoriesService) ListDeployments(ctx context.Context, owner, repo string, opts *DeploymentsListOptions) ([]*Deployment, *Response, error) { u := fmt.Sprintf("repos/%v/%v/deployments", owner, repo) - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } @@ -159,9 +159,9 @@ type DeploymentStatusRequest struct { // ListDeploymentStatuses lists the statuses of a given deployment of a repository. // // GitHub API docs: https://developer.github.com/v3/repos/deployments/#list-deployment-statuses -func (s *RepositoriesService) ListDeploymentStatuses(ctx context.Context, owner, repo string, deployment int64, opt *ListOptions) ([]*DeploymentStatus, *Response, error) { +func (s *RepositoriesService) ListDeploymentStatuses(ctx context.Context, owner, repo string, deployment int64, opts *ListOptions) ([]*DeploymentStatus, *Response, error) { u := fmt.Sprintf("repos/%v/%v/deployments/%v/statuses", owner, repo, deployment) - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } diff --git a/github/repos_forks.go b/github/repos_forks.go index bfff27bb951..5973587dd50 100644 --- a/github/repos_forks.go +++ b/github/repos_forks.go @@ -25,9 +25,9 @@ type RepositoryListForksOptions struct { // ListForks lists the forks of the specified repository. // // GitHub API docs: https://developer.github.com/v3/repos/forks/#list-forks -func (s *RepositoriesService) ListForks(ctx context.Context, owner, repo string, opt *RepositoryListForksOptions) ([]*Repository, *Response, error) { +func (s *RepositoriesService) ListForks(ctx context.Context, owner, repo string, opts *RepositoryListForksOptions) ([]*Repository, *Response, error) { u := fmt.Sprintf("repos/%v/%v/forks", owner, repo) - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } @@ -66,9 +66,9 @@ type RepositoryCreateForkOptions struct { // in a successful request. // // GitHub API docs: https://developer.github.com/v3/repos/forks/#create-a-fork -func (s *RepositoriesService) CreateFork(ctx context.Context, owner, repo string, opt *RepositoryCreateForkOptions) (*Repository, *Response, error) { +func (s *RepositoriesService) CreateFork(ctx context.Context, owner, repo string, opts *RepositoryCreateForkOptions) (*Repository, *Response, error) { u := fmt.Sprintf("repos/%v/%v/forks", owner, repo) - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } diff --git a/github/repos_hooks.go b/github/repos_hooks.go index 7674947df32..86728223844 100644 --- a/github/repos_hooks.go +++ b/github/repos_hooks.go @@ -132,9 +132,9 @@ func (s *RepositoriesService) CreateHook(ctx context.Context, owner, repo string // ListHooks lists all Hooks for the specified repository. // // GitHub API docs: https://developer.github.com/v3/repos/hooks/#list -func (s *RepositoriesService) ListHooks(ctx context.Context, owner, repo string, opt *ListOptions) ([]*Hook, *Response, error) { +func (s *RepositoriesService) ListHooks(ctx context.Context, owner, repo string, opts *ListOptions) ([]*Hook, *Response, error) { u := fmt.Sprintf("repos/%v/%v/hooks", owner, repo) - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } diff --git a/github/repos_invitations.go b/github/repos_invitations.go index b88e9359f3e..6e76f2d579d 100644 --- a/github/repos_invitations.go +++ b/github/repos_invitations.go @@ -28,9 +28,9 @@ type RepositoryInvitation struct { // ListInvitations lists all currently-open repository invitations. // // GitHub API docs: https://developer.github.com/v3/repos/invitations/#list-invitations-for-a-repository -func (s *RepositoriesService) ListInvitations(ctx context.Context, owner, repo string, opt *ListOptions) ([]*RepositoryInvitation, *Response, error) { +func (s *RepositoriesService) ListInvitations(ctx context.Context, owner, repo string, opts *ListOptions) ([]*RepositoryInvitation, *Response, error) { u := fmt.Sprintf("repos/%v/%v/invitations", owner, repo) - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } diff --git a/github/repos_keys.go b/github/repos_keys.go index b484f844463..64ee7422a07 100644 --- a/github/repos_keys.go +++ b/github/repos_keys.go @@ -15,9 +15,9 @@ import ( // ListKeys lists the deploy keys for a repository. // // GitHub API docs: https://developer.github.com/v3/repos/keys/#list -func (s *RepositoriesService) ListKeys(ctx context.Context, owner string, repo string, opt *ListOptions) ([]*Key, *Response, error) { +func (s *RepositoriesService) ListKeys(ctx context.Context, owner string, repo string, opts *ListOptions) ([]*Key, *Response, error) { u := fmt.Sprintf("repos/%v/%v/keys", owner, repo) - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } diff --git a/github/repos_pages.go b/github/repos_pages.go index c0892fdc7de..ff8d2d55b9c 100644 --- a/github/repos_pages.go +++ b/github/repos_pages.go @@ -113,9 +113,9 @@ func (s *RepositoriesService) GetPagesInfo(ctx context.Context, owner, repo stri // ListPagesBuilds lists the builds for a GitHub Pages site. // // GitHub API docs: https://developer.github.com/v3/repos/pages/#list-pages-builds -func (s *RepositoriesService) ListPagesBuilds(ctx context.Context, owner, repo string, opt *ListOptions) ([]*PagesBuild, *Response, error) { +func (s *RepositoriesService) ListPagesBuilds(ctx context.Context, owner, repo string, opts *ListOptions) ([]*PagesBuild, *Response, error) { u := fmt.Sprintf("repos/%v/%v/pages/builds", owner, repo) - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } diff --git a/github/repos_prereceive_hooks.go b/github/repos_prereceive_hooks.go index cab09f74791..1ce6478d33b 100644 --- a/github/repos_prereceive_hooks.go +++ b/github/repos_prereceive_hooks.go @@ -25,9 +25,9 @@ func (p PreReceiveHook) String() string { // ListPreReceiveHooks lists all pre-receive hooks for the specified repository. // // GitHub API docs: https://developer.github.com/enterprise/2.13/v3/repos/pre_receive_hooks/#list-pre-receive-hooks -func (s *RepositoriesService) ListPreReceiveHooks(ctx context.Context, owner, repo string, opt *ListOptions) ([]*PreReceiveHook, *Response, error) { +func (s *RepositoriesService) ListPreReceiveHooks(ctx context.Context, owner, repo string, opts *ListOptions) ([]*PreReceiveHook, *Response, error) { u := fmt.Sprintf("repos/%v/%v/pre-receive-hooks", owner, repo) - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } diff --git a/github/repos_projects.go b/github/repos_projects.go index d6486d293c8..442f5232a39 100644 --- a/github/repos_projects.go +++ b/github/repos_projects.go @@ -22,9 +22,9 @@ type ProjectListOptions struct { // ListProjects lists the projects for a repo. // // GitHub API docs: https://developer.github.com/v3/projects/#list-repository-projects -func (s *RepositoriesService) ListProjects(ctx context.Context, owner, repo string, opt *ProjectListOptions) ([]*Project, *Response, error) { +func (s *RepositoriesService) ListProjects(ctx context.Context, owner, repo string, opts *ProjectListOptions) ([]*Project, *Response, error) { u := fmt.Sprintf("repos/%v/%v/projects", owner, repo) - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } @@ -49,9 +49,9 @@ func (s *RepositoriesService) ListProjects(ctx context.Context, owner, repo stri // CreateProject creates a GitHub Project for the specified repository. // // GitHub API docs: https://developer.github.com/v3/projects/#create-a-repository-project -func (s *RepositoriesService) CreateProject(ctx context.Context, owner, repo string, opt *ProjectOptions) (*Project, *Response, error) { +func (s *RepositoriesService) CreateProject(ctx context.Context, owner, repo string, opts *ProjectOptions) (*Project, *Response, error) { u := fmt.Sprintf("repos/%v/%v/projects", owner, repo) - req, err := s.client.NewRequest("POST", u, opt) + req, err := s.client.NewRequest("POST", u, opts) if err != nil { return nil, nil, err } diff --git a/github/repos_releases.go b/github/repos_releases.go index 0a43457263e..645f980a535 100644 --- a/github/repos_releases.go +++ b/github/repos_releases.go @@ -69,9 +69,9 @@ func (r ReleaseAsset) String() string { // ListReleases lists the releases for a repository. // // GitHub API docs: https://developer.github.com/v3/repos/releases/#list-releases-for-a-repository -func (s *RepositoriesService) ListReleases(ctx context.Context, owner, repo string, opt *ListOptions) ([]*RepositoryRelease, *Response, error) { +func (s *RepositoriesService) ListReleases(ctx context.Context, owner, repo string, opts *ListOptions) ([]*RepositoryRelease, *Response, error) { u := fmt.Sprintf("repos/%s/%s/releases", owner, repo) - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } @@ -220,9 +220,9 @@ func (s *RepositoriesService) DeleteRelease(ctx context.Context, owner, repo str // ListReleaseAssets lists the release's assets. // // GitHub API docs: https://developer.github.com/v3/repos/releases/#list-assets-for-a-release -func (s *RepositoriesService) ListReleaseAssets(ctx context.Context, owner, repo string, id int64, opt *ListOptions) ([]*ReleaseAsset, *Response, error) { +func (s *RepositoriesService) ListReleaseAssets(ctx context.Context, owner, repo string, id int64, opts *ListOptions) ([]*ReleaseAsset, *Response, error) { u := fmt.Sprintf("repos/%s/%s/releases/%d/assets", owner, repo, id) - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } @@ -367,9 +367,9 @@ func (s *RepositoriesService) DeleteReleaseAsset(ctx context.Context, owner, rep // To upload assets that cannot be represented by an os.File, call NewUploadRequest directly. // // GitHub API docs: https://developer.github.com/v3/repos/releases/#upload-a-release-asset -func (s *RepositoriesService) UploadReleaseAsset(ctx context.Context, owner, repo string, id int64, opt *UploadOptions, file *os.File) (*ReleaseAsset, *Response, error) { +func (s *RepositoriesService) UploadReleaseAsset(ctx context.Context, owner, repo string, id int64, opts *UploadOptions, file *os.File) (*ReleaseAsset, *Response, error) { u := fmt.Sprintf("repos/%s/%s/releases/%d/assets", owner, repo, id) - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } @@ -383,8 +383,8 @@ func (s *RepositoriesService) UploadReleaseAsset(ctx context.Context, owner, rep } mediaType := mime.TypeByExtension(filepath.Ext(file.Name())) - if opt.MediaType != "" { - mediaType = opt.MediaType + if opts.MediaType != "" { + mediaType = opts.MediaType } req, err := s.client.NewUploadRequest(u, file, stat.Size(), mediaType) diff --git a/github/repos_statuses.go b/github/repos_statuses.go index 6d6a0d2fe4e..5543265880c 100644 --- a/github/repos_statuses.go +++ b/github/repos_statuses.go @@ -45,9 +45,9 @@ func (r RepoStatus) String() string { // reference. ref can be a SHA, a branch name, or a tag name. // // GitHub API docs: https://developer.github.com/v3/repos/statuses/#list-statuses-for-a-specific-ref -func (s *RepositoriesService) ListStatuses(ctx context.Context, owner, repo, ref string, opt *ListOptions) ([]*RepoStatus, *Response, error) { +func (s *RepositoriesService) ListStatuses(ctx context.Context, owner, repo, ref string, opts *ListOptions) ([]*RepoStatus, *Response, error) { u := fmt.Sprintf("repos/%v/%v/commits/%v/statuses", owner, repo, url.QueryEscape(ref)) - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } @@ -109,9 +109,9 @@ func (s CombinedStatus) String() string { // reference. ref can be a SHA, a branch name, or a tag name. // // GitHub API docs: https://developer.github.com/v3/repos/statuses/#get-the-combined-status-for-a-specific-ref -func (s *RepositoriesService) GetCombinedStatus(ctx context.Context, owner, repo, ref string, opt *ListOptions) (*CombinedStatus, *Response, error) { +func (s *RepositoriesService) GetCombinedStatus(ctx context.Context, owner, repo, ref string, opts *ListOptions) (*CombinedStatus, *Response, error) { u := fmt.Sprintf("repos/%v/%v/commits/%v/status", owner, repo, url.QueryEscape(ref)) - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } diff --git a/github/repos_traffic.go b/github/repos_traffic.go index fb1c97648a7..e7ee18849a5 100644 --- a/github/repos_traffic.go +++ b/github/repos_traffic.go @@ -95,9 +95,9 @@ func (s *RepositoriesService) ListTrafficPaths(ctx context.Context, owner, repo // ListTrafficViews get total number of views for the last 14 days and breaks it down either per day or week. // // GitHub API docs: https://developer.github.com/v3/repos/traffic/#views -func (s *RepositoriesService) ListTrafficViews(ctx context.Context, owner, repo string, opt *TrafficBreakdownOptions) (*TrafficViews, *Response, error) { +func (s *RepositoriesService) ListTrafficViews(ctx context.Context, owner, repo string, opts *TrafficBreakdownOptions) (*TrafficViews, *Response, error) { u := fmt.Sprintf("repos/%v/%v/traffic/views", owner, repo) - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } @@ -119,9 +119,9 @@ func (s *RepositoriesService) ListTrafficViews(ctx context.Context, owner, repo // ListTrafficClones get total number of clones for the last 14 days and breaks it down either per day or week for the last 14 days. // // GitHub API docs: https://developer.github.com/v3/repos/traffic/#views -func (s *RepositoriesService) ListTrafficClones(ctx context.Context, owner, repo string, opt *TrafficBreakdownOptions) (*TrafficClones, *Response, error) { +func (s *RepositoriesService) ListTrafficClones(ctx context.Context, owner, repo string, opts *TrafficBreakdownOptions) (*TrafficClones, *Response, error) { u := fmt.Sprintf("repos/%v/%v/traffic/clones", owner, repo) - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } diff --git a/github/search.go b/github/search.go index d294a4f06ee..80587a3e76b 100644 --- a/github/search.go +++ b/github/search.go @@ -70,9 +70,9 @@ type RepositoriesSearchResult struct { // Repositories searches repositories via various criteria. // // GitHub API docs: https://developer.github.com/v3/search/#search-repositories -func (s *SearchService) Repositories(ctx context.Context, query string, opt *SearchOptions) (*RepositoriesSearchResult, *Response, error) { +func (s *SearchService) Repositories(ctx context.Context, query string, opts *SearchOptions) (*RepositoriesSearchResult, *Response, error) { result := new(RepositoriesSearchResult) - resp, err := s.search(ctx, "repositories", &searchParameters{Query: query}, opt, result) + resp, err := s.search(ctx, "repositories", &searchParameters{Query: query}, opts, result) return result, resp, err } @@ -101,9 +101,9 @@ type TopicResult struct { // information about search qualifiers. // // GitHub API docs: https://developer.github.com/v3/search/#search-topics -func (s *SearchService) Topics(ctx context.Context, query string, opt *SearchOptions) (*TopicsSearchResult, *Response, error) { +func (s *SearchService) Topics(ctx context.Context, query string, opts *SearchOptions) (*TopicsSearchResult, *Response, error) { result := new(TopicsSearchResult) - resp, err := s.search(ctx, "topics", &searchParameters{Query: query}, opt, result) + resp, err := s.search(ctx, "topics", &searchParameters{Query: query}, opts, result) return result, resp, err } @@ -132,9 +132,9 @@ type CommitResult struct { // Commits searches commits via various criteria. // // GitHub API docs: https://developer.github.com/v3/search/#search-commits -func (s *SearchService) Commits(ctx context.Context, query string, opt *SearchOptions) (*CommitsSearchResult, *Response, error) { +func (s *SearchService) Commits(ctx context.Context, query string, opts *SearchOptions) (*CommitsSearchResult, *Response, error) { result := new(CommitsSearchResult) - resp, err := s.search(ctx, "commits", &searchParameters{Query: query}, opt, result) + resp, err := s.search(ctx, "commits", &searchParameters{Query: query}, opts, result) return result, resp, err } @@ -148,9 +148,9 @@ type IssuesSearchResult struct { // Issues searches issues via various criteria. // // GitHub API docs: https://developer.github.com/v3/search/#search-issues -func (s *SearchService) Issues(ctx context.Context, query string, opt *SearchOptions) (*IssuesSearchResult, *Response, error) { +func (s *SearchService) Issues(ctx context.Context, query string, opts *SearchOptions) (*IssuesSearchResult, *Response, error) { result := new(IssuesSearchResult) - resp, err := s.search(ctx, "issues", &searchParameters{Query: query}, opt, result) + resp, err := s.search(ctx, "issues", &searchParameters{Query: query}, opts, result) return result, resp, err } @@ -164,9 +164,9 @@ type UsersSearchResult struct { // Users searches users via various criteria. // // GitHub API docs: https://developer.github.com/v3/search/#search-users -func (s *SearchService) Users(ctx context.Context, query string, opt *SearchOptions) (*UsersSearchResult, *Response, error) { +func (s *SearchService) Users(ctx context.Context, query string, opts *SearchOptions) (*UsersSearchResult, *Response, error) { result := new(UsersSearchResult) - resp, err := s.search(ctx, "users", &searchParameters{Query: query}, opt, result) + resp, err := s.search(ctx, "users", &searchParameters{Query: query}, opts, result) return result, resp, err } @@ -213,9 +213,9 @@ func (c CodeResult) String() string { // Code searches code via various criteria. // // GitHub API docs: https://developer.github.com/v3/search/#search-code -func (s *SearchService) Code(ctx context.Context, query string, opt *SearchOptions) (*CodeSearchResult, *Response, error) { +func (s *SearchService) Code(ctx context.Context, query string, opts *SearchOptions) (*CodeSearchResult, *Response, error) { result := new(CodeSearchResult) - resp, err := s.search(ctx, "code", &searchParameters{Query: query}, opt, result) + resp, err := s.search(ctx, "code", &searchParameters{Query: query}, opts, result) return result, resp, err } @@ -244,9 +244,9 @@ func (l LabelResult) String() string { // Labels searches labels in the repository with ID repoID via various criteria. // // GitHub API docs: https://developer.github.com/v3/search/#search-labels -func (s *SearchService) Labels(ctx context.Context, repoID int64, query string, opt *SearchOptions) (*LabelsSearchResult, *Response, error) { +func (s *SearchService) Labels(ctx context.Context, repoID int64, query string, opts *SearchOptions) (*LabelsSearchResult, *Response, error) { result := new(LabelsSearchResult) - resp, err := s.search(ctx, "labels", &searchParameters{RepositoryID: &repoID, Query: query}, opt, result) + resp, err := s.search(ctx, "labels", &searchParameters{RepositoryID: &repoID, Query: query}, opts, result) return result, resp, err } @@ -255,8 +255,8 @@ func (s *SearchService) Labels(ctx context.Context, repoID int64, query string, // // If searchParameters.Query includes multiple condition, it MUST NOT include "+" as condition separator. // For example, querying with "language:c++" and "leveldb", then searchParameters.Query should be "language:c++ leveldb" but not "language:c+++leveldb". -func (s *SearchService) search(ctx context.Context, searchType string, parameters *searchParameters, opt *SearchOptions, result interface{}) (*Response, error) { - params, err := qs.Values(opt) +func (s *SearchService) search(ctx context.Context, searchType string, parameters *searchParameters, opts *SearchOptions, result interface{}) (*Response, error) { + params, err := qs.Values(opts) if err != nil { return nil, err } @@ -284,7 +284,7 @@ func (s *SearchService) search(ctx context.Context, searchType string, parameter // Accept header for search repositories based on topics preview endpoint // TODO: remove custom Accept header when this API fully launches. req.Header.Set("Accept", mediaTypeTopicsPreview) - case opt != nil && opt.TextMatch: + case opts != nil && opts.TextMatch: // Accept header defaults to "application/vnd.github.v3+json" // We change it here to fetch back text-match metadata req.Header.Set("Accept", "application/vnd.github.v3.text-match+json") diff --git a/github/teams.go b/github/teams.go index 03284874466..1f86ef9654f 100644 --- a/github/teams.go +++ b/github/teams.go @@ -76,9 +76,9 @@ func (i Invitation) String() string { // ListTeams lists all of the teams for an organization. // // GitHub API docs: https://developer.github.com/v3/teams/#list-teams -func (s *TeamsService) ListTeams(ctx context.Context, org string, opt *ListOptions) ([]*Team, *Response, error) { +func (s *TeamsService) ListTeams(ctx context.Context, org string, opts *ListOptions) ([]*Team, *Response, error) { u := fmt.Sprintf("orgs/%v/teams", org) - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } @@ -255,9 +255,9 @@ func (s *TeamsService) DeleteTeam(ctx context.Context, team int64) (*Response, e // ListChildTeams lists child teams for a team. // // GitHub API docs: https://developer.github.com/v3/teams/#list-child-teams -func (s *TeamsService) ListChildTeams(ctx context.Context, teamID int64, opt *ListOptions) ([]*Team, *Response, error) { +func (s *TeamsService) ListChildTeams(ctx context.Context, teamID int64, opts *ListOptions) ([]*Team, *Response, error) { u := fmt.Sprintf("teams/%v/teams", teamID) - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } @@ -279,9 +279,9 @@ func (s *TeamsService) ListChildTeams(ctx context.Context, teamID int64, opt *Li // ListTeamRepos lists the repositories that the specified team has access to. // // GitHub API docs: https://developer.github.com/v3/teams/#list-team-repos -func (s *TeamsService) ListTeamRepos(ctx context.Context, team int64, opt *ListOptions) ([]*Repository, *Response, error) { +func (s *TeamsService) ListTeamRepos(ctx context.Context, team int64, opts *ListOptions) ([]*Repository, *Response, error) { u := fmt.Sprintf("teams/%v/repos", team) - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } @@ -346,9 +346,9 @@ type TeamAddTeamRepoOptions struct { // belongs, or a direct fork of a repository owned by the organization. // // GitHub API docs: https://developer.github.com/v3/teams/#add-team-repo -func (s *TeamsService) AddTeamRepo(ctx context.Context, team int64, owner string, repo string, opt *TeamAddTeamRepoOptions) (*Response, error) { +func (s *TeamsService) AddTeamRepo(ctx context.Context, team int64, owner string, repo string, opts *TeamAddTeamRepoOptions) (*Response, error) { u := fmt.Sprintf("teams/%v/repos/%v/%v", team, owner, repo) - req, err := s.client.NewRequest("PUT", u, opt) + req, err := s.client.NewRequest("PUT", u, opts) if err != nil { return nil, err } @@ -373,9 +373,9 @@ func (s *TeamsService) RemoveTeamRepo(ctx context.Context, team int64, owner str // ListUserTeams lists a user's teams // GitHub API docs: https://developer.github.com/v3/teams/#list-user-teams -func (s *TeamsService) ListUserTeams(ctx context.Context, opt *ListOptions) ([]*Team, *Response, error) { +func (s *TeamsService) ListUserTeams(ctx context.Context, opts *ListOptions) ([]*Team, *Response, error) { u := "user/teams" - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } @@ -459,9 +459,9 @@ type TeamProjectOptions struct { // permissions for the project. // // GitHub API docs: https://developer.github.com/v3/teams/#add-or-update-team-project -func (s *TeamsService) AddTeamProject(ctx context.Context, teamID, projectID int64, opt *TeamProjectOptions) (*Response, error) { +func (s *TeamsService) AddTeamProject(ctx context.Context, teamID, projectID int64, opts *TeamProjectOptions) (*Response, error) { u := fmt.Sprintf("teams/%v/projects/%v", teamID, projectID) - req, err := s.client.NewRequest("PUT", u, opt) + req, err := s.client.NewRequest("PUT", u, opts) if err != nil { return nil, err } @@ -509,9 +509,9 @@ type IDPGroup struct { // ListIDPGroupsInOrganization lists IDP groups available in an organization. // // GitHub API docs: https://developer.github.com/v3/teams/team_sync/#list-idp-groups-in-an-organization -func (s *TeamsService) ListIDPGroupsInOrganization(ctx context.Context, org string, opt *ListCursorOptions) (*IDPGroupList, *Response, error) { +func (s *TeamsService) ListIDPGroupsInOrganization(ctx context.Context, org string, opts *ListCursorOptions) (*IDPGroupList, *Response, error) { u := fmt.Sprintf("orgs/%v/team-sync/groups", org) - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } @@ -552,10 +552,10 @@ func (s *TeamsService) ListIDPGroupsForTeam(ctx context.Context, teamID string) // and an IDP group. // // GitHub API docs: https://developer.github.com/v3/teams/team_sync/#create-or-update-idp-group-connections -func (s *TeamsService) CreateOrUpdateIDPGroupConnections(ctx context.Context, teamID string, opt IDPGroupList) (*IDPGroupList, *Response, error) { +func (s *TeamsService) CreateOrUpdateIDPGroupConnections(ctx context.Context, teamID string, opts IDPGroupList) (*IDPGroupList, *Response, error) { u := fmt.Sprintf("teams/%v/team-sync/group-mappings", teamID) - req, err := s.client.NewRequest("PATCH", u, opt) + req, err := s.client.NewRequest("PATCH", u, opts) if err != nil { return nil, nil, err } diff --git a/github/teams_members.go b/github/teams_members.go index 2a211fe9072..36ca74353b2 100644 --- a/github/teams_members.go +++ b/github/teams_members.go @@ -24,9 +24,9 @@ type TeamListTeamMembersOptions struct { // team. // // GitHub API docs: https://developer.github.com/v3/teams/members/#list-team-members -func (s *TeamsService) ListTeamMembers(ctx context.Context, team int64, opt *TeamListTeamMembersOptions) ([]*User, *Response, error) { +func (s *TeamsService) ListTeamMembers(ctx context.Context, team int64, opts *TeamListTeamMembersOptions) ([]*User, *Response, error) { u := fmt.Sprintf("teams/%v/members", team) - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } @@ -114,9 +114,9 @@ type TeamAddTeamMembershipOptions struct { // added as a member of the team. // // GitHub API docs: https://developer.github.com/v3/teams/members/#add-or-update-team-membership -func (s *TeamsService) AddTeamMembership(ctx context.Context, team int64, user string, opt *TeamAddTeamMembershipOptions) (*Membership, *Response, error) { +func (s *TeamsService) AddTeamMembership(ctx context.Context, team int64, user string, opts *TeamAddTeamMembershipOptions) (*Membership, *Response, error) { u := fmt.Sprintf("teams/%v/memberships/%v", team, user) - req, err := s.client.NewRequest("PUT", u, opt) + req, err := s.client.NewRequest("PUT", u, opts) if err != nil { return nil, nil, err } @@ -148,9 +148,9 @@ func (s *TeamsService) RemoveTeamMembership(ctx context.Context, team int64, use // Preview features are not supported for production use. // // GitHub API docs: https://developer.github.com/v3/teams/members/#list-pending-team-invitations -func (s *TeamsService) ListPendingTeamInvitations(ctx context.Context, team int64, opt *ListOptions) ([]*Invitation, *Response, error) { +func (s *TeamsService) ListPendingTeamInvitations(ctx context.Context, team int64, opts *ListOptions) ([]*Invitation, *Response, error) { u := fmt.Sprintf("teams/%v/invitations", team) - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } diff --git a/github/users.go b/github/users.go index 88a15bdb761..f7c77c61d87 100644 --- a/github/users.go +++ b/github/users.go @@ -164,9 +164,9 @@ type UserContext struct { // via Basic Auth or via OAuth with the repo scope. // // GitHub API docs: https://developer.github.com/v3/users/#get-contextual-information-about-a-user -func (s *UsersService) GetHovercard(ctx context.Context, user string, opt *HovercardOptions) (*Hovercard, *Response, error) { +func (s *UsersService) GetHovercard(ctx context.Context, user string, opts *HovercardOptions) (*Hovercard, *Response, error) { u := fmt.Sprintf("users/%v/hovercard", user) - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } @@ -202,8 +202,8 @@ type UserListOptions struct { // To paginate through all users, populate 'Since' with the ID of the last user. // // GitHub API docs: https://developer.github.com/v3/users/#get-all-users -func (s *UsersService) ListAll(ctx context.Context, opt *UserListOptions) ([]*User, *Response, error) { - u, err := addOptions("users", opt) +func (s *UsersService) ListAll(ctx context.Context, opts *UserListOptions) ([]*User, *Response, error) { + u, err := addOptions("users", opts) if err != nil { return nil, nil, err } @@ -226,8 +226,8 @@ func (s *UsersService) ListAll(ctx context.Context, opt *UserListOptions) ([]*Us // authenticated user. // // GitHub API docs: https://developer.github.com/v3/repos/invitations/#list-a-users-repository-invitations -func (s *UsersService) ListInvitations(ctx context.Context, opt *ListOptions) ([]*RepositoryInvitation, *Response, error) { - u, err := addOptions("user/repository_invitations", opt) +func (s *UsersService) ListInvitations(ctx context.Context, opts *ListOptions) ([]*RepositoryInvitation, *Response, error) { + u, err := addOptions("user/repository_invitations", opts) if err != nil { return nil, nil, err } diff --git a/github/users_administration.go b/github/users_administration.go index 1c483a7b17a..aef947ec451 100644 --- a/github/users_administration.go +++ b/github/users_administration.go @@ -46,10 +46,10 @@ type UserSuspendOptions struct { // Suspend a user on a GitHub Enterprise instance. // // GitHub API docs: https://developer.github.com/enterprise/v3/enterprise-admin/users/#suspend-a-user -func (s *UsersService) Suspend(ctx context.Context, user string, opt *UserSuspendOptions) (*Response, error) { +func (s *UsersService) Suspend(ctx context.Context, user string, opts *UserSuspendOptions) (*Response, error) { u := fmt.Sprintf("users/%v/suspended", user) - req, err := s.client.NewRequest("PUT", u, opt) + req, err := s.client.NewRequest("PUT", u, opts) if err != nil { return nil, err } diff --git a/github/users_blocking.go b/github/users_blocking.go index 39e45601cc1..c60bfdbcd5a 100644 --- a/github/users_blocking.go +++ b/github/users_blocking.go @@ -13,9 +13,9 @@ import ( // ListBlockedUsers lists all the blocked users by the authenticated user. // // GitHub API docs: https://developer.github.com/v3/users/blocking/#list-blocked-users -func (s *UsersService) ListBlockedUsers(ctx context.Context, opt *ListOptions) ([]*User, *Response, error) { +func (s *UsersService) ListBlockedUsers(ctx context.Context, opts *ListOptions) ([]*User, *Response, error) { u := "user/blocks" - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } diff --git a/github/users_emails.go b/github/users_emails.go index 78d21491191..bf02d1a6102 100644 --- a/github/users_emails.go +++ b/github/users_emails.go @@ -18,9 +18,9 @@ type UserEmail struct { // ListEmails lists all email addresses for the authenticated user. // // GitHub API docs: https://developer.github.com/v3/users/emails/#list-email-addresses-for-a-user -func (s *UsersService) ListEmails(ctx context.Context, opt *ListOptions) ([]*UserEmail, *Response, error) { +func (s *UsersService) ListEmails(ctx context.Context, opts *ListOptions) ([]*UserEmail, *Response, error) { u := "user/emails" - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } diff --git a/github/users_followers.go b/github/users_followers.go index c2224096a62..afa7d4b6b71 100644 --- a/github/users_followers.go +++ b/github/users_followers.go @@ -14,14 +14,14 @@ import ( // fetch followers for the authenticated user. // // GitHub API docs: https://developer.github.com/v3/users/followers/#list-followers-of-a-user -func (s *UsersService) ListFollowers(ctx context.Context, user string, opt *ListOptions) ([]*User, *Response, error) { +func (s *UsersService) ListFollowers(ctx context.Context, user string, opts *ListOptions) ([]*User, *Response, error) { var u string if user != "" { u = fmt.Sprintf("users/%v/followers", user) } else { u = "user/followers" } - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } @@ -44,14 +44,14 @@ func (s *UsersService) ListFollowers(ctx context.Context, user string, opt *List // string will list people the authenticated user is following. // // GitHub API docs: https://developer.github.com/v3/users/followers/#list-users-followed-by-another-user -func (s *UsersService) ListFollowing(ctx context.Context, user string, opt *ListOptions) ([]*User, *Response, error) { +func (s *UsersService) ListFollowing(ctx context.Context, user string, opts *ListOptions) ([]*User, *Response, error) { var u string if user != "" { u = fmt.Sprintf("users/%v/following", user) } else { u = "user/following" } - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } diff --git a/github/users_gpg_keys.go b/github/users_gpg_keys.go index 07ed38dcbef..42638eb541c 100644 --- a/github/users_gpg_keys.go +++ b/github/users_gpg_keys.go @@ -45,14 +45,14 @@ type GPGEmail struct { // via Basic Auth or via OAuth with at least read:gpg_key scope. // // GitHub API docs: https://developer.github.com/v3/users/gpg_keys/#list-gpg-keys-for-a-user -func (s *UsersService) ListGPGKeys(ctx context.Context, user string, opt *ListOptions) ([]*GPGKey, *Response, error) { +func (s *UsersService) ListGPGKeys(ctx context.Context, user string, opts *ListOptions) ([]*GPGKey, *Response, error) { var u string if user != "" { u = fmt.Sprintf("users/%v/gpg_keys", user) } else { u = "user/gpg_keys" } - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } diff --git a/github/users_keys.go b/github/users_keys.go index 39a4f54d6c2..f12c01b9b07 100644 --- a/github/users_keys.go +++ b/github/users_keys.go @@ -28,14 +28,14 @@ func (k Key) String() string { // string will fetch keys for the authenticated user. // // GitHub API docs: https://developer.github.com/v3/users/keys/#list-public-keys-for-a-user -func (s *UsersService) ListKeys(ctx context.Context, user string, opt *ListOptions) ([]*Key, *Response, error) { +func (s *UsersService) ListKeys(ctx context.Context, user string, opts *ListOptions) ([]*Key, *Response, error) { var u string if user != "" { u = fmt.Sprintf("users/%v/keys", user) } else { u = "user/keys" } - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } diff --git a/github/users_projects.go b/github/users_projects.go index bd2ca75e1f0..64e85a03226 100644 --- a/github/users_projects.go +++ b/github/users_projects.go @@ -13,9 +13,9 @@ import ( // ListProjects lists the projects for the specified user. // // GitHub API docs: https://developer.github.com/v3/projects/#list-user-projects -func (s *UsersService) ListProjects(ctx context.Context, user string, opt *ProjectListOptions) ([]*Project, *Response, error) { +func (s *UsersService) ListProjects(ctx context.Context, user string, opts *ProjectListOptions) ([]*Project, *Response, error) { u := fmt.Sprintf("users/%v/projects", user) - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } @@ -48,9 +48,9 @@ type CreateUserProjectOptions struct { // CreateProject creates a GitHub Project for the current user. // // GitHub API docs: https://developer.github.com/v3/projects/#create-a-user-project -func (s *UsersService) CreateProject(ctx context.Context, opt *CreateUserProjectOptions) (*Project, *Response, error) { +func (s *UsersService) CreateProject(ctx context.Context, opts *CreateUserProjectOptions) (*Project, *Response, error) { u := "users/projects" - req, err := s.client.NewRequest("POST", u, opt) + req, err := s.client.NewRequest("POST", u, opts) if err != nil { return nil, nil, err } From 7d28d53999240c3f92dfbc40651e970301b9989a Mon Sep 17 00:00:00 2001 From: Martins Sipenko Date: Mon, 10 Feb 2020 05:21:44 +0200 Subject: [PATCH 0129/1468] Implement support for action secrets (#1402) Relates to: #1399. --- github/actions.go | 12 +++ github/actions_secrets.go | 132 +++++++++++++++++++++++++++++++++ github/actions_secrets_test.go | 123 ++++++++++++++++++++++++++++++ github/github-accessors.go | 16 ++++ github/github.go | 2 + 5 files changed, 285 insertions(+) create mode 100644 github/actions.go create mode 100644 github/actions_secrets.go create mode 100644 github/actions_secrets_test.go diff --git a/github/actions.go b/github/actions.go new file mode 100644 index 00000000000..f9f7f8ee867 --- /dev/null +++ b/github/actions.go @@ -0,0 +1,12 @@ +// Copyright 2020 The go-github AUTHORS. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package github + +// ActionsService handles communication with the actions related +// methods of the GitHub API. +// +// GitHub API docs: https://developer.github.com/v3/actions/ +type ActionsService service diff --git a/github/actions_secrets.go b/github/actions_secrets.go new file mode 100644 index 00000000000..d660663e139 --- /dev/null +++ b/github/actions_secrets.go @@ -0,0 +1,132 @@ +// Copyright 2020 The go-github AUTHORS. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package github + +import ( + "context" + "fmt" +) + +// PublicKey represents the public key that should be used to encrypt secrets. +type PublicKey struct { + KeyID *string `json:"key_id"` + Key *string `json:"key"` +} + +// GetPublicKey gets a public key that should be used for secret encryption. +// +// GitHub API docs: https://developer.github.com/v3/actions/secrets/#get-your-public-key +func (s *ActionsService) GetPublicKey(ctx context.Context, owner, repo string) (*PublicKey, *Response, error) { + u := fmt.Sprintf("repos/%v/%v/actions/secrets/public-key", owner, repo) + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + + pubKey := new(PublicKey) + resp, err := s.client.Do(ctx, req, pubKey) + if err != nil { + return nil, resp, err + } + + return pubKey, resp, nil +} + +// Secret represents a repository action secret. +type Secret struct { + Name string `json:"name"` + CreatedAt Timestamp `json:"created_at"` + UpdatedAt Timestamp `json:"updated_at"` +} + +// Secrets represents one item from the ListSecrets response. +type Secrets struct { + TotalCount int `json:"total_count"` + Secrets []*Secret `json:"secrets"` +} + +// ListSecrets lists all secrets available in a repository +// without revealing their encrypted values. +// +// GitHub API docs: https://developer.github.com/v3/actions/secrets/#list-secrets-for-a-repository +func (s *ActionsService) ListSecrets(ctx context.Context, owner, repo string, opt *ListOptions) (*Secrets, *Response, error) { + u := fmt.Sprintf("repos/%s/%s/actions/secrets", owner, repo) + 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 + } + + secrets := new(Secrets) + resp, err := s.client.Do(ctx, req, &secrets) + if err != nil { + return nil, resp, err + } + + return secrets, resp, nil +} + +// GetSecret gets a single secret without revealing its encrypted value. +// +// GitHub API docs: https://developer.github.com/v3/actions/secrets/#get-a-secret +func (s *ActionsService) GetSecret(ctx context.Context, owner, repo, name string) (*Secret, *Response, error) { + u := fmt.Sprintf("repos/%v/%v/actions/secrets/%v", owner, repo, name) + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + + secret := new(Secret) + resp, err := s.client.Do(ctx, req, secret) + if err != nil { + return nil, resp, err + } + + return secret, resp, nil +} + +// EncryptedSecret represents a secret that is encrypted using a public key. +// +// The value of EncryptedValue must be your secret, encrypted with +// LibSodium (see documentation here: https://libsodium.gitbook.io/doc/bindings_for_other_languages) +// using the public key retrieved using the GetPublicKey method. +type EncryptedSecret struct { + Name string `json:"-"` + KeyID string `json:"key_id"` + EncryptedValue string `json:"encrypted_value"` +} + +// CreateOrUpdateSecret creates or updates a secret with an encrypted value. +// +// GitHub API docs: https://developer.github.com/v3/actions/secrets/#create-or-update-a-secret-for-a-repository +func (s *ActionsService) CreateOrUpdateSecret(ctx context.Context, owner, repo string, eSecret *EncryptedSecret) (*Response, error) { + u := fmt.Sprintf("repos/%v/%v/actions/secrets/%v", owner, repo, eSecret.Name) + + req, err := s.client.NewRequest("PUT", u, eSecret) + if err != nil { + return nil, err + } + + return s.client.Do(ctx, req, nil) +} + +// DeleteSecret deletes a secret in a repository using the secret name. +// +// GitHub API docs: https://developer.github.com/v3/actions/secrets/#delete-a-secret-from-a-repository +func (s *ActionsService) DeleteSecret(ctx context.Context, owner, repo, name string) (*Response, error) { + u := fmt.Sprintf("repos/%v/%v/actions/secrets/%v", owner, repo, name) + + req, err := s.client.NewRequest("DELETE", u, nil) + if err != nil { + return nil, err + } + + return s.client.Do(ctx, req, nil) +} diff --git a/github/actions_secrets_test.go b/github/actions_secrets_test.go new file mode 100644 index 00000000000..07f911fd7d8 --- /dev/null +++ b/github/actions_secrets_test.go @@ -0,0 +1,123 @@ +// Copyright 2020 The go-github AUTHORS. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package github + +import ( + "context" + "fmt" + "net/http" + "reflect" + "testing" + "time" +) + +func TestActionsService_GetPublicKey(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/repos/o/r/actions/secrets/public-key", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + fmt.Fprint(w, `{"key_id":"1234","key":"2Sg8iYjAxxmI2LvUXpJjkYrMxURPc8r+dB7TJyvv1234"}`) + }) + + key, _, err := client.Actions.GetPublicKey(context.Background(), "o", "r") + if err != nil { + t.Errorf("Actions.GetPublicKey returned error: %v", err) + } + + want := &PublicKey{KeyID: String("1234"), Key: String("2Sg8iYjAxxmI2LvUXpJjkYrMxURPc8r+dB7TJyvv1234")} + if !reflect.DeepEqual(key, want) { + t.Errorf("Actions.GetPublicKey returned %+v, want %+v", key, want) + } +} + +func TestActionsService_ListSecrets(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/repos/o/r/actions/secrets", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + testFormValues(t, r, values{"per_page": "2", "page": "2"}) + fmt.Fprint(w, `{"total_count":4,"secrets":[{"name":"A","created_at":"2019-01-02T15:04:05Z","updated_at":"2020-01-02T15:04:05Z"},{"name":"B","created_at":"2019-01-02T15:04:05Z","updated_at":"2020-01-02T15:04:05Z"}]}`) + }) + + opt := &ListOptions{Page: 2, PerPage: 2} + secrets, _, err := client.Actions.ListSecrets(context.Background(), "o", "r", opt) + if err != nil { + t.Errorf("Actions.ListSecrets returned error: %v", err) + } + + want := &Secrets{ + TotalCount: 4, + Secrets: []*Secret{ + {Name: "A", CreatedAt: Timestamp{time.Date(2019, time.January, 02, 15, 04, 05, 0, time.UTC)}, UpdatedAt: Timestamp{time.Date(2020, time.January, 02, 15, 04, 05, 0, time.UTC)}}, + {Name: "B", CreatedAt: Timestamp{time.Date(2019, time.January, 02, 15, 04, 05, 0, time.UTC)}, UpdatedAt: Timestamp{time.Date(2020, time.January, 02, 15, 04, 05, 0, time.UTC)}}, + }, + } + if !reflect.DeepEqual(secrets, want) { + t.Errorf("Actions.ListSecrets returned %+v, want %+v", secrets, want) + } +} + +func TestActionsService_GetSecret(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/repos/o/r/actions/secrets/NAME", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + fmt.Fprint(w, `{"name":"NAME","created_at":"2019-01-02T15:04:05Z","updated_at":"2020-01-02T15:04:05Z"}`) + }) + + secret, _, err := client.Actions.GetSecret(context.Background(), "o", "r", "NAME") + if err != nil { + t.Errorf("Actions.GetSecret returned error: %v", err) + } + + want := &Secret{ + Name: "NAME", + CreatedAt: Timestamp{time.Date(2019, time.January, 02, 15, 04, 05, 0, time.UTC)}, + UpdatedAt: Timestamp{time.Date(2020, time.January, 02, 15, 04, 05, 0, time.UTC)}, + } + if !reflect.DeepEqual(secret, want) { + t.Errorf("Actions.GetSecret returned %+v, want %+v", secret, want) + } +} + +func TestActionsService_CreateOrUpdateSecret(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/repos/o/r/actions/secrets/NAME", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "PUT") + testHeader(t, r, "Content-Type", "application/json") + testBody(t, r, `{"key_id":"1234","encrypted_value":"QIv="}`+"\n") + w.WriteHeader(http.StatusCreated) + }) + + input := &EncryptedSecret{ + Name: "NAME", + EncryptedValue: "QIv=", + KeyID: "1234", + } + _, err := client.Actions.CreateOrUpdateSecret(context.Background(), "o", "r", input) + if err != nil { + t.Errorf("Actions.CreateOrUpdateSecret returned error: %v", err) + } +} + +func TestActionsService_DeleteSecret(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/repos/o/r/actions/secrets/NAME", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "DELETE") + }) + + _, err := client.Actions.DeleteSecret(context.Background(), "o", "r", "NAME") + if err != nil { + t.Errorf("Actions.DeleteSecret returned error: %v", err) + } +} diff --git a/github/github-accessors.go b/github/github-accessors.go index a17114ec914..212e334b460 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -7932,6 +7932,22 @@ func (p *PublicEvent) GetSender() *User { return p.Sender } +// GetKey returns the Key field if it's non-nil, zero value otherwise. +func (p *PublicKey) GetKey() string { + if p == nil || p.Key == nil { + return "" + } + return *p.Key +} + +// GetKeyID returns the KeyID field if it's non-nil, zero value otherwise. +func (p *PublicKey) GetKeyID() string { + if p == nil || p.KeyID == nil { + return "" + } + return *p.KeyID +} + // GetActiveLockReason returns the ActiveLockReason field if it's non-nil, zero value otherwise. func (p *PullRequest) GetActiveLockReason() string { if p == nil || p.ActiveLockReason == nil { diff --git a/github/github.go b/github/github.go index b1b9afa2ff9..696684b931f 100644 --- a/github/github.go +++ b/github/github.go @@ -159,6 +159,7 @@ type Client struct { common service // Reuse a single struct instead of allocating one for each service on the heap. // Services used for talking to different parts of the GitHub API. + Actions *ActionsService Activity *ActivityService Admin *AdminService Apps *AppsService @@ -264,6 +265,7 @@ func NewClient(httpClient *http.Client) *Client { c := &Client{client: httpClient, BaseURL: baseURL, UserAgent: userAgent, UploadURL: uploadURL} c.common.client = c + c.Actions = (*ActionsService)(&c.common) c.Activity = (*ActivityService)(&c.common) c.Admin = (*AdminService)(&c.common) c.Apps = (*AppsService)(&c.common) From f0c864390edc477cb0a4cb58943f9c42fbd2ed16 Mon Sep 17 00:00:00 2001 From: Joshua Bezaleel Abednego Date: Mon, 10 Feb 2020 19:44:53 +0700 Subject: [PATCH 0130/1468] Implement support for action workflows (#1411) Relates to: #1399. --- github/actions_secrets.go | 4 +- github/actions_secrets_test.go | 4 +- github/actions_workflows.go | 88 ++++++++++++++++++++++++++++++ github/actions_workflows_test.go | 91 ++++++++++++++++++++++++++++++++ 4 files changed, 183 insertions(+), 4 deletions(-) create mode 100644 github/actions_workflows.go create mode 100644 github/actions_workflows_test.go diff --git a/github/actions_secrets.go b/github/actions_secrets.go index d660663e139..1640b5a02cc 100644 --- a/github/actions_secrets.go +++ b/github/actions_secrets.go @@ -52,9 +52,9 @@ type Secrets struct { // without revealing their encrypted values. // // GitHub API docs: https://developer.github.com/v3/actions/secrets/#list-secrets-for-a-repository -func (s *ActionsService) ListSecrets(ctx context.Context, owner, repo string, opt *ListOptions) (*Secrets, *Response, error) { +func (s *ActionsService) ListSecrets(ctx context.Context, owner, repo string, opts *ListOptions) (*Secrets, *Response, error) { u := fmt.Sprintf("repos/%s/%s/actions/secrets", owner, repo) - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } diff --git a/github/actions_secrets_test.go b/github/actions_secrets_test.go index 07f911fd7d8..0a17e583512 100644 --- a/github/actions_secrets_test.go +++ b/github/actions_secrets_test.go @@ -44,8 +44,8 @@ func TestActionsService_ListSecrets(t *testing.T) { fmt.Fprint(w, `{"total_count":4,"secrets":[{"name":"A","created_at":"2019-01-02T15:04:05Z","updated_at":"2020-01-02T15:04:05Z"},{"name":"B","created_at":"2019-01-02T15:04:05Z","updated_at":"2020-01-02T15:04:05Z"}]}`) }) - opt := &ListOptions{Page: 2, PerPage: 2} - secrets, _, err := client.Actions.ListSecrets(context.Background(), "o", "r", opt) + opts := &ListOptions{Page: 2, PerPage: 2} + secrets, _, err := client.Actions.ListSecrets(context.Background(), "o", "r", opts) if err != nil { t.Errorf("Actions.ListSecrets returned error: %v", err) } diff --git a/github/actions_workflows.go b/github/actions_workflows.go new file mode 100644 index 00000000000..fc4cf4a531a --- /dev/null +++ b/github/actions_workflows.go @@ -0,0 +1,88 @@ +// Copyright 2020 The go-github AUTHORS. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package github + +import ( + "context" + "fmt" +) + +// Workflow represents a repository action workflow. +type Workflow struct { + ID int64 `json:"id"` + NodeID string `json:"node_id"` + Name string `json:"name"` + Path string `json:"path"` + State string `json:"state"` + CreatedAt Timestamp `json:"created_at"` + UpdatedAt Timestamp `json:"updated_at"` + URL string `json:"url"` + HTMLURL string `json:"html_url"` + BadgeURL string `json:"badge_url"` +} + +// Workflows represents a slice of repository action workflows. +type Workflows struct { + TotalCount int `json:"total_count"` + Workflows []*Workflow `json:"workflows"` +} + +// ListWorkflows lists all workflows in a repository. +// +// GitHub API docs: https://developer.github.com/v3/actions/workflows/#list-repository-workflows +func (s *ActionsService) ListWorkflows(ctx context.Context, owner, repo string, opts *ListOptions) (*Workflows, *Response, error) { + u := fmt.Sprintf("repos/%s/%s/actions/workflows", owner, repo) + u, err := addOptions(u, opts) + if err != nil { + return nil, nil, err + } + + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + + workflows := new(Workflows) + resp, err := s.client.Do(ctx, req, &workflows) + if err != nil { + return nil, resp, err + } + + return workflows, resp, nil +} + +// GetWorkflowByID gets a specific workflow by ID. +// +// GitHub API docs: https://developer.github.com/v3/actions/workflows/#get-a-workflow +func (s *ActionsService) GetWorkflowByID(ctx context.Context, owner, repo string, workflowID int64) (*Workflow, *Response, error) { + u := fmt.Sprintf("repos/%v/%v/actions/workflows/%v", owner, repo, workflowID) + + return s.getWorkflow(ctx, u) +} + +// GetWorkflowByFileName gets a specific workflow by file name. +// +// GitHub API docs: https://developer.github.com/v3/actions/workflows/#get-a-workflow +func (s *ActionsService) GetWorkflowByFileName(ctx context.Context, owner, repo, workflowFileName string) (*Workflow, *Response, error) { + u := fmt.Sprintf("repos/%v/%v/actions/workflows/%v", owner, repo, workflowFileName) + + return s.getWorkflow(ctx, u) +} + +func (s *ActionsService) getWorkflow(ctx context.Context, url string) (*Workflow, *Response, error) { + req, err := s.client.NewRequest("GET", url, nil) + if err != nil { + return nil, nil, err + } + + workflow := new(Workflow) + resp, err := s.client.Do(ctx, req, workflow) + if err != nil { + return nil, resp, err + } + + return workflow, resp, nil +} diff --git a/github/actions_workflows_test.go b/github/actions_workflows_test.go new file mode 100644 index 00000000000..8d9f9232487 --- /dev/null +++ b/github/actions_workflows_test.go @@ -0,0 +1,91 @@ +// Copyright 2020 The go-github AUTHORS. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package github + +import ( + "context" + "fmt" + "net/http" + "reflect" + "testing" + "time" +) + +func TestActionsService_ListWorkflows(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/repos/o/r/actions/workflows", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + testFormValues(t, r, values{"per_page": "2", "page": "2"}) + fmt.Fprint(w, `{"total_count":4,"workflows":[{"id":72844,"created_at":"2019-01-02T15:04:05Z","updated_at":"2020-01-02T15:04:05Z"},{"id":72845,"created_at":"2019-01-02T15:04:05Z","updated_at":"2020-01-02T15:04:05Z"}]}`) + }) + + opts := &ListOptions{Page: 2, PerPage: 2} + workflows, _, err := client.Actions.ListWorkflows(context.Background(), "o", "r", opts) + if err != nil { + t.Errorf("Actions.ListWorkflows returned error: %v", err) + } + + want := &Workflows{ + TotalCount: 4, + Workflows: []*Workflow{ + {ID: 72844, CreatedAt: Timestamp{time.Date(2019, time.January, 02, 15, 04, 05, 0, time.UTC)}, UpdatedAt: Timestamp{time.Date(2020, time.January, 02, 15, 04, 05, 0, time.UTC)}}, + {ID: 72845, CreatedAt: Timestamp{time.Date(2019, time.January, 02, 15, 04, 05, 0, time.UTC)}, UpdatedAt: Timestamp{time.Date(2020, time.January, 02, 15, 04, 05, 0, time.UTC)}}, + }, + } + if !reflect.DeepEqual(workflows, want) { + t.Errorf("Actions.ListWorkflows returned %+v, want %+v", workflows, want) + } +} + +func TestActionsService_GetWorkflowByID(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/repos/o/r/actions/workflows/72844", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + fmt.Fprint(w, `{"id":72844,"created_at":"2019-01-02T15:04:05Z","updated_at":"2020-01-02T15:04:05Z"}`) + }) + + workflow, _, err := client.Actions.GetWorkflowByID(context.Background(), "o", "r", 72844) + if err != nil { + t.Errorf("Actions.GetWorkflowByID returned error: %v", err) + } + + want := &Workflow{ + ID: 72844, + CreatedAt: Timestamp{time.Date(2019, time.January, 02, 15, 04, 05, 0, time.UTC)}, + UpdatedAt: Timestamp{time.Date(2020, time.January, 02, 15, 04, 05, 0, time.UTC)}, + } + if !reflect.DeepEqual(workflow, want) { + t.Errorf("Actions.GetWorkflowByID returned %+v, want %+v", workflow, want) + } +} + +func TestActionsService_GetWorkflowByFileName(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/repos/o/r/actions/workflows/main.yml", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + fmt.Fprint(w, `{"id":72844,"created_at":"2019-01-02T15:04:05Z","updated_at":"2020-01-02T15:04:05Z"}`) + }) + + workflow, _, err := client.Actions.GetWorkflowByFileName(context.Background(), "o", "r", "main.yml") + if err != nil { + t.Errorf("Actions.GetWorkflowByFileName returned error: %v", err) + } + + want := &Workflow{ + ID: 72844, + CreatedAt: Timestamp{time.Date(2019, time.January, 02, 15, 04, 05, 0, time.UTC)}, + UpdatedAt: Timestamp{time.Date(2020, time.January, 02, 15, 04, 05, 0, time.UTC)}, + } + if !reflect.DeepEqual(workflow, want) { + t.Errorf("Actions.GetWorkflowByFileName returned %+v, want %+v", workflow, want) + } +} From 2e3e74fa920e7d6278b7a9737ab5c8b7b1480294 Mon Sep 17 00:00:00 2001 From: Alex Orr Date: Mon, 10 Feb 2020 05:19:58 -0800 Subject: [PATCH 0131/1468] Move the GitHub Teams API (#1400) Fixes: #1387. --- github/teams.go | 328 ++++++++++++++++++++---- github/teams_test.go | 593 +++++++++++++++++++++++++++++++------------ 2 files changed, 718 insertions(+), 203 deletions(-) diff --git a/github/teams.go b/github/teams.go index 1f86ef9654f..cfb814e7dbd 100644 --- a/github/teams.go +++ b/github/teams.go @@ -97,11 +97,11 @@ func (s *TeamsService) ListTeams(ctx context.Context, org string, opts *ListOpti return teams, resp, nil } -// GetTeam fetches a team by ID. +// GetTeamByID fetches a team, given a specified organization ID, by ID. // -// GitHub API docs: https://developer.github.com/v3/teams/#get-team -func (s *TeamsService) GetTeam(ctx context.Context, team int64) (*Team, *Response, error) { - u := fmt.Sprintf("teams/%v", team) +// GitHub API docs: https://developer.github.com/v3/teams/#get-team-by-name +func (s *TeamsService) GetTeamByID(ctx context.Context, orgID, teamID int64) (*Team, *Response, error) { + u := fmt.Sprintf("organizations/%v/team/%v", orgID, teamID) req, err := s.client.NewRequest("GET", u, nil) if err != nil { return nil, nil, err @@ -116,7 +116,7 @@ func (s *TeamsService) GetTeam(ctx context.Context, team int64) (*Team, *Respons return t, resp, nil } -// GetTeamBySlug fetches a team by slug. +// GetTeamBySlug fetches a team, given a specified organization name, by slug. // // GitHub API docs: https://developer.github.com/v3/teams/#get-team-by-name func (s *TeamsService) GetTeamBySlug(ctx context.Context, org, slug string) (*Team, *Response, error) { @@ -212,11 +212,11 @@ func copyNewTeamWithoutParent(team *NewTeam) *newTeamNoParent { } } -// EditTeam edits a team. +// EditTeamByID edits a team, given an organization ID, selected by ID. // // GitHub API docs: https://developer.github.com/v3/teams/#edit-team -func (s *TeamsService) EditTeam(ctx context.Context, id int64, team NewTeam, removeParent bool) (*Team, *Response, error) { - u := fmt.Sprintf("teams/%v", id) +func (s *TeamsService) EditTeamByID(ctx context.Context, orgID, teamID int64, team NewTeam, removeParent bool) (*Team, *Response, error) { + u := fmt.Sprintf("organizations/%v/team/%v", orgID, teamID) var req *http.Request var err error @@ -239,11 +239,51 @@ func (s *TeamsService) EditTeam(ctx context.Context, id int64, team NewTeam, rem return t, resp, nil } -// DeleteTeam deletes a team. +// EditTeamBySlug edits a team, given an organization name, by slug. +// +// GitHub API docs: https://developer.github.com/v3/teams/#edit-team +func (s *TeamsService) EditTeamBySlug(ctx context.Context, org, slug string, team NewTeam, removeParent bool) (*Team, *Response, error) { + u := fmt.Sprintf("orgs/%v/teams/%v", org, slug) + + var req *http.Request + var err error + if removeParent { + teamRemoveParent := copyNewTeamWithoutParent(&team) + req, err = s.client.NewRequest("PATCH", u, teamRemoveParent) + } else { + req, err = s.client.NewRequest("PATCH", u, team) + } + if err != nil { + return nil, nil, err + } + + t := new(Team) + resp, err := s.client.Do(ctx, req, t) + if err != nil { + return nil, resp, err + } + + return t, resp, nil +} + +// DeleteTeamByID deletes a team referenced by ID. +// +// GitHub API docs: https://developer.github.com/v3/teams/#delete-team +func (s *TeamsService) DeleteTeamByID(ctx context.Context, orgID, teamID int64) (*Response, error) { + u := fmt.Sprintf("organizations/%v/team/%v", orgID, teamID) + req, err := s.client.NewRequest("DELETE", u, nil) + if err != nil { + return nil, err + } + + return s.client.Do(ctx, req, nil) +} + +// DeleteTeamBySlug deletes a team reference by slug. // // GitHub API docs: https://developer.github.com/v3/teams/#delete-team -func (s *TeamsService) DeleteTeam(ctx context.Context, team int64) (*Response, error) { - u := fmt.Sprintf("teams/%v", team) +func (s *TeamsService) DeleteTeamBySlug(ctx context.Context, org, slug string) (*Response, error) { + u := fmt.Sprintf("orgs/%v/teams/%v", org, slug) req, err := s.client.NewRequest("DELETE", u, nil) if err != nil { return nil, err @@ -252,11 +292,35 @@ func (s *TeamsService) DeleteTeam(ctx context.Context, team int64) (*Response, e return s.client.Do(ctx, req, nil) } -// ListChildTeams lists child teams for a team. +// ListChildTeamsByParentID lists child teams for a parent team given parent ID. +// +// GitHub API docs: https://developer.github.com/v3/teams/#list-child-teams +func (s *TeamsService) ListChildTeamsByParentID(ctx context.Context, orgID, teamID int64, opts *ListOptions) ([]*Team, *Response, error) { + u := fmt.Sprintf("organizations/%v/team/%v/teams", orgID, teamID) + u, err := addOptions(u, opts) + if err != nil { + return nil, nil, err + } + + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + + var teams []*Team + resp, err := s.client.Do(ctx, req, &teams) + if err != nil { + return nil, resp, err + } + + return teams, resp, nil +} + +// ListChildTeamsByParentSlug lists child teams for a parent team given parent slug. // // GitHub API docs: https://developer.github.com/v3/teams/#list-child-teams -func (s *TeamsService) ListChildTeams(ctx context.Context, teamID int64, opts *ListOptions) ([]*Team, *Response, error) { - u := fmt.Sprintf("teams/%v/teams", teamID) +func (s *TeamsService) ListChildTeamsByParentSlug(ctx context.Context, org, slug string, opts *ListOptions) ([]*Team, *Response, error) { + u := fmt.Sprintf("orgs/%v/teams/%v/teams", org, slug) u, err := addOptions(u, opts) if err != nil { return nil, nil, err @@ -276,11 +340,11 @@ func (s *TeamsService) ListChildTeams(ctx context.Context, teamID int64, opts *L return teams, resp, nil } -// ListTeamRepos lists the repositories that the specified team has access to. +// ListTeamReposByID lists the repositories given a team ID that the specified team has access to. // // GitHub API docs: https://developer.github.com/v3/teams/#list-team-repos -func (s *TeamsService) ListTeamRepos(ctx context.Context, team int64, opts *ListOptions) ([]*Repository, *Response, error) { - u := fmt.Sprintf("teams/%v/repos", team) +func (s *TeamsService) ListTeamReposByID(ctx context.Context, orgID, teamID int64, opts *ListOptions) ([]*Repository, *Response, error) { + u := fmt.Sprintf("organizations/%v/team/%v/repos", orgID, teamID) u, err := addOptions(u, opts) if err != nil { return nil, nil, err @@ -304,13 +368,65 @@ func (s *TeamsService) ListTeamRepos(ctx context.Context, team int64, opts *List return repos, resp, nil } -// IsTeamRepo checks if a team manages the specified repository. If the +// ListTeamReposBySlug lists the repositories given a team slug that the specified team has access to. +// +// GitHub API docs: https://developer.github.com/v3/teams/#list-team-repos +func (s *TeamsService) ListTeamReposBySlug(ctx context.Context, org, slug string, opts *ListOptions) ([]*Repository, *Response, error) { + u := fmt.Sprintf("orgs/%v/teams/%v/repos", org, slug) + u, err := addOptions(u, opts) + 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 topics API fully launches. + headers := []string{mediaTypeTopicsPreview} + req.Header.Set("Accept", strings.Join(headers, ", ")) + + var repos []*Repository + resp, err := s.client.Do(ctx, req, &repos) + if err != nil { + return nil, resp, err + } + + return repos, resp, nil +} + +// IsTeamRepoByID checks if a team, given its ID, manages the specified repository. If the +// repository is managed by team, a Repository is returned which includes the +// permissions team has for that repo. +// +// GitHub API docs: https://developer.github.com/v3/teams/#check-if-a-team-manages-a-repository +func (s *TeamsService) IsTeamRepoByID(ctx context.Context, orgID, teamID int64, owner, repo string) (*Repository, *Response, error) { + u := fmt.Sprintf("organizations/%v/team/%v/repos/%v/%v", orgID, teamID, owner, repo) + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + + headers := []string{mediaTypeOrgPermissionRepo} + req.Header.Set("Accept", strings.Join(headers, ", ")) + + repository := new(Repository) + resp, err := s.client.Do(ctx, req, repository) + if err != nil { + return nil, resp, err + } + + return repository, resp, nil +} + +// IsTeamRepoBySlug checks if a team, given its slug, manages the specified repository. If the // repository is managed by team, a Repository is returned which includes the // permissions team has for that repo. // // GitHub API docs: https://developer.github.com/v3/teams/#check-if-a-team-manages-a-repository -func (s *TeamsService) IsTeamRepo(ctx context.Context, team int64, owner string, repo string) (*Repository, *Response, error) { - u := fmt.Sprintf("teams/%v/repos/%v/%v", team, owner, repo) +func (s *TeamsService) IsTeamRepoBySlug(ctx context.Context, org, slug, owner, repo string) (*Repository, *Response, error) { + u := fmt.Sprintf("orgs/%v/teams/%v/repos/%v/%v", org, slug, owner, repo) req, err := s.client.NewRequest("GET", u, nil) if err != nil { return nil, nil, err @@ -341,13 +457,13 @@ type TeamAddTeamRepoOptions struct { Permission string `json:"permission,omitempty"` } -// AddTeamRepo adds a repository to be managed by the specified team. The -// specified repository must be owned by the organization to which the team +// AddTeamRepoByID adds a repository to be managed by the specified team given the team ID. +// The specified repository must be owned by the organization to which the team // belongs, or a direct fork of a repository owned by the organization. // // GitHub API docs: https://developer.github.com/v3/teams/#add-team-repo -func (s *TeamsService) AddTeamRepo(ctx context.Context, team int64, owner string, repo string, opts *TeamAddTeamRepoOptions) (*Response, error) { - u := fmt.Sprintf("teams/%v/repos/%v/%v", team, owner, repo) +func (s *TeamsService) AddTeamRepoByID(ctx context.Context, orgID, teamID int64, owner, repo string, opts *TeamAddTeamRepoOptions) (*Response, error) { + u := fmt.Sprintf("organizations/%v/team/%v/repos/%v/%v", orgID, teamID, owner, repo) req, err := s.client.NewRequest("PUT", u, opts) if err != nil { return nil, err @@ -356,13 +472,43 @@ func (s *TeamsService) AddTeamRepo(ctx context.Context, team int64, owner string return s.client.Do(ctx, req, nil) } -// RemoveTeamRepo removes a repository from being managed by the specified -// team. Note that this does not delete the repository, it just removes it -// from the team. +// AddTeamRepoBySlug adds a repository to be managed by the specified team given the team slug. +// The specified repository must be owned by the organization to which the team +// belongs, or a direct fork of a repository owned by the organization. +// +// GitHub API docs: https://developer.github.com/v3/teams/#add-team-repo +func (s *TeamsService) AddTeamRepoBySlug(ctx context.Context, org, slug, owner, repo string, opts *TeamAddTeamRepoOptions) (*Response, error) { + u := fmt.Sprintf("orgs/%v/teams/%v/repos/%v/%v", org, slug, owner, repo) + req, err := s.client.NewRequest("PUT", u, opts) + if err != nil { + return nil, err + } + + return s.client.Do(ctx, req, nil) +} + +// RemoveTeamRepoByID removes a repository from being managed by the specified +// team given the team ID. Note that this does not delete the repository, it +// just removes it from the team. // // GitHub API docs: https://developer.github.com/v3/teams/#remove-team-repo -func (s *TeamsService) RemoveTeamRepo(ctx context.Context, team int64, owner string, repo string) (*Response, error) { - u := fmt.Sprintf("teams/%v/repos/%v/%v", team, owner, repo) +func (s *TeamsService) RemoveTeamRepoByID(ctx context.Context, orgID, teamID int64, owner, repo string) (*Response, error) { + u := fmt.Sprintf("organizations/%v/team/%v/repos/%v/%v", orgID, teamID, owner, repo) + req, err := s.client.NewRequest("DELETE", u, nil) + if err != nil { + return nil, err + } + + return s.client.Do(ctx, req, nil) +} + +// RemoveTeamRepoBySlug removes a repository from being managed by the specified +// team given the team slug. Note that this does not delete the repository, it +// just removes it from the team. +// +// GitHub API docs: https://developer.github.com/v3/teams/#remove-team-repo +func (s *TeamsService) RemoveTeamRepoBySlug(ctx context.Context, org, slug, owner, repo string) (*Response, error) { + u := fmt.Sprintf("orgs/%v/teams/%v/repos/%v/%v", org, slug, owner, repo) req, err := s.client.NewRequest("DELETE", u, nil) if err != nil { return nil, err @@ -394,11 +540,35 @@ func (s *TeamsService) ListUserTeams(ctx context.Context, opts *ListOptions) ([] return teams, resp, nil } -// ListTeamProjects lists the organization projects for a team. +// ListTeamProjectsByID lists the organization projects for a team given the team ID. +// +// GitHub API docs: https://developer.github.com/v3/teams/#list-team-projects +func (s *TeamsService) ListTeamProjectsByID(ctx context.Context, orgID, teamID int64) ([]*Project, *Response, error) { + u := fmt.Sprintf("organizations/%v/team/%v/projects", orgID, teamID) + + 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{mediaTypeProjectsPreview} + req.Header.Set("Accept", strings.Join(acceptHeaders, ", ")) + + var projects []*Project + resp, err := s.client.Do(ctx, req, &projects) + if err != nil { + return nil, resp, err + } + + return projects, resp, nil +} + +// ListTeamProjectsBySlug lists the organization projects for a team given the team slug. // // GitHub API docs: https://developer.github.com/v3/teams/#list-team-projects -func (s *TeamsService) ListTeamProjects(ctx context.Context, teamID int64) ([]*Project, *Response, error) { - u := fmt.Sprintf("teams/%v/projects", teamID) +func (s *TeamsService) ListTeamProjectsBySlug(ctx context.Context, org, slug string) ([]*Project, *Response, error) { + u := fmt.Sprintf("orgs/%v/teams/%v/projects", org, slug) req, err := s.client.NewRequest("GET", u, nil) if err != nil { @@ -418,12 +588,36 @@ func (s *TeamsService) ListTeamProjects(ctx context.Context, teamID int64) ([]*P return projects, resp, nil } -// ReviewTeamProjects checks whether a team has read, write, or admin +// ReviewTeamProjectsByID checks whether a team, given its ID, has read, write, or admin +// permissions for an organization project. +// +// GitHub API docs: https://developer.github.com/v3/teams/#review-a-team-project +func (s *TeamsService) ReviewTeamProjectsByID(ctx context.Context, orgID, teamID, projectID int64) (*Project, *Response, error) { + u := fmt.Sprintf("organizations/%v/team/%v/projects/%v", orgID, teamID, projectID) + 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{mediaTypeProjectsPreview} + req.Header.Set("Accept", strings.Join(acceptHeaders, ", ")) + + projects := &Project{} + resp, err := s.client.Do(ctx, req, &projects) + if err != nil { + return nil, resp, err + } + + return projects, resp, nil +} + +// ReviewTeamProjectsBySlug checks whether a team, given its slug, has read, write, or admin // permissions for an organization project. // // GitHub API docs: https://developer.github.com/v3/teams/#review-a-team-project -func (s *TeamsService) ReviewTeamProjects(ctx context.Context, teamID, projectID int64) (*Project, *Response, error) { - u := fmt.Sprintf("teams/%v/projects/%v", teamID, projectID) +func (s *TeamsService) ReviewTeamProjectsBySlug(ctx context.Context, org, slug string, projectID int64) (*Project, *Response, error) { + u := fmt.Sprintf("orgs/%v/teams/%v/projects/%v", org, slug, projectID) req, err := s.client.NewRequest("GET", u, nil) if err != nil { return nil, nil, err @@ -454,13 +648,13 @@ type TeamProjectOptions struct { Permission *string `json:"permission,omitempty"` } -// AddTeamProject adds an organization project to a team. To add a project to a team or -// update the team's permission on a project, the authenticated user must have admin -// permissions for the project. +// AddTeamProjectByID adds an organization project to a team given the team ID. +// To add a project to a team or update the team's permission on a project, the +// authenticated user must have admin permissions for the project. // // GitHub API docs: https://developer.github.com/v3/teams/#add-or-update-team-project -func (s *TeamsService) AddTeamProject(ctx context.Context, teamID, projectID int64, opts *TeamProjectOptions) (*Response, error) { - u := fmt.Sprintf("teams/%v/projects/%v", teamID, projectID) +func (s *TeamsService) AddTeamProjectByID(ctx context.Context, orgID, teamID, projectID int64, opts *TeamProjectOptions) (*Response, error) { + u := fmt.Sprintf("organizations/%v/team/%v/projects/%v", orgID, teamID, projectID) req, err := s.client.NewRequest("PUT", u, opts) if err != nil { return nil, err @@ -473,15 +667,57 @@ func (s *TeamsService) AddTeamProject(ctx context.Context, teamID, projectID int return s.client.Do(ctx, req, nil) } -// RemoveTeamProject removes an organization project from a team. An organization owner or -// a team maintainer can remove any project from the team. To remove a project from a team -// as an organization member, the authenticated user must have "read" access to both the team -// and project, or "admin" access to the team or project. +// AddTeamProjectBySlug adds an organization project to a team given the team slug. +// To add a project to a team or update the team's permission on a project, the +// authenticated user must have admin permissions for the project. +// +// GitHub API docs: https://developer.github.com/v3/teams/#add-or-update-team-project +func (s *TeamsService) AddTeamProjectBySlug(ctx context.Context, org, slug string, projectID int64, opts *TeamProjectOptions) (*Response, error) { + u := fmt.Sprintf("orgs/%v/teams/%v/projects/%v", org, slug, projectID) + req, err := s.client.NewRequest("PUT", u, opts) + if err != nil { + return nil, err + } + + // TODO: remove custom Accept header when this API fully launches. + acceptHeaders := []string{mediaTypeProjectsPreview} + req.Header.Set("Accept", strings.Join(acceptHeaders, ", ")) + + return s.client.Do(ctx, req, nil) +} + +// RemoveTeamProjectByID removes an organization project from a team given team ID. +// An organization owner or a team maintainer can remove any project from the team. +// To remove a project from a team as an organization member, the authenticated user +// must have "read" access to both the team and project, or "admin" access to the team +// or project. +// Note: This endpoint removes the project from the team, but does not delete it. +// +// GitHub API docs: https://developer.github.com/v3/teams/#remove-team-project +func (s *TeamsService) RemoveTeamProjectByID(ctx context.Context, orgID, teamID, projectID int64) (*Response, error) { + u := fmt.Sprintf("organizations/%v/team/%v/projects/%v", orgID, teamID, projectID) + req, err := s.client.NewRequest("DELETE", u, nil) + if err != nil { + return nil, err + } + + // TODO: remove custom Accept header when this API fully launches. + acceptHeaders := []string{mediaTypeProjectsPreview} + req.Header.Set("Accept", strings.Join(acceptHeaders, ", ")) + + return s.client.Do(ctx, req, nil) +} + +// RemoveTeamProjectBySlug removes an organization project from a team given team slug. +// An organization owner or a team maintainer can remove any project from the team. +// To remove a project from a team as an organization member, the authenticated user +// must have "read" access to both the team and project, or "admin" access to the team +// or project. // Note: This endpoint removes the project from the team, but does not delete it. // // GitHub API docs: https://developer.github.com/v3/teams/#remove-team-project -func (s *TeamsService) RemoveTeamProject(ctx context.Context, teamID int64, projectID int64) (*Response, error) { - u := fmt.Sprintf("teams/%v/projects/%v", teamID, projectID) +func (s *TeamsService) RemoveTeamProjectBySlug(ctx context.Context, org, slug string, projectID int64) (*Response, error) { + u := fmt.Sprintf("orgs/%v/teams/%v/projects/%v", org, slug, projectID) req, err := s.client.NewRequest("DELETE", u, nil) if err != nil { return nil, err diff --git a/github/teams_test.go b/github/teams_test.go index ce7ece54b06..414ad78e7fc 100644 --- a/github/teams_test.go +++ b/github/teams_test.go @@ -15,7 +15,6 @@ import ( "reflect" "strings" "testing" - "time" ) func TestTeamsService_ListTeams(t *testing.T) { @@ -48,46 +47,44 @@ func TestTeamsService_ListTeams_invalidOrg(t *testing.T) { testURLParseError(t, err) } -func TestTeamsService_GetTeam(t *testing.T) { +func TestTeamsService_GetTeamByID(t *testing.T) { client, mux, _, teardown := setup() defer teardown() - mux.HandleFunc("/teams/1", func(w http.ResponseWriter, r *http.Request) { + mux.HandleFunc("/organizations/1/team/1", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") fmt.Fprint(w, `{"id":1, "name":"n", "description": "d", "url":"u", "slug": "s", "permission":"p", "ldap_dn":"cn=n,ou=groups,dc=example,dc=com", "parent":null}`) }) - team, _, err := client.Teams.GetTeam(context.Background(), 1) + team, _, err := client.Teams.GetTeamByID(context.Background(), 1, 1) if err != nil { - t.Errorf("Teams.GetTeam returned error: %v", err) + t.Errorf("Teams.GetTeamByID returned error: %v", err) } want := &Team{ID: Int64(1), Name: String("n"), Description: String("d"), URL: String("u"), Slug: String("s"), Permission: String("p"), LDAPDN: String("cn=n,ou=groups,dc=example,dc=com")} if !reflect.DeepEqual(team, want) { - t.Errorf("Teams.GetTeam returned %+v, want %+v", team, want) + t.Errorf("Teams.GetTeamByID returned %+v, want %+v", team, want) } } -func TestTeamsService_GetTeam_nestedTeams(t *testing.T) { +func TestTeamsService_GetTeamByID_notFound(t *testing.T) { client, mux, _, teardown := setup() defer teardown() - mux.HandleFunc("/teams/1", func(w http.ResponseWriter, r *http.Request) { + mux.HandleFunc("/organizations/1/team/2", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") - fmt.Fprint(w, `{"id":1, "name":"n", "description": "d", "url":"u", "slug": "s", "permission":"p", - "parent": {"id":2, "name":"n", "description": "d", "parent": null}}`) + w.WriteHeader(http.StatusNotFound) }) - team, _, err := client.Teams.GetTeam(context.Background(), 1) - if err != nil { - t.Errorf("Teams.GetTeam returned error: %v", err) + team, resp, err := client.Teams.GetTeamByID(context.Background(), 1, 2) + if err == nil { + t.Errorf("Expected HTTP 404 response") } - - want := &Team{ID: Int64(1), Name: String("n"), Description: String("d"), URL: String("u"), Slug: String("s"), Permission: String("p"), - Parent: &Team{ID: Int64(2), Name: String("n"), Description: String("d")}, + if got, want := resp.Response.StatusCode, http.StatusNotFound; got != want { + t.Errorf("Teams.GetTeamByID returned status %d, want %d", got, want) } - if !reflect.DeepEqual(team, want) { - t.Errorf("Teams.GetTeam returned %+v, want %+v", team, want) + if team != nil { + t.Errorf("Teams.GetTeamByID returned %+v, want nil", team) } } @@ -177,13 +174,13 @@ func TestTeamsService_CreateTeam_invalidOrg(t *testing.T) { testURLParseError(t, err) } -func TestTeamsService_EditTeam(t *testing.T) { +func TestTeamsService_EditTeamByID(t *testing.T) { client, mux, _, teardown := setup() defer teardown() input := NewTeam{Name: "n", Privacy: String("closed")} - mux.HandleFunc("/teams/1", func(w http.ResponseWriter, r *http.Request) { + mux.HandleFunc("/organizations/1/team/1", func(w http.ResponseWriter, r *http.Request) { v := new(NewTeam) json.NewDecoder(r.Body).Decode(v) @@ -195,25 +192,25 @@ func TestTeamsService_EditTeam(t *testing.T) { fmt.Fprint(w, `{"id":1}`) }) - team, _, err := client.Teams.EditTeam(context.Background(), 1, input, false) + team, _, err := client.Teams.EditTeamByID(context.Background(), 1, 1, input, false) if err != nil { - t.Errorf("Teams.EditTeam returned error: %v", err) + t.Errorf("Teams.EditTeamByID returned error: %v", err) } want := &Team{ID: Int64(1)} if !reflect.DeepEqual(team, want) { - t.Errorf("Teams.EditTeam returned %+v, want %+v", team, want) + t.Errorf("Teams.EditTeamByID returned %+v, want %+v", team, want) } } -func TestTeamsService_EditTeam_RemoveParent(t *testing.T) { +func TestTeamsService_EditTeamByID_RemoveParent(t *testing.T) { client, mux, _, teardown := setup() defer teardown() input := NewTeam{Name: "n", Privacy: String("closed")} var body string - mux.HandleFunc("/teams/1", func(w http.ResponseWriter, r *http.Request) { + mux.HandleFunc("/organizations/1/team/1", func(w http.ResponseWriter, r *http.Request) { v := new(NewTeam) buf, err := ioutil.ReadAll(r.Body) if err != nil { @@ -230,7 +227,75 @@ func TestTeamsService_EditTeam_RemoveParent(t *testing.T) { fmt.Fprint(w, `{"id":1}`) }) - team, _, err := client.Teams.EditTeam(context.Background(), 1, input, true) + team, _, err := client.Teams.EditTeamByID(context.Background(), 1, 1, input, true) + if err != nil { + t.Errorf("Teams.EditTeamByID returned error: %v", err) + } + + want := &Team{ID: Int64(1)} + if !reflect.DeepEqual(team, want) { + t.Errorf("Teams.EditTeamByID returned %+v, want %+v", team, want) + } + + if want := `{"name":"n","parent_team_id":null,"privacy":"closed"}` + "\n"; body != want { + t.Errorf("Teams.EditTeamByID body = %+v, want %+v", body, want) + } +} + +func TestTeamsService_EditTeamBySlug(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + input := NewTeam{Name: "n", Privacy: String("closed")} + + mux.HandleFunc("/orgs/o/teams/s", func(w http.ResponseWriter, r *http.Request) { + v := new(NewTeam) + json.NewDecoder(r.Body).Decode(v) + + testMethod(t, r, "PATCH") + if !reflect.DeepEqual(v, &input) { + t.Errorf("Request body = %+v, want %+v", v, input) + } + + fmt.Fprint(w, `{"id":1}`) + }) + + team, _, err := client.Teams.EditTeamBySlug(context.Background(), "o", "s", input, false) + if err != nil { + t.Errorf("Teams.EditTeamBySlug returned error: %v", err) + } + + want := &Team{ID: Int64(1)} + if !reflect.DeepEqual(team, want) { + t.Errorf("Teams.EditTeamBySlug returned %+v, want %+v", team, want) + } +} + +func TestTeamsService_EditTeamBySlug_RemoveParent(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + input := NewTeam{Name: "n", Privacy: String("closed")} + var body string + + mux.HandleFunc("/orgs/o/teams/s", func(w http.ResponseWriter, r *http.Request) { + v := new(NewTeam) + buf, err := ioutil.ReadAll(r.Body) + if err != nil { + t.Errorf("Unable to read body: %v", err) + } + body = string(buf) + json.NewDecoder(bytes.NewBuffer(buf)).Decode(v) + + testMethod(t, r, "PATCH") + if !reflect.DeepEqual(v, &input) { + t.Errorf("Request body = %+v, want %+v", v, input) + } + + fmt.Fprint(w, `{"id":1}`) + }) + + team, _, err := client.Teams.EditTeamBySlug(context.Background(), "o", "s", input, true) if err != nil { t.Errorf("Teams.EditTeam returned error: %v", err) } @@ -245,47 +310,83 @@ func TestTeamsService_EditTeam_RemoveParent(t *testing.T) { } } -func TestTeamsService_DeleteTeam(t *testing.T) { +func TestTeamsService_DeleteTeamByID(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/organizations/1/team/1", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "DELETE") + }) + + _, err := client.Teams.DeleteTeamByID(context.Background(), 1, 1) + if err != nil { + t.Errorf("Teams.DeleteTeamByID returned error: %v", err) + } +} + +func TestTeamsService_DeleteTeamBySlug(t *testing.T) { client, mux, _, teardown := setup() defer teardown() - mux.HandleFunc("/teams/1", func(w http.ResponseWriter, r *http.Request) { + mux.HandleFunc("/orgs/o/teams/s", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "DELETE") }) - _, err := client.Teams.DeleteTeam(context.Background(), 1) + _, err := client.Teams.DeleteTeamBySlug(context.Background(), "o", "s") if err != nil { - t.Errorf("Teams.DeleteTeam returned error: %v", err) + t.Errorf("Teams.DeleteTeamBySlug returned error: %v", err) } } -func TestTeamsService_ListChildTeams(t *testing.T) { +func TestTeamsService_ListChildTeamsByParentID(t *testing.T) { client, mux, _, teardown := setup() defer teardown() - mux.HandleFunc("/teams/1/teams", func(w http.ResponseWriter, r *http.Request) { + mux.HandleFunc("/organizations/1/team/2/teams", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") testFormValues(t, r, values{"page": "2"}) fmt.Fprint(w, `[{"id":2}]`) }) opt := &ListOptions{Page: 2} - teams, _, err := client.Teams.ListChildTeams(context.Background(), 1, opt) + teams, _, err := client.Teams.ListChildTeamsByParentID(context.Background(), 1, 2, opt) if err != nil { - t.Errorf("Teams.ListTeams returned error: %v", err) + t.Errorf("Teams.ListChildTeamsByParentID returned error: %v", err) } want := []*Team{{ID: Int64(2)}} if !reflect.DeepEqual(teams, want) { - t.Errorf("Teams.ListTeams returned %+v, want %+v", teams, want) + t.Errorf("Teams.ListChildTeamsByParentID returned %+v, want %+v", teams, want) } } -func TestTeamsService_ListTeamRepos(t *testing.T) { +func TestTeamsService_ListChildTeamsByParentSlug(t *testing.T) { client, mux, _, teardown := setup() defer teardown() - mux.HandleFunc("/teams/1/repos", func(w http.ResponseWriter, r *http.Request) { + mux.HandleFunc("/orgs/o/teams/s/teams", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + testFormValues(t, r, values{"page": "2"}) + fmt.Fprint(w, `[{"id":2}]`) + }) + + opt := &ListOptions{Page: 2} + teams, _, err := client.Teams.ListChildTeamsByParentSlug(context.Background(), "o", "s", opt) + if err != nil { + t.Errorf("Teams.ListChildTeamsByParentSlug returned error: %v", err) + } + + want := []*Team{{ID: Int64(2)}} + if !reflect.DeepEqual(teams, want) { + t.Errorf("Teams.ListChildTeamsByParentSlug returned %+v, want %+v", teams, want) + } +} + +func TestTeamsService_ListTeamReposByID(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/organizations/1/team/1/repos", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") wantAcceptHeaders := []string{mediaTypeTopicsPreview} testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", ")) @@ -294,96 +395,192 @@ func TestTeamsService_ListTeamRepos(t *testing.T) { }) opt := &ListOptions{Page: 2} - members, _, err := client.Teams.ListTeamRepos(context.Background(), 1, opt) + members, _, err := client.Teams.ListTeamReposByID(context.Background(), 1, 1, opt) if err != nil { - t.Errorf("Teams.ListTeamRepos returned error: %v", err) + t.Errorf("Teams.ListTeamReposByID returned error: %v", err) } want := []*Repository{{ID: Int64(1)}} if !reflect.DeepEqual(members, want) { - t.Errorf("Teams.ListTeamRepos returned %+v, want %+v", members, want) + t.Errorf("Teams.ListTeamReposByID returned %+v, want %+v", members, want) } } -func TestTeamsService_IsTeamRepo_true(t *testing.T) { +func TestTeamsService_ListTeamReposBySlug(t *testing.T) { client, mux, _, teardown := setup() defer teardown() - mux.HandleFunc("/teams/1/repos/o/r", func(w http.ResponseWriter, r *http.Request) { + mux.HandleFunc("/orgs/o/teams/s/repos", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + wantAcceptHeaders := []string{mediaTypeTopicsPreview} + testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", ")) + testFormValues(t, r, values{"page": "2"}) + fmt.Fprint(w, `[{"id":1}]`) + }) + + opt := &ListOptions{Page: 2} + members, _, err := client.Teams.ListTeamReposBySlug(context.Background(), "o", "s", opt) + if err != nil { + t.Errorf("Teams.ListTeamReposBySlug returned error: %v", err) + } + + want := []*Repository{{ID: Int64(1)}} + if !reflect.DeepEqual(members, want) { + t.Errorf("Teams.ListTeamReposBySlug returned %+v, want %+v", members, want) + } +} + +func TestTeamsService_IsTeamRepoByID_true(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/organizations/1/team/1/repos/owner/repo", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + wantAcceptHeaders := []string{mediaTypeOrgPermissionRepo} + testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", ")) + fmt.Fprint(w, `{"id":1}`) + }) + + repo, _, err := client.Teams.IsTeamRepoByID(context.Background(), 1, 1, "owner", "repo") + if err != nil { + t.Errorf("Teams.IsTeamRepoByID returned error: %v", err) + } + + want := &Repository{ID: Int64(1)} + if !reflect.DeepEqual(repo, want) { + t.Errorf("Teams.IsTeamRepoByID returned %+v, want %+v", repo, want) + } +} + +func TestTeamsService_IsTeamRepoBySlug_true(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/orgs/org/teams/slug/repos/owner/repo", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") wantAcceptHeaders := []string{mediaTypeOrgPermissionRepo} testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", ")) fmt.Fprint(w, `{"id":1}`) }) - repo, _, err := client.Teams.IsTeamRepo(context.Background(), 1, "o", "r") + repo, _, err := client.Teams.IsTeamRepoBySlug(context.Background(), "org", "slug", "owner", "repo") if err != nil { - t.Errorf("Teams.IsTeamRepo returned error: %v", err) + t.Errorf("Teams.IsTeamRepoBySlug returned error: %v", err) } want := &Repository{ID: Int64(1)} if !reflect.DeepEqual(repo, want) { - t.Errorf("Teams.IsTeamRepo returned %+v, want %+v", repo, want) + t.Errorf("Teams.IsTeamRepoBySlug returned %+v, want %+v", repo, want) + } +} + +func TestTeamsService_IsTeamRepoByID_false(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/organizations/1/team/1/repos/owner/repo", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + w.WriteHeader(http.StatusNotFound) + }) + + repo, resp, err := client.Teams.IsTeamRepoByID(context.Background(), 1, 1, "owner", "repo") + if err == nil { + t.Errorf("Expected HTTP 404 response") + } + if got, want := resp.Response.StatusCode, http.StatusNotFound; got != want { + t.Errorf("Teams.IsTeamRepoByID returned status %d, want %d", got, want) + } + if repo != nil { + t.Errorf("Teams.IsTeamRepoByID returned %+v, want nil", repo) } } -func TestTeamsService_IsTeamRepo_false(t *testing.T) { +func TestTeamsService_IsTeamRepoBySlug_false(t *testing.T) { client, mux, _, teardown := setup() defer teardown() - mux.HandleFunc("/teams/1/repos/o/r", func(w http.ResponseWriter, r *http.Request) { + mux.HandleFunc("/orgs/org/teams/slug/repos/o/r", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") w.WriteHeader(http.StatusNotFound) }) - repo, resp, err := client.Teams.IsTeamRepo(context.Background(), 1, "o", "r") + repo, resp, err := client.Teams.IsTeamRepoBySlug(context.Background(), "org", "slug", "owner", "repo") if err == nil { t.Errorf("Expected HTTP 404 response") } if got, want := resp.Response.StatusCode, http.StatusNotFound; got != want { - t.Errorf("Teams.IsTeamRepo returned status %d, want %d", got, want) + t.Errorf("Teams.IsTeamRepoByID returned status %d, want %d", got, want) } if repo != nil { - t.Errorf("Teams.IsTeamRepo returned %+v, want nil", repo) + t.Errorf("Teams.IsTeamRepoByID returned %+v, want nil", repo) } } -func TestTeamsService_IsTeamRepo_error(t *testing.T) { +func TestTeamsService_IsTeamRepoByID_error(t *testing.T) { client, mux, _, teardown := setup() defer teardown() - mux.HandleFunc("/teams/1/repos/o/r", func(w http.ResponseWriter, r *http.Request) { + mux.HandleFunc("/organizations/1/team/1/repos/owner/repo", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") http.Error(w, "BadRequest", http.StatusBadRequest) }) - repo, resp, err := client.Teams.IsTeamRepo(context.Background(), 1, "o", "r") + repo, resp, err := client.Teams.IsTeamRepoByID(context.Background(), 1, 1, "owner", "repo") if err == nil { t.Errorf("Expected HTTP 400 response") } if got, want := resp.Response.StatusCode, http.StatusBadRequest; got != want { - t.Errorf("Teams.IsTeamRepo returned status %d, want %d", got, want) + t.Errorf("Teams.IsTeamRepoByID returned status %d, want %d", got, want) } if repo != nil { - t.Errorf("Teams.IsTeamRepo returned %+v, want nil", repo) + t.Errorf("Teams.IsTeamRepoByID returned %+v, want nil", repo) } } -func TestTeamsService_IsTeamRepo_invalidOwner(t *testing.T) { +func TestTeamsService_IsTeamRepoBySlug_error(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/orgs/org/teams/slug/repos/owner/repo", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + http.Error(w, "BadRequest", http.StatusBadRequest) + }) + + repo, resp, err := client.Teams.IsTeamRepoBySlug(context.Background(), "org", "slug", "owner", "repo") + if err == nil { + t.Errorf("Expected HTTP 400 response") + } + if got, want := resp.Response.StatusCode, http.StatusBadRequest; got != want { + t.Errorf("Teams.IsTeamRepoBySlug returned status %d, want %d", got, want) + } + if repo != nil { + t.Errorf("Teams.IsTeamRepoBySlug returned %+v, want nil", repo) + } +} + +func TestTeamsService_IsTeamRepoByID_invalidOwner(t *testing.T) { client, _, _, teardown := setup() defer teardown() - _, _, err := client.Teams.IsTeamRepo(context.Background(), 1, "%", "r") + _, _, err := client.Teams.IsTeamRepoByID(context.Background(), 1, 1, "%", "r") testURLParseError(t, err) } -func TestTeamsService_AddTeamRepo(t *testing.T) { +func TestTeamsService_IsTeamRepoBySlug_invalidOwner(t *testing.T) { + client, _, _, teardown := setup() + defer teardown() + + _, _, err := client.Teams.IsTeamRepoBySlug(context.Background(), "o", "s", "%", "r") + testURLParseError(t, err) +} + +func TestTeamsService_AddTeamRepoByID(t *testing.T) { client, mux, _, teardown := setup() defer teardown() opt := &TeamAddTeamRepoOptions{Permission: "admin"} - mux.HandleFunc("/teams/1/repos/o/r", func(w http.ResponseWriter, r *http.Request) { + mux.HandleFunc("/organizations/1/team/1/repos/owner/repo", func(w http.ResponseWriter, r *http.Request) { v := new(TeamAddTeamRepoOptions) json.NewDecoder(r.Body).Decode(v) @@ -395,55 +592,125 @@ func TestTeamsService_AddTeamRepo(t *testing.T) { w.WriteHeader(http.StatusNoContent) }) - _, err := client.Teams.AddTeamRepo(context.Background(), 1, "o", "r", opt) + _, err := client.Teams.AddTeamRepoByID(context.Background(), 1, 1, "owner", "repo", opt) if err != nil { - t.Errorf("Teams.AddTeamRepo returned error: %v", err) + t.Errorf("Teams.AddTeamRepoByID returned error: %v", err) } } -func TestTeamsService_AddTeamRepo_noAccess(t *testing.T) { +func TestTeamsService_AddTeamRepoBySlug(t *testing.T) { client, mux, _, teardown := setup() defer teardown() - mux.HandleFunc("/teams/1/repos/o/r", func(w http.ResponseWriter, r *http.Request) { + opt := &TeamAddTeamRepoOptions{Permission: "admin"} + + mux.HandleFunc("/orgs/org/teams/slug/repos/owner/repo", func(w http.ResponseWriter, r *http.Request) { + v := new(TeamAddTeamRepoOptions) + json.NewDecoder(r.Body).Decode(v) + + testMethod(t, r, "PUT") + if !reflect.DeepEqual(v, opt) { + t.Errorf("Request body = %+v, want %+v", v, opt) + } + + w.WriteHeader(http.StatusNoContent) + }) + + _, err := client.Teams.AddTeamRepoBySlug(context.Background(), "org", "slug", "owner", "repo", opt) + if err != nil { + t.Errorf("Teams.AddTeamRepoBySlug returned error: %v", err) + } +} + +func TestTeamsService_AddTeamRepoByID_noAccess(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/organizations/1/team/1/repos/owner/repo", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "PUT") + w.WriteHeader(http.StatusUnprocessableEntity) + }) + + _, err := client.Teams.AddTeamRepoByID(context.Background(), 1, 1, "owner", "repo", nil) + if err == nil { + t.Errorf("Expcted error to be returned") + } +} + +func TestTeamsService_AddTeamRepoBySlug_noAccess(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/orgs/org/teams/slug/repos/o/r", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "PUT") w.WriteHeader(http.StatusUnprocessableEntity) }) - _, err := client.Teams.AddTeamRepo(context.Background(), 1, "o", "r", nil) + _, err := client.Teams.AddTeamRepoBySlug(context.Background(), "org", "slug", "owner", "repo", nil) if err == nil { t.Errorf("Expcted error to be returned") } } -func TestTeamsService_AddTeamRepo_invalidOwner(t *testing.T) { +func TestTeamsService_AddTeamRepoByID_invalidOwner(t *testing.T) { + client, _, _, teardown := setup() + defer teardown() + + _, err := client.Teams.AddTeamRepoByID(context.Background(), 1, 1, "%", "r", nil) + testURLParseError(t, err) +} + +func TestTeamsService_AddTeamRepoBySlug_invalidOwner(t *testing.T) { client, _, _, teardown := setup() defer teardown() - _, err := client.Teams.AddTeamRepo(context.Background(), 1, "%", "r", nil) + _, err := client.Teams.AddTeamRepoBySlug(context.Background(), "o", "s", "%", "r", nil) testURLParseError(t, err) } -func TestTeamsService_RemoveTeamRepo(t *testing.T) { +func TestTeamsService_RemoveTeamRepoByID(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/organizations/1/team/1/repos/owner/repo", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "DELETE") + w.WriteHeader(http.StatusNoContent) + }) + + _, err := client.Teams.RemoveTeamRepoByID(context.Background(), 1, 1, "owner", "repo") + if err != nil { + t.Errorf("Teams.RemoveTeamRepoByID returned error: %v", err) + } +} + +func TestTeamsService_RemoveTeamRepoBySlug(t *testing.T) { client, mux, _, teardown := setup() defer teardown() - mux.HandleFunc("/teams/1/repos/o/r", func(w http.ResponseWriter, r *http.Request) { + mux.HandleFunc("/orgs/org/teams/slug/repos/owner/repo", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "DELETE") w.WriteHeader(http.StatusNoContent) }) - _, err := client.Teams.RemoveTeamRepo(context.Background(), 1, "o", "r") + _, err := client.Teams.RemoveTeamRepoBySlug(context.Background(), "org", "slug", "owner", "repo") if err != nil { - t.Errorf("Teams.RemoveTeamRepo returned error: %v", err) + t.Errorf("Teams.RemoveTeamRepoBySlug returned error: %v", err) } } -func TestTeamsService_RemoveTeamRepo_invalidOwner(t *testing.T) { +func TestTeamsService_RemoveTeamRepoByID_invalidOwner(t *testing.T) { + client, _, _, teardown := setup() + defer teardown() + + _, err := client.Teams.RemoveTeamRepoByID(context.Background(), 1, 1, "%", "r") + testURLParseError(t, err) +} + +func TestTeamsService_RemoveTeamRepoBySlug_invalidOwner(t *testing.T) { client, _, _, teardown := setup() defer teardown() - _, err := client.Teams.RemoveTeamRepo(context.Background(), 1, "%", "r") + _, err := client.Teams.RemoveTeamRepoBySlug(context.Background(), "o", "s", "%", "r") testURLParseError(t, err) } @@ -469,128 +736,95 @@ func TestTeamsService_ListUserTeams(t *testing.T) { } } -func TestTeamsService_ListPendingTeamInvitations(t *testing.T) { +func TestTeamsService_ListProjectsByID(t *testing.T) { client, mux, _, teardown := setup() defer teardown() - mux.HandleFunc("/teams/1/invitations", func(w http.ResponseWriter, r *http.Request) { + wantAcceptHeaders := []string{mediaTypeProjectsPreview} + mux.HandleFunc("/organizations/1/team/1/projects", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") - testFormValues(t, r, values{"page": "1"}) - fmt.Fprint(w, `[ - { - "id": 1, - "login": "monalisa", - "email": "octocat@github.com", - "role": "direct_member", - "created_at": "2017-01-21T00:00:00Z", - "inviter": { - "login": "other_user", - "id": 1, - "avatar_url": "https://github.com/images/error/other_user_happy.gif", - "gravatar_id": "", - "url": "https://api.github.com/users/other_user", - "html_url": "https://github.com/other_user", - "followers_url": "https://api.github.com/users/other_user/followers", - "following_url": "https://api.github.com/users/other_user/following/other_user", - "gists_url": "https://api.github.com/users/other_user/gists/gist_id", - "starred_url": "https://api.github.com/users/other_user/starred/owner/repo", - "subscriptions_url": "https://api.github.com/users/other_user/subscriptions", - "organizations_url": "https://api.github.com/users/other_user/orgs", - "repos_url": "https://api.github.com/users/other_user/repos", - "events_url": "https://api.github.com/users/other_user/events/privacy", - "received_events_url": "https://api.github.com/users/other_user/received_events/privacy", - "type": "User", - "site_admin": false - } - } - ]`) + testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", ")) + fmt.Fprint(w, `[{"id":1}]`) }) - opt := &ListOptions{Page: 1} - invitations, _, err := client.Teams.ListPendingTeamInvitations(context.Background(), 1, opt) - if err != nil { - t.Errorf("Teams.ListPendingTeamInvitations returned error: %v", err) - } - - createdAt := time.Date(2017, time.January, 21, 0, 0, 0, 0, time.UTC) - want := []*Invitation{ - { - ID: Int64(1), - Login: String("monalisa"), - Email: String("octocat@github.com"), - Role: String("direct_member"), - CreatedAt: &createdAt, - Inviter: &User{ - Login: String("other_user"), - ID: Int64(1), - AvatarURL: String("https://github.com/images/error/other_user_happy.gif"), - GravatarID: String(""), - URL: String("https://api.github.com/users/other_user"), - HTMLURL: String("https://github.com/other_user"), - FollowersURL: String("https://api.github.com/users/other_user/followers"), - FollowingURL: String("https://api.github.com/users/other_user/following/other_user"), - GistsURL: String("https://api.github.com/users/other_user/gists/gist_id"), - StarredURL: String("https://api.github.com/users/other_user/starred/owner/repo"), - SubscriptionsURL: String("https://api.github.com/users/other_user/subscriptions"), - OrganizationsURL: String("https://api.github.com/users/other_user/orgs"), - ReposURL: String("https://api.github.com/users/other_user/repos"), - EventsURL: String("https://api.github.com/users/other_user/events/privacy"), - ReceivedEventsURL: String("https://api.github.com/users/other_user/received_events/privacy"), - Type: String("User"), - SiteAdmin: Bool(false), - }, - }} + projects, _, err := client.Teams.ListTeamProjectsByID(context.Background(), 1, 1) + if err != nil { + t.Errorf("Teams.ListTeamProjectsByID returned error: %v", err) + } - if !reflect.DeepEqual(invitations, want) { - t.Errorf("Teams.ListPendingTeamInvitations returned %+v, want %+v", invitations, want) + want := []*Project{{ID: Int64(1)}} + if !reflect.DeepEqual(projects, want) { + t.Errorf("Teams.ListTeamProjectsByID returned %+v, want %+v", projects, want) } } -func TestTeamsService_ListProjects(t *testing.T) { +func TestTeamsService_ListProjectsBySlug(t *testing.T) { client, mux, _, teardown := setup() defer teardown() wantAcceptHeaders := []string{mediaTypeProjectsPreview} - mux.HandleFunc("/teams/1/projects", func(w http.ResponseWriter, r *http.Request) { + mux.HandleFunc("/orgs/o/teams/s/projects", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", ")) fmt.Fprint(w, `[{"id":1}]`) }) - projects, _, err := client.Teams.ListTeamProjects(context.Background(), 1) + projects, _, err := client.Teams.ListTeamProjectsBySlug(context.Background(), "o", "s") if err != nil { - t.Errorf("Teams.ListTeamProjects returned error: %v", err) + t.Errorf("Teams.ListTeamProjectsBySlug returned error: %v", err) } want := []*Project{{ID: Int64(1)}} if !reflect.DeepEqual(projects, want) { - t.Errorf("Teams.ListTeamProjects returned %+v, want %+v", projects, want) + t.Errorf("Teams.ListTeamProjectsBySlug returned %+v, want %+v", projects, want) } } -func TestTeamsService_ReviewProjects(t *testing.T) { +func TestTeamsService_ReviewProjectsByID(t *testing.T) { client, mux, _, teardown := setup() defer teardown() wantAcceptHeaders := []string{mediaTypeProjectsPreview} - mux.HandleFunc("/teams/1/projects/1", func(w http.ResponseWriter, r *http.Request) { + mux.HandleFunc("/organizations/1/team/1/projects/1", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", ")) fmt.Fprint(w, `{"id":1}`) }) - project, _, err := client.Teams.ReviewTeamProjects(context.Background(), 1, 1) + project, _, err := client.Teams.ReviewTeamProjectsByID(context.Background(), 1, 1, 1) if err != nil { - t.Errorf("Teams.ReviewTeamProjects returned error: %v", err) + t.Errorf("Teams.ReviewTeamProjectsByID returned error: %v", err) } want := &Project{ID: Int64(1)} if !reflect.DeepEqual(project, want) { - t.Errorf("Teams.ReviewTeamProjects returned %+v, want %+v", project, want) + t.Errorf("Teams.ReviewTeamProjectsByID returned %+v, want %+v", project, want) } } -func TestTeamsService_AddTeamProject(t *testing.T) { +func TestTeamsService_ReviewProjectsBySlug(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + wantAcceptHeaders := []string{mediaTypeProjectsPreview} + mux.HandleFunc("/orgs/o/teams/s/projects/1", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", ")) + fmt.Fprint(w, `{"id":1}`) + }) + + project, _, err := client.Teams.ReviewTeamProjectsBySlug(context.Background(), "o", "s", 1) + if err != nil { + t.Errorf("Teams.ReviewTeamProjectsBySlug returned error: %v", err) + } + + want := &Project{ID: Int64(1)} + if !reflect.DeepEqual(project, want) { + t.Errorf("Teams.ReviewTeamProjectsBySlug returned %+v, want %+v", project, want) + } +} + +func TestTeamsService_AddTeamProjectByID(t *testing.T) { client, mux, _, teardown := setup() defer teardown() @@ -599,7 +833,7 @@ func TestTeamsService_AddTeamProject(t *testing.T) { } wantAcceptHeaders := []string{mediaTypeProjectsPreview} - mux.HandleFunc("/teams/1/projects/1", func(w http.ResponseWriter, r *http.Request) { + mux.HandleFunc("/organizations/1/team/1/projects/1", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "PUT") testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", ")) @@ -612,26 +846,71 @@ func TestTeamsService_AddTeamProject(t *testing.T) { w.WriteHeader(http.StatusNoContent) }) - _, err := client.Teams.AddTeamProject(context.Background(), 1, 1, opt) + _, err := client.Teams.AddTeamProjectByID(context.Background(), 1, 1, 1, opt) + if err != nil { + t.Errorf("Teams.AddTeamProjectByID returned error: %v", err) + } +} + +func TestTeamsService_AddTeamProjectBySlug(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + opt := &TeamProjectOptions{ + Permission: String("admin"), + } + + wantAcceptHeaders := []string{mediaTypeProjectsPreview} + mux.HandleFunc("/orgs/o/teams/s/projects/1", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "PUT") + testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", ")) + + v := &TeamProjectOptions{} + json.NewDecoder(r.Body).Decode(v) + if !reflect.DeepEqual(v, opt) { + t.Errorf("Request body = %+v, want %+v", v, opt) + } + + w.WriteHeader(http.StatusNoContent) + }) + + _, err := client.Teams.AddTeamProjectBySlug(context.Background(), "o", "s", 1, opt) + if err != nil { + t.Errorf("Teams.AddTeamProjectBySlug returned error: %v", err) + } +} + +func TestTeamsService_RemoveTeamProjectByID(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + wantAcceptHeaders := []string{mediaTypeProjectsPreview} + mux.HandleFunc("/organizations/1/team/1/projects/1", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "DELETE") + testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", ")) + w.WriteHeader(http.StatusNoContent) + }) + + _, err := client.Teams.RemoveTeamProjectByID(context.Background(), 1, 1, 1) if err != nil { - t.Errorf("Teams.AddTeamProject returned error: %v", err) + t.Errorf("Teams.RemoveTeamProjectByID returned error: %v", err) } } -func TestTeamsService_RemoveTeamProject(t *testing.T) { +func TestTeamsService_RemoveTeamProjectBySlug(t *testing.T) { client, mux, _, teardown := setup() defer teardown() wantAcceptHeaders := []string{mediaTypeProjectsPreview} - mux.HandleFunc("/teams/1/projects/1", func(w http.ResponseWriter, r *http.Request) { + mux.HandleFunc("/orgs/o/teams/s/projects/1", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "DELETE") testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", ")) w.WriteHeader(http.StatusNoContent) }) - _, err := client.Teams.RemoveTeamProject(context.Background(), 1, 1) + _, err := client.Teams.RemoveTeamProjectBySlug(context.Background(), "o", "s", 1) if err != nil { - t.Errorf("Teams.RemoveTeamProject returned error: %v", err) + t.Errorf("Teams.RemoveTeamProjectBySlug returned error: %v", err) } } From 2f9ce45df20025dc1f2b50e6aa8b751eb1746b92 Mon Sep 17 00:00:00 2001 From: Glenn Lewis <6598971+gmlewis@users.noreply.github.com> Date: Sat, 22 Feb 2020 09:40:33 -0500 Subject: [PATCH 0132/1468] Switch Workflow to pointers (#1437) --- github/actions_workflows.go | 24 ++++----- github/actions_workflows_test.go | 18 +++---- github/github-accessors.go | 88 ++++++++++++++++++++++++++++++++ 3 files changed, 109 insertions(+), 21 deletions(-) diff --git a/github/actions_workflows.go b/github/actions_workflows.go index fc4cf4a531a..9743f5072ba 100644 --- a/github/actions_workflows.go +++ b/github/actions_workflows.go @@ -12,22 +12,22 @@ import ( // Workflow represents a repository action workflow. type Workflow struct { - ID int64 `json:"id"` - NodeID string `json:"node_id"` - Name string `json:"name"` - Path string `json:"path"` - State string `json:"state"` - CreatedAt Timestamp `json:"created_at"` - UpdatedAt Timestamp `json:"updated_at"` - URL string `json:"url"` - HTMLURL string `json:"html_url"` - BadgeURL string `json:"badge_url"` + ID *int64 `json:"id,omitempty"` + NodeID *string `json:"node_id,omitempty"` + Name *string `json:"name,omitempty"` + Path *string `json:"path,omitempty"` + State *string `json:"state,omitempty"` + CreatedAt *Timestamp `json:"created_at,omitempty"` + UpdatedAt *Timestamp `json:"updated_at,omitempty"` + URL *string `json:"url,omitempty"` + HTMLURL *string `json:"html_url,omitempty"` + BadgeURL *string `json:"badge_url,omitempty"` } // Workflows represents a slice of repository action workflows. type Workflows struct { - TotalCount int `json:"total_count"` - Workflows []*Workflow `json:"workflows"` + TotalCount *int `json:"total_count,omitempty"` + Workflows []*Workflow `json:"workflows,omitempty"` } // ListWorkflows lists all workflows in a repository. diff --git a/github/actions_workflows_test.go b/github/actions_workflows_test.go index 8d9f9232487..e9448645ecf 100644 --- a/github/actions_workflows_test.go +++ b/github/actions_workflows_test.go @@ -31,10 +31,10 @@ func TestActionsService_ListWorkflows(t *testing.T) { } want := &Workflows{ - TotalCount: 4, + TotalCount: Int(4), Workflows: []*Workflow{ - {ID: 72844, CreatedAt: Timestamp{time.Date(2019, time.January, 02, 15, 04, 05, 0, time.UTC)}, UpdatedAt: Timestamp{time.Date(2020, time.January, 02, 15, 04, 05, 0, time.UTC)}}, - {ID: 72845, CreatedAt: Timestamp{time.Date(2019, time.January, 02, 15, 04, 05, 0, time.UTC)}, UpdatedAt: Timestamp{time.Date(2020, time.January, 02, 15, 04, 05, 0, time.UTC)}}, + {ID: Int64(72844), CreatedAt: &Timestamp{time.Date(2019, time.January, 02, 15, 04, 05, 0, time.UTC)}, UpdatedAt: &Timestamp{time.Date(2020, time.January, 02, 15, 04, 05, 0, time.UTC)}}, + {ID: Int64(72845), CreatedAt: &Timestamp{time.Date(2019, time.January, 02, 15, 04, 05, 0, time.UTC)}, UpdatedAt: &Timestamp{time.Date(2020, time.January, 02, 15, 04, 05, 0, time.UTC)}}, }, } if !reflect.DeepEqual(workflows, want) { @@ -57,9 +57,9 @@ func TestActionsService_GetWorkflowByID(t *testing.T) { } want := &Workflow{ - ID: 72844, - CreatedAt: Timestamp{time.Date(2019, time.January, 02, 15, 04, 05, 0, time.UTC)}, - UpdatedAt: Timestamp{time.Date(2020, time.January, 02, 15, 04, 05, 0, time.UTC)}, + ID: Int64(72844), + CreatedAt: &Timestamp{time.Date(2019, time.January, 02, 15, 04, 05, 0, time.UTC)}, + UpdatedAt: &Timestamp{time.Date(2020, time.January, 02, 15, 04, 05, 0, time.UTC)}, } if !reflect.DeepEqual(workflow, want) { t.Errorf("Actions.GetWorkflowByID returned %+v, want %+v", workflow, want) @@ -81,9 +81,9 @@ func TestActionsService_GetWorkflowByFileName(t *testing.T) { } want := &Workflow{ - ID: 72844, - CreatedAt: Timestamp{time.Date(2019, time.January, 02, 15, 04, 05, 0, time.UTC)}, - UpdatedAt: Timestamp{time.Date(2020, time.January, 02, 15, 04, 05, 0, time.UTC)}, + ID: Int64(72844), + CreatedAt: &Timestamp{time.Date(2019, time.January, 02, 15, 04, 05, 0, time.UTC)}, + UpdatedAt: &Timestamp{time.Date(2020, time.January, 02, 15, 04, 05, 0, time.UTC)}, } if !reflect.DeepEqual(workflow, want) { t.Errorf("Actions.GetWorkflowByFileName returned %+v, want %+v", workflow, want) diff --git a/github/github-accessors.go b/github/github-accessors.go index 212e334b460..a1f3e0c19a3 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -13851,3 +13851,91 @@ func (w *WeeklyStats) GetWeek() Timestamp { } return *w.Week } + +// GetBadgeURL returns the BadgeURL field if it's non-nil, zero value otherwise. +func (w *Workflow) GetBadgeURL() string { + if w == nil || w.BadgeURL == nil { + return "" + } + return *w.BadgeURL +} + +// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise. +func (w *Workflow) GetCreatedAt() Timestamp { + if w == nil || w.CreatedAt == nil { + return Timestamp{} + } + return *w.CreatedAt +} + +// GetHTMLURL returns the HTMLURL field if it's non-nil, zero value otherwise. +func (w *Workflow) GetHTMLURL() string { + if w == nil || w.HTMLURL == nil { + return "" + } + return *w.HTMLURL +} + +// GetID returns the ID field if it's non-nil, zero value otherwise. +func (w *Workflow) GetID() int64 { + if w == nil || w.ID == nil { + return 0 + } + return *w.ID +} + +// GetName returns the Name field if it's non-nil, zero value otherwise. +func (w *Workflow) GetName() string { + if w == nil || w.Name == nil { + return "" + } + return *w.Name +} + +// GetNodeID returns the NodeID field if it's non-nil, zero value otherwise. +func (w *Workflow) GetNodeID() string { + if w == nil || w.NodeID == nil { + return "" + } + return *w.NodeID +} + +// GetPath returns the Path field if it's non-nil, zero value otherwise. +func (w *Workflow) GetPath() string { + if w == nil || w.Path == nil { + return "" + } + return *w.Path +} + +// GetState returns the State field if it's non-nil, zero value otherwise. +func (w *Workflow) GetState() string { + if w == nil || w.State == nil { + return "" + } + return *w.State +} + +// GetUpdatedAt returns the UpdatedAt field if it's non-nil, zero value otherwise. +func (w *Workflow) GetUpdatedAt() Timestamp { + if w == nil || w.UpdatedAt == nil { + return Timestamp{} + } + return *w.UpdatedAt +} + +// GetURL returns the URL field if it's non-nil, zero value otherwise. +func (w *Workflow) GetURL() string { + if w == nil || w.URL == nil { + return "" + } + return *w.URL +} + +// GetTotalCount returns the TotalCount field if it's non-nil, zero value otherwise. +func (w *Workflows) GetTotalCount() int { + if w == nil || w.TotalCount == nil { + return 0 + } + return *w.TotalCount +} From cb1e3f4500d1e79bda820c14abc74c59bb6de96f Mon Sep 17 00:00:00 2001 From: Hanno Hecker Date: Sat, 22 Feb 2020 15:44:04 +0100 Subject: [PATCH 0133/1468] Do not encode / in ref names (#1433) Fixes: #1432. --- github/checks.go | 5 ++--- github/git_refs.go | 16 ++++++++++++--- github/git_refs_test.go | 28 ++++++++++++++++++++++++++ github/repos_commits.go | 3 +-- github/repos_commits_test.go | 39 ++++++++++++++++++++++++++++++++++++ github/repos_statuses.go | 7 +++---- 6 files changed, 86 insertions(+), 12 deletions(-) diff --git a/github/checks.go b/github/checks.go index 55adf14ea16..67b7e770217 100644 --- a/github/checks.go +++ b/github/checks.go @@ -8,7 +8,6 @@ package github import ( "context" "fmt" - "net/url" ) // ChecksService provides access to the Checks API in the @@ -258,7 +257,7 @@ type ListCheckRunsResults struct { // // GitHub API docs: https://developer.github.com/v3/checks/runs/#list-check-runs-for-a-specific-ref func (s *ChecksService) ListCheckRunsForRef(ctx context.Context, owner, repo, ref string, opts *ListCheckRunsOptions) (*ListCheckRunsResults, *Response, error) { - u := fmt.Sprintf("repos/%v/%v/commits/%v/check-runs", owner, repo, url.QueryEscape(ref)) + u := fmt.Sprintf("repos/%v/%v/commits/%v/check-runs", owner, repo, refURLEscape(ref)) u, err := addOptions(u, opts) if err != nil { return nil, nil, err @@ -324,7 +323,7 @@ type ListCheckSuiteResults struct { // // GitHub API docs: https://developer.github.com/v3/checks/suites/#list-check-suites-for-a-specific-ref func (s *ChecksService) ListCheckSuitesForRef(ctx context.Context, owner, repo, ref string, opts *ListCheckSuiteOptions) (*ListCheckSuiteResults, *Response, error) { - u := fmt.Sprintf("repos/%v/%v/commits/%v/check-suites", owner, repo, url.QueryEscape(ref)) + u := fmt.Sprintf("repos/%v/%v/commits/%v/check-suites", owner, repo, refURLEscape(ref)) u, err := addOptions(u, opts) if err != nil { return nil, nil, err diff --git a/github/git_refs.go b/github/git_refs.go index 18494dae33e..a6269e5a9e4 100644 --- a/github/git_refs.go +++ b/github/git_refs.go @@ -58,7 +58,7 @@ type updateRefRequest struct { // GitHub API docs: https://developer.github.com/v3/git/refs/#get-a-reference func (s *GitService) GetRef(ctx context.Context, owner string, repo string, ref string) (*Reference, *Response, error) { ref = strings.TrimPrefix(ref, "refs/") - u := fmt.Sprintf("repos/%v/%v/git/refs/%v", owner, repo, url.QueryEscape(ref)) + u := fmt.Sprintf("repos/%v/%v/git/refs/%v", owner, repo, refURLEscape(ref)) req, err := s.client.NewRequest("GET", u, nil) if err != nil { return nil, nil, err @@ -79,6 +79,16 @@ func (s *GitService) GetRef(ctx context.Context, owner string, repo string, ref return r, resp, nil } +// refURLEscape escapes every path segment of the given ref. Those must +// not contain escaped "/" - as "%2F" - or github will not recognize it. +func refURLEscape(ref string) string { + parts := strings.Split(ref, "/") + for i, s := range parts { + parts[i] = url.PathEscape(s) + } + return strings.Join(parts, "/") +} + // GetRefs fetches a slice of Reference objects for a given Git ref. // If there is an exact match, only that ref is returned. // If there is no exact match, GitHub returns all refs that start with ref. @@ -92,7 +102,7 @@ func (s *GitService) GetRef(ctx context.Context, owner string, repo string, ref // GitHub API docs: https://developer.github.com/v3/git/refs/#get-a-reference func (s *GitService) GetRefs(ctx context.Context, owner string, repo string, ref string) ([]*Reference, *Response, error) { ref = strings.TrimPrefix(ref, "refs/") - u := fmt.Sprintf("repos/%v/%v/git/refs/%v", owner, repo, url.QueryEscape(ref)) + u := fmt.Sprintf("repos/%v/%v/git/refs/%v", owner, repo, refURLEscape(ref)) req, err := s.client.NewRequest("GET", u, nil) if err != nil { return nil, nil, err @@ -212,7 +222,7 @@ func (s *GitService) UpdateRef(ctx context.Context, owner string, repo string, r // GitHub API docs: https://developer.github.com/v3/git/refs/#delete-a-reference func (s *GitService) DeleteRef(ctx context.Context, owner string, repo string, ref string) (*Response, error) { ref = strings.TrimPrefix(ref, "refs/") - u := fmt.Sprintf("repos/%v/%v/git/refs/%v", owner, repo, url.QueryEscape(ref)) + u := fmt.Sprintf("repos/%v/%v/git/refs/%v", owner, repo, refURLEscape(ref)) req, err := s.client.NewRequest("DELETE", u, nil) if err != nil { return nil, err diff --git a/github/git_refs_test.go b/github/git_refs_test.go index fb91c043316..22dc8eb6247 100644 --- a/github/git_refs_test.go +++ b/github/git_refs_test.go @@ -11,6 +11,7 @@ import ( "fmt" "net/http" "reflect" + "strings" "testing" ) @@ -444,3 +445,30 @@ func TestGitService_DeleteRef(t *testing.T) { t.Errorf("Git.DeleteRef returned error: %v", err) } } + +func TestGitService_GetRef_pathEscape(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/repos/o/r/git/refs/heads/b", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + if strings.Contains(r.URL.RawPath, "%2F") { + t.Errorf("RawPath still contains escaped / as %%2F: %v", r.URL.RawPath) + } + fmt.Fprint(w, ` + { + "ref": "refs/heads/b", + "url": "https://api.github.com/repos/o/r/git/refs/heads/b", + "object": { + "type": "commit", + "sha": "aa218f56b14c9653891f9e74264a383fa43fefbd", + "url": "https://api.github.com/repos/o/r/git/commits/aa218f56b14c9653891f9e74264a383fa43fefbd" + } + }`) + }) + + _, _, err := client.Git.GetRef(context.Background(), "o", "r", "refs/heads/b") + if err != nil { + t.Fatalf("Git.GetRef returned error: %v", err) + } +} diff --git a/github/repos_commits.go b/github/repos_commits.go index a4ff2be4b9d..d6960124d7a 100644 --- a/github/repos_commits.go +++ b/github/repos_commits.go @@ -9,7 +9,6 @@ import ( "bytes" "context" "fmt" - "net/url" "time" ) @@ -198,7 +197,7 @@ func (s *RepositoriesService) GetCommitRaw(ctx context.Context, owner string, re // // GitHub API docs: https://developer.github.com/v3/repos/commits/#get-the-sha-1-of-a-commit-reference func (s *RepositoriesService) GetCommitSHA1(ctx context.Context, owner, repo, ref, lastSHA string) (string, *Response, error) { - u := fmt.Sprintf("repos/%v/%v/commits/%v", owner, repo, url.QueryEscape(ref)) + u := fmt.Sprintf("repos/%v/%v/commits/%v", owner, repo, refURLEscape(ref)) req, err := s.client.NewRequest("GET", u, nil) if err != nil { diff --git a/github/repos_commits_test.go b/github/repos_commits_test.go index 54a60147856..1c4fd77462c 100644 --- a/github/repos_commits_test.go +++ b/github/repos_commits_test.go @@ -262,6 +262,45 @@ func TestRepositoriesService_NonAlphabetCharacter_GetCommitSHA1(t *testing.T) { } } +func TestRepositoriesService_TrailingPercent_GetCommitSHA1(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + const sha1 = "01234abcde" + + mux.HandleFunc("/repos/o/r/commits/comm%", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + testHeader(t, r, "Accept", mediaTypeV3SHA) + + fmt.Fprintf(w, sha1) + }) + + got, _, err := client.Repositories.GetCommitSHA1(context.Background(), "o", "r", "comm%", "") + if err != nil { + t.Errorf("Repositories.GetCommitSHA1 returned error: %v", err) + } + + if want := sha1; got != want { + t.Errorf("Repositories.GetCommitSHA1 = %v, want %v", got, want) + } + + mux.HandleFunc("/repos/o/r/commits/tag", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + testHeader(t, r, "Accept", mediaTypeV3SHA) + testHeader(t, r, "If-None-Match", `"`+sha1+`"`) + + w.WriteHeader(http.StatusNotModified) + }) + + got, _, err = client.Repositories.GetCommitSHA1(context.Background(), "o", "r", "tag", sha1) + if err == nil { + t.Errorf("Expected HTTP 304 response") + } + + if want := ""; got != want { + t.Errorf("Repositories.GetCommitSHA1 = %v, want %v", got, want) + } +} + func TestRepositoriesService_CompareCommits(t *testing.T) { client, mux, _, teardown := setup() defer teardown() diff --git a/github/repos_statuses.go b/github/repos_statuses.go index 5543265880c..5576d311255 100644 --- a/github/repos_statuses.go +++ b/github/repos_statuses.go @@ -8,7 +8,6 @@ package github import ( "context" "fmt" - "net/url" "time" ) @@ -46,7 +45,7 @@ func (r RepoStatus) String() string { // // GitHub API docs: https://developer.github.com/v3/repos/statuses/#list-statuses-for-a-specific-ref func (s *RepositoriesService) ListStatuses(ctx context.Context, owner, repo, ref string, opts *ListOptions) ([]*RepoStatus, *Response, error) { - u := fmt.Sprintf("repos/%v/%v/commits/%v/statuses", owner, repo, url.QueryEscape(ref)) + u := fmt.Sprintf("repos/%v/%v/commits/%v/statuses", owner, repo, refURLEscape(ref)) u, err := addOptions(u, opts) if err != nil { return nil, nil, err @@ -71,7 +70,7 @@ func (s *RepositoriesService) ListStatuses(ctx context.Context, owner, repo, ref // // GitHub API docs: https://developer.github.com/v3/repos/statuses/#create-a-status func (s *RepositoriesService) CreateStatus(ctx context.Context, owner, repo, ref string, status *RepoStatus) (*RepoStatus, *Response, error) { - u := fmt.Sprintf("repos/%v/%v/statuses/%v", owner, repo, url.QueryEscape(ref)) + u := fmt.Sprintf("repos/%v/%v/statuses/%v", owner, repo, refURLEscape(ref)) req, err := s.client.NewRequest("POST", u, status) if err != nil { return nil, nil, err @@ -110,7 +109,7 @@ func (s CombinedStatus) String() string { // // GitHub API docs: https://developer.github.com/v3/repos/statuses/#get-the-combined-status-for-a-specific-ref func (s *RepositoriesService) GetCombinedStatus(ctx context.Context, owner, repo, ref string, opts *ListOptions) (*CombinedStatus, *Response, error) { - u := fmt.Sprintf("repos/%v/%v/commits/%v/status", owner, repo, url.QueryEscape(ref)) + u := fmt.Sprintf("repos/%v/%v/commits/%v/status", owner, repo, refURLEscape(ref)) u, err := addOptions(u, opts) if err != nil { return nil, nil, err From f89d41eaef6f959bf7a1a419b442e17534ed8f81 Mon Sep 17 00:00:00 2001 From: Aynur Zulkarnaev <50375356+ayzu@users.noreply.github.com> Date: Sat, 22 Feb 2020 15:45:24 +0100 Subject: [PATCH 0134/1468] Update teams_discussion_comments with ByID and BySlug endpoints (#1431) Fixes #1423. --- github/teams_discussion_comments.go | 132 ++++++++++++++++--- github/teams_discussion_comments_test.go | 160 ++++++++++++++++++----- 2 files changed, 243 insertions(+), 49 deletions(-) diff --git a/github/teams_discussion_comments.go b/github/teams_discussion_comments.go index ff871f22be0..61b18f30984 100644 --- a/github/teams_discussion_comments.go +++ b/github/teams_discussion_comments.go @@ -37,14 +37,15 @@ type DiscussionCommentListOptions struct { // Sorts the discussion comments by the date they were created. // Accepted values are asc and desc. Default is desc. Direction string `url:"direction,omitempty"` + ListOptions } -// ListComments lists all comments on a team discussion. +// ListCommentsByID lists all comments on a team discussion by team ID. // Authenticated user must grant read:discussion scope. // // GitHub API docs: https://developer.github.com/v3/teams/discussion_comments/#list-comments -func (s *TeamsService) ListComments(ctx context.Context, teamID int64, discussionNumber int, options *DiscussionCommentListOptions) ([]*DiscussionComment, *Response, error) { - u := fmt.Sprintf("teams/%v/discussions/%v/comments", teamID, discussionNumber) +func (s *TeamsService) ListCommentsByID(ctx context.Context, orgID, teamID int64, discussionNumber int, options *DiscussionCommentListOptions) ([]*DiscussionComment, *Response, error) { + u := fmt.Sprintf("organizations/%v/team/%v/discussions/%v/comments", orgID, teamID, discussionNumber) u, err := addOptions(u, options) if err != nil { return nil, nil, err @@ -64,12 +65,37 @@ func (s *TeamsService) ListComments(ctx context.Context, teamID int64, discussio return comments, resp, nil } -// GetComment gets a specific comment on a team discussion. +// ListCommentsBySlug lists all comments on a team discussion by team slug. +// Authenticated user must grant read:discussion scope. +// +// GitHub API docs: https://developer.github.com/v3/teams/discussion_comments/#list-comments +func (s *TeamsService) ListCommentsBySlug(ctx context.Context, org, slug string, discussionNumber int, options *DiscussionCommentListOptions) ([]*DiscussionComment, *Response, error) { + u := fmt.Sprintf("orgs/%v/teams/%v/discussions/%v/comments", org, slug, discussionNumber) + u, err := addOptions(u, options) + if err != nil { + return nil, nil, err + } + + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + + var comments []*DiscussionComment + resp, err := s.client.Do(ctx, req, &comments) + if err != nil { + return nil, resp, err + } + + return comments, resp, nil +} + +// GetCommentByID gets a specific comment on a team discussion by team ID. // Authenticated user must grant read:discussion scope. // // GitHub API docs: https://developer.github.com/v3/teams/discussion_comments/#get-a-single-comment -func (s *TeamsService) GetComment(ctx context.Context, teamID int64, discussionNumber, commentNumber int) (*DiscussionComment, *Response, error) { - u := fmt.Sprintf("teams/%v/discussions/%v/comments/%v", teamID, discussionNumber, commentNumber) +func (s *TeamsService) GetCommentByID(ctx context.Context, orgID, teamID int64, discussionNumber, commentNumber int) (*DiscussionComment, *Response, error) { + u := fmt.Sprintf("organizations/%v/team/%v/discussions/%v/comments/%v", orgID, teamID, discussionNumber, commentNumber) req, err := s.client.NewRequest("GET", u, nil) if err != nil { return nil, nil, err @@ -84,12 +110,53 @@ func (s *TeamsService) GetComment(ctx context.Context, teamID int64, discussionN return discussionComment, resp, nil } -// CreateComment creates a new discussion post on a team discussion. +// GetCommentBySlug gets a specific comment on a team discussion by team slug. +// Authenticated user must grant read:discussion scope. +// +// GitHub API docs: https://developer.github.com/v3/teams/discussion_comments/#get-a-single-comment +func (s *TeamsService) GetCommentBySlug(ctx context.Context, org, slug string, discussionNumber, commentNumber int) (*DiscussionComment, *Response, error) { + u := fmt.Sprintf("orgs/%v/teams/%v/discussions/%v/comments/%v", org, slug, discussionNumber, commentNumber) + + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + + discussionComment := &DiscussionComment{} + resp, err := s.client.Do(ctx, req, discussionComment) + if err != nil { + return nil, resp, err + } + + return discussionComment, resp, nil +} + +// CreateCommentByID creates a new comment on a team discussion by team ID. +// Authenticated user must grant write:discussion scope. +// +// GitHub API docs: https://developer.github.com/v3/teams/discussion_comments/#create-a-comment +func (s *TeamsService) CreateCommentByID(ctx context.Context, orgID, teamID int64, discsusionNumber int, comment DiscussionComment) (*DiscussionComment, *Response, error) { + u := fmt.Sprintf("organizations/%v/team/%v/discussions/%v/comments", orgID, teamID, discsusionNumber) + req, err := s.client.NewRequest("POST", u, comment) + if err != nil { + return nil, nil, err + } + + discussionComment := &DiscussionComment{} + resp, err := s.client.Do(ctx, req, discussionComment) + if err != nil { + return nil, resp, err + } + + return discussionComment, resp, nil +} + +// CreateCommentBySlug creates a new comment on a team discussion by team slug. // Authenticated user must grant write:discussion scope. // // GitHub API docs: https://developer.github.com/v3/teams/discussion_comments/#create-a-comment -func (s *TeamsService) CreateComment(ctx context.Context, teamID int64, discsusionNumber int, comment DiscussionComment) (*DiscussionComment, *Response, error) { - u := fmt.Sprintf("teams/%v/discussions/%v/comments", teamID, discsusionNumber) +func (s *TeamsService) CreateCommentBySlug(ctx context.Context, org, slug string, discsusionNumber int, comment DiscussionComment) (*DiscussionComment, *Response, error) { + u := fmt.Sprintf("orgs/%v/teams/%v/discussions/%v/comments", org, slug, discsusionNumber) req, err := s.client.NewRequest("POST", u, comment) if err != nil { return nil, nil, err @@ -104,13 +171,13 @@ func (s *TeamsService) CreateComment(ctx context.Context, teamID int64, discsusi return discussionComment, resp, nil } -// EditComment edits the body text of a discussion comment. +// EditCommentByID edits the body text of a discussion comment by team ID. // Authenticated user must grant write:discussion scope. // User is allowed to edit body of a comment only. // // GitHub API docs: https://developer.github.com/v3/teams/discussion_comments/#edit-a-comment -func (s *TeamsService) EditComment(ctx context.Context, teamID int64, discussionNumber, commentNumber int, comment DiscussionComment) (*DiscussionComment, *Response, error) { - u := fmt.Sprintf("teams/%v/discussions/%v/comments/%v", teamID, discussionNumber, commentNumber) +func (s *TeamsService) EditCommentByID(ctx context.Context, orgID, teamID int64, discussionNumber, commentNumber int, comment DiscussionComment) (*DiscussionComment, *Response, error) { + u := fmt.Sprintf("organizations/%v/team/%v/discussions/%v/comments/%v", orgID, teamID, discussionNumber, commentNumber) req, err := s.client.NewRequest("PATCH", u, comment) if err != nil { return nil, nil, err @@ -125,12 +192,47 @@ func (s *TeamsService) EditComment(ctx context.Context, teamID int64, discussion return discussionComment, resp, nil } -// DeleteComment deletes a comment on a team discussion. +// EditCommentBySlug edits the body text of a discussion comment by team slug. +// Authenticated user must grant write:discussion scope. +// User is allowed to edit body of a comment only. +// +// GitHub API docs: https://developer.github.com/v3/teams/discussion_comments/#edit-a-comment +func (s *TeamsService) EditCommentBySlug(ctx context.Context, org, slug string, discussionNumber, commentNumber int, comment DiscussionComment) (*DiscussionComment, *Response, error) { + u := fmt.Sprintf("orgs/%v/teams/%v/discussions/%v/comments/%v", org, slug, discussionNumber, commentNumber) + req, err := s.client.NewRequest("PATCH", u, comment) + if err != nil { + return nil, nil, err + } + + discussionComment := &DiscussionComment{} + resp, err := s.client.Do(ctx, req, discussionComment) + if err != nil { + return nil, resp, err + } + + return discussionComment, resp, nil +} + +// DeleteCommentByID deletes a comment on a team discussion by team ID. +// Authenticated user must grant write:discussion scope. +// +// GitHub API docs: https://developer.github.com/v3/teams/discussion_comments/#delete-a-comment +func (s *TeamsService) DeleteCommentByID(ctx context.Context, orgID, teamID int64, discussionNumber, commentNumber int) (*Response, error) { + u := fmt.Sprintf("organizations/%v/team/%v/discussions/%v/comments/%v", orgID, teamID, discussionNumber, commentNumber) + req, err := s.client.NewRequest("DELETE", u, nil) + if err != nil { + return nil, err + } + + return s.client.Do(ctx, req, nil) +} + +// DeleteCommentBySlug deletes a comment on a team discussion by team slug. // Authenticated user must grant write:discussion scope. // // GitHub API docs: https://developer.github.com/v3/teams/discussion_comments/#delete-a-comment -func (s *TeamsService) DeleteComment(ctx context.Context, teamID int64, discussionNumber, commentNumber int) (*Response, error) { - u := fmt.Sprintf("teams/%v/discussions/%v/comments/%v", teamID, discussionNumber, commentNumber) +func (s *TeamsService) DeleteCommentBySlug(ctx context.Context, org, slug string, discussionNumber, commentNumber int) (*Response, error) { + u := fmt.Sprintf("orgs/%v/teams/%v/discussions/%v/comments/%v", org, slug, discussionNumber, commentNumber) req, err := s.client.NewRequest("DELETE", u, nil) if err != nil { return nil, err diff --git a/github/teams_discussion_comments_test.go b/github/teams_discussion_comments_test.go index 96ed1464109..b632f0d862d 100644 --- a/github/teams_discussion_comments_test.go +++ b/github/teams_discussion_comments_test.go @@ -15,11 +15,29 @@ import ( "time" ) +// "Team Discussion Comments" endpoint, when using a teamID. +func tdcEndpointByID(orgID, teamID, discussionNumber, commentNumber string) string { + out := fmt.Sprintf("/organizations/%v/team/%v/discussions/%v/comments", orgID, teamID, discussionNumber) + if commentNumber != "" { + return fmt.Sprintf("%v/%v", out, commentNumber) + } + return out +} + +// "Team Discussion Comments" endpoint, when using a team slug. +func tdcEndpointBySlug(org, slug, dicsuccionsNumber, commentNumber string) string { + out := fmt.Sprintf("/orgs/%v/teams/%v/discussions/%v/comments", org, slug, dicsuccionsNumber) + if commentNumber != "" { + return fmt.Sprintf("%v/%v", out, commentNumber) + } + return out +} + func TestTeamsService_ListComments(t *testing.T) { client, mux, _, teardown := setup() defer teardown() - mux.HandleFunc("/teams/2/discussions/3/comments", func(w http.ResponseWriter, r *http.Request) { + handleFunc := func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") testFormValues(t, r, values{ "direction": "desc", @@ -59,11 +77,6 @@ func TestTeamsService_ListComments(t *testing.T) { "url": "https://api.github.com/teams/2/discussions/3/comments/4" } ]`) - }) - - comments, _, err := client.Teams.ListComments(context.Background(), 2, 3, &DiscussionCommentListOptions{"desc"}) - if err != nil { - t.Errorf("Teams.ListComments returned error: %v", err) } want := []*DiscussionComment{ @@ -100,8 +113,31 @@ func TestTeamsService_ListComments(t *testing.T) { URL: String("https://api.github.com/teams/2/discussions/3/comments/4"), }, } - if !reflect.DeepEqual(comments, want) { - t.Errorf("Teams.ListComments returned %+v, want %+v", comments, want) + + e := tdcEndpointByID("1", "2", "3", "") + mux.HandleFunc(e, handleFunc) + + commentsByID, _, err := client.Teams.ListCommentsByID(context.Background(), 1, 2, 3, + &DiscussionCommentListOptions{Direction: "desc"}) + if err != nil { + t.Errorf("Teams.ListCommentsByID returned error: %v", err) + } + + if !reflect.DeepEqual(commentsByID, want) { + t.Errorf("Teams.ListCommentsByID returned %+v, want %+v", commentsByID, want) + } + + e = tdcEndpointBySlug("a", "b", "3", "") + mux.HandleFunc(e, handleFunc) + + commentsBySlug, _, err := client.Teams.ListCommentsBySlug(context.Background(), "a", "b", 3, + &DiscussionCommentListOptions{Direction: "desc"}) + if err != nil { + t.Errorf("Teams.ListCommentsBySlug returned error: %v", err) + } + + if !reflect.DeepEqual(commentsBySlug, want) { + t.Errorf("Teams.ListCommentsBySlug returned %+v, want %+v", commentsBySlug, want) } } @@ -109,20 +145,36 @@ func TestTeamsService_GetComment(t *testing.T) { client, mux, _, teardown := setup() defer teardown() - mux.HandleFunc("/teams/2/discussions/3/comments/4", func(w http.ResponseWriter, r *http.Request) { + handlerFunc := func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") fmt.Fprint(w, `{"number":4}`) - }) + } + want := &DiscussionComment{Number: Int(4)} + + e := tdcEndpointByID("1", "2", "3", "4") + mux.HandleFunc(e, handlerFunc) - comment, _, err := client.Teams.GetComment(context.Background(), 2, 3, 4) + commentByID, _, err := client.Teams.GetCommentByID(context.Background(), 1, 2, 3, 4) if err != nil { - t.Errorf("Teams.GetComment returned error: %v", err) + t.Errorf("Teams.GetCommentByID returned error: %v", err) } - want := &DiscussionComment{Number: Int(4)} - if !reflect.DeepEqual(comment, want) { - t.Errorf("Teams.GetComment returned %+v, want %+v", comment, want) + if !reflect.DeepEqual(commentByID, want) { + t.Errorf("Teams.GetCommentByID returned %+v, want %+v", commentByID, want) + } + + e = tdcEndpointBySlug("a", "b", "3", "4") + mux.HandleFunc(e, handlerFunc) + + commentBySlug, _, err := client.Teams.GetCommentBySlug(context.Background(), "a", "b", 3, 4) + if err != nil { + t.Errorf("Teams.GetCommentBySlug returned error: %v", err) + } + + if !reflect.DeepEqual(commentBySlug, want) { + t.Errorf("Teams.GetCommentBySlug returned %+v, want %+v", commentBySlug, want) } + } func TestTeamsService_CreateComment(t *testing.T) { @@ -131,7 +183,7 @@ func TestTeamsService_CreateComment(t *testing.T) { input := DiscussionComment{Body: String("c")} - mux.HandleFunc("/teams/2/discussions/3/comments", func(w http.ResponseWriter, r *http.Request) { + handlerFunc := func(w http.ResponseWriter, r *http.Request) { v := new(DiscussionComment) json.NewDecoder(r.Body).Decode(v) @@ -141,16 +193,31 @@ func TestTeamsService_CreateComment(t *testing.T) { } fmt.Fprint(w, `{"number":4}`) - }) + } + want := &DiscussionComment{Number: Int(4)} + + e := tdcEndpointByID("1", "2", "3", "") + mux.HandleFunc(e, handlerFunc) - comment, _, err := client.Teams.CreateComment(context.Background(), 2, 3, input) + commentByID, _, err := client.Teams.CreateCommentByID(context.Background(), 1, 2, 3, input) if err != nil { - t.Errorf("Teams.CreateComment returned error: %v", err) + t.Errorf("Teams.CreateCommentByID returned error: %v", err) } - want := &DiscussionComment{Number: Int(4)} - if !reflect.DeepEqual(comment, want) { - t.Errorf("Teams.CreateComment returned %+v, want %+v", comment, want) + if !reflect.DeepEqual(commentByID, want) { + t.Errorf("Teams.CreateCommentByID returned %+v, want %+v", commentByID, want) + } + + e = tdcEndpointBySlug("a", "b", "3", "") + mux.HandleFunc(e, handlerFunc) + + commentBySlug, _, err := client.Teams.CreateCommentBySlug(context.Background(), "a", "b", 3, input) + if err != nil { + t.Errorf("Teams.CreateCommentBySlug returned error: %v", err) + } + + if !reflect.DeepEqual(commentBySlug, want) { + t.Errorf("Teams.CreateCommentBySlug returned %+v, want %+v", commentBySlug, want) } } @@ -159,8 +226,7 @@ func TestTeamsService_EditComment(t *testing.T) { defer teardown() input := DiscussionComment{Body: String("e")} - - mux.HandleFunc("/teams/2/discussions/3/comments/4", func(w http.ResponseWriter, r *http.Request) { + handlerFunc := func(w http.ResponseWriter, r *http.Request) { v := new(DiscussionComment) json.NewDecoder(r.Body).Decode(v) @@ -170,16 +236,31 @@ func TestTeamsService_EditComment(t *testing.T) { } fmt.Fprint(w, `{"number":4}`) - }) + } + want := &DiscussionComment{Number: Int(4)} - comment, _, err := client.Teams.EditComment(context.Background(), 2, 3, 4, input) + e := tdcEndpointByID("1", "2", "3", "4") + mux.HandleFunc(e, handlerFunc) + + commentByID, _, err := client.Teams.EditCommentByID(context.Background(), 1, 2, 3, 4, input) if err != nil { - t.Errorf("Teams.EditComment returned error: %v", err) + t.Errorf("Teams.EditCommentByID returned error: %v", err) } - want := &DiscussionComment{Number: Int(4)} - if !reflect.DeepEqual(comment, want) { - t.Errorf("Teams.EditComment returned %+v, want %+v", comment, want) + if !reflect.DeepEqual(commentByID, want) { + t.Errorf("Teams.EditCommentByID returned %+v, want %+v", commentByID, want) + } + + e = tdcEndpointBySlug("a", "b", "3", "4") + mux.HandleFunc(e, handlerFunc) + + commentBySlug, _, err := client.Teams.EditCommentBySlug(context.Background(), "a", "b", 3, 4, input) + if err != nil { + t.Errorf("Teams.EditCommentBySlug returned error: %v", err) + } + + if !reflect.DeepEqual(commentBySlug, want) { + t.Errorf("Teams.EditCommentBySlug returned %+v, want %+v", commentBySlug, want) } } @@ -187,12 +268,23 @@ func TestTeamsService_DeleteComment(t *testing.T) { client, mux, _, teardown := setup() defer teardown() - mux.HandleFunc("/teams/2/discussions/3/comments/4", func(w http.ResponseWriter, r *http.Request) { + handlerFunc := func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "DELETE") - }) + } + + e := tdcEndpointByID("1", "2", "3", "4") + mux.HandleFunc(e, handlerFunc) + + _, err := client.Teams.DeleteCommentByID(context.Background(), 1, 2, 3, 4) + if err != nil { + t.Errorf("Teams.DeleteCommentByID returned error: %v", err) + } + + e = tdcEndpointBySlug("a", "b", "3", "4") + mux.HandleFunc(e, handlerFunc) - _, err := client.Teams.DeleteComment(context.Background(), 2, 3, 4) + _, err = client.Teams.DeleteCommentBySlug(context.Background(), "a", "b", 3, 4) if err != nil { - t.Errorf("Teams.DeleteComment returned error: %v", err) + t.Errorf("Teams.DeleteCommentBySlug returned error: %v", err) } } From 0c6788b2a83e5ba928a54acf4572a93b169973e3 Mon Sep 17 00:00:00 2001 From: adrienzieba Date: Sat, 22 Feb 2020 09:46:17 -0500 Subject: [PATCH 0135/1468] Update teams members endpoints+Remove deprecated ones (#1428) Fixes: #1422. --- github/teams_members.go | 157 +++++++++---- github/teams_members_test.go | 426 +++++++++++++++++++++++++++++++---- 2 files changed, 496 insertions(+), 87 deletions(-) diff --git a/github/teams_members.go b/github/teams_members.go index 36ca74353b2..a29263e75c7 100644 --- a/github/teams_members.go +++ b/github/teams_members.go @@ -20,12 +20,12 @@ type TeamListTeamMembersOptions struct { ListOptions } -// ListTeamMembers lists all of the users who are members of the specified -// team. +// ListTeamMembersByID lists all of the users who are members of a team, given a specified +// organization ID, by team ID. // // GitHub API docs: https://developer.github.com/v3/teams/members/#list-team-members -func (s *TeamsService) ListTeamMembers(ctx context.Context, team int64, opts *TeamListTeamMembersOptions) ([]*User, *Response, error) { - u := fmt.Sprintf("teams/%v/members", team) +func (s *TeamsService) ListTeamMembersByID(ctx context.Context, orgID, teamID int64, opts *TeamListTeamMembersOptions) ([]*User, *Response, error) { + u := fmt.Sprintf("organizations/%v/team/%v/members", orgID, teamID) u, err := addOptions(u, opts) if err != nil { return nil, nil, err @@ -45,29 +45,57 @@ func (s *TeamsService) ListTeamMembers(ctx context.Context, team int64, opts *Te return members, resp, nil } -// IsTeamMember checks if a user is a member of the specified team. +// ListTeamMembersBySlug lists all of the users who are members of a team, given a specified +// organization name, by team slug. // -// GitHub API docs: https://developer.github.com/v3/teams/members/#get-team-member +// GitHub API docs: https://developer.github.com/v3/teams/members/#list-team-members +func (s *TeamsService) ListTeamMembersBySlug(ctx context.Context, org, slug string, opts *TeamListTeamMembersOptions) ([]*User, *Response, error) { + u := fmt.Sprintf("orgs/%v/teams/%v/members", org, slug) + u, err := addOptions(u, opts) + if err != nil { + return nil, nil, err + } + + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + + var members []*User + resp, err := s.client.Do(ctx, req, &members) + if err != nil { + return nil, resp, err + } + + return members, resp, nil +} + +// GetTeamMembershipByID returns the membership status for a user in a team, given a specified +// organization ID, by team ID. // -// Deprecated: This API has been marked as deprecated in the Github API docs, -// TeamsService.GetTeamMembership method should be used instead. -func (s *TeamsService) IsTeamMember(ctx context.Context, team int64, user string) (bool, *Response, error) { - u := fmt.Sprintf("teams/%v/members/%v", team, user) +// GitHub API docs: https://developer.github.com/v3/teams/members/#get-team-membership +func (s *TeamsService) GetTeamMembershipByID(ctx context.Context, orgID, teamID int64, user string) (*Membership, *Response, error) { + u := fmt.Sprintf("organizations/%v/team/%v/memberships/%v", orgID, teamID, user) req, err := s.client.NewRequest("GET", u, nil) if err != nil { - return false, nil, err + return nil, nil, err + } + + t := new(Membership) + resp, err := s.client.Do(ctx, req, t) + if err != nil { + return nil, resp, err } - resp, err := s.client.Do(ctx, req, nil) - member, err := parseBoolResponse(err) - return member, resp, err + return t, resp, nil } -// GetTeamMembership returns the membership status for a user in a team. +// GetTeamMembershipBySlug returns the membership status for a user in a team, given a specified +// organization name, by team slug. // // GitHub API docs: https://developer.github.com/v3/teams/members/#get-team-membership -func (s *TeamsService) GetTeamMembership(ctx context.Context, team int64, user string) (*Membership, *Response, error) { - u := fmt.Sprintf("teams/%v/memberships/%v", team, user) +func (s *TeamsService) GetTeamMembershipBySlug(ctx context.Context, org, slug, user string) (*Membership, *Response, error) { + u := fmt.Sprintf("orgs/%v/teams/%v/memberships/%v", org, slug, user) req, err := s.client.NewRequest("GET", u, nil) if err != nil { return nil, nil, err @@ -96,26 +124,32 @@ type TeamAddTeamMembershipOptions struct { Role string `json:"role,omitempty"` } -// AddTeamMembership adds or invites a user to a team. -// -// In order to add a membership between a user and a team, the authenticated -// user must have 'admin' permissions to the team or be an owner of the -// organization that the team is associated with. +// AddTeamMembership adds or invites a user to a team, given a specified +// organization ID, by team ID. // -// If the user is already a part of the team's organization (meaning they're on -// at least one other team in the organization), this endpoint will add the -// user to the team. -// -// If the user is completely unaffiliated with the team's organization (meaning -// they're on none of the organization's teams), this endpoint will send an -// invitation to the user via email. This newly-created membership will be in -// the "pending" state until the user accepts the invitation, at which point -// the membership will transition to the "active" state and the user will be -// added as a member of the team. +// GitHub API docs: https://developer.github.com/v3/teams/members/#add-or-update-team-membership +func (s *TeamsService) AddTeamMembershipByID(ctx context.Context, orgID, teamID int64, user string, opts *TeamAddTeamMembershipOptions) (*Membership, *Response, error) { + u := fmt.Sprintf("organizations/%v/team/%v/memberships/%v", orgID, teamID, user) + req, err := s.client.NewRequest("PUT", u, opts) + if err != nil { + return nil, nil, err + } + + t := new(Membership) + resp, err := s.client.Do(ctx, req, t) + if err != nil { + return nil, resp, err + } + + return t, resp, nil +} + +// AddTeamMembershipBySlug adds or invites a user to a team, given a specified +// organization name, by team slug. // // GitHub API docs: https://developer.github.com/v3/teams/members/#add-or-update-team-membership -func (s *TeamsService) AddTeamMembership(ctx context.Context, team int64, user string, opts *TeamAddTeamMembershipOptions) (*Membership, *Response, error) { - u := fmt.Sprintf("teams/%v/memberships/%v", team, user) +func (s *TeamsService) AddTeamMembershipBySlug(ctx context.Context, org, slug, user string, opts *TeamAddTeamMembershipOptions) (*Membership, *Response, error) { + u := fmt.Sprintf("orgs/%v/teams/%v/memberships/%v", org, slug, user) req, err := s.client.NewRequest("PUT", u, opts) if err != nil { return nil, nil, err @@ -130,11 +164,12 @@ func (s *TeamsService) AddTeamMembership(ctx context.Context, team int64, user s return t, resp, nil } -// RemoveTeamMembership removes a user from a team. +// RemoveTeamMembership removes a user from a team, given a specified +// organization ID, by team ID. // // GitHub API docs: https://developer.github.com/v3/teams/members/#remove-team-membership -func (s *TeamsService) RemoveTeamMembership(ctx context.Context, team int64, user string) (*Response, error) { - u := fmt.Sprintf("teams/%v/memberships/%v", team, user) +func (s *TeamsService) RemoveTeamMembershipByID(ctx context.Context, orgID, teamID int64, user string) (*Response, error) { + u := fmt.Sprintf("organizations/%v/team/%v/memberships/%v", orgID, teamID, user) req, err := s.client.NewRequest("DELETE", u, nil) if err != nil { return nil, err @@ -143,13 +178,51 @@ func (s *TeamsService) RemoveTeamMembership(ctx context.Context, team int64, use return s.client.Do(ctx, req, nil) } -// ListPendingTeamInvitations get pending invitaion list in team. -// Warning: The API may change without advance notice during the preview period. -// Preview features are not supported for production use. +// RemoveTeamMembership removes a user from a team, given a specified +// organization name, by team slug. +// +// GitHub API docs: https://developer.github.com/v3/teams/members/#remove-team-membership +func (s *TeamsService) RemoveTeamMembershipBySlug(ctx context.Context, org, slug, user string) (*Response, error) { + u := fmt.Sprintf("orgs/%v/teams/%v/memberships/%v", org, slug, user) + req, err := s.client.NewRequest("DELETE", u, nil) + if err != nil { + return nil, err + } + + return s.client.Do(ctx, req, nil) +} + +// ListPendingTeamInvitationsByID gets pending invitation list of a team, given a specified +// organization ID, by team ID. +// +// GitHub API docs: https://developer.github.com/v3/teams/members/#list-pending-team-invitations +func (s *TeamsService) ListPendingTeamInvitationsByID(ctx context.Context, orgID, teamID int64, opts *ListOptions) ([]*Invitation, *Response, error) { + u := fmt.Sprintf("organizations/%v/team/%v/invitations", orgID, teamID) + u, err := addOptions(u, opts) + if err != nil { + return nil, nil, err + } + + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + + var pendingInvitations []*Invitation + resp, err := s.client.Do(ctx, req, &pendingInvitations) + if err != nil { + return nil, resp, err + } + + return pendingInvitations, resp, nil +} + +// ListPendingTeamInvitationsByID get pending invitation list of a team, given a specified +// organization name, by team slug. // // GitHub API docs: https://developer.github.com/v3/teams/members/#list-pending-team-invitations -func (s *TeamsService) ListPendingTeamInvitations(ctx context.Context, team int64, opts *ListOptions) ([]*Invitation, *Response, error) { - u := fmt.Sprintf("teams/%v/invitations", team) +func (s *TeamsService) ListPendingTeamInvitationsBySlug(ctx context.Context, org, slug string, opts *ListOptions) ([]*Invitation, *Response, error) { + u := fmt.Sprintf("orgs/%v/teams/%v/invitations", org, slug) u, err := addOptions(u, opts) if err != nil { return nil, nil, err diff --git a/github/teams_members_test.go b/github/teams_members_test.go index 616a747b410..2859526f917 100644 --- a/github/teams_members_test.go +++ b/github/teams_members_test.go @@ -14,119 +14,201 @@ import ( "testing" ) -func TestTeamsService__ListTeamMembers(t *testing.T) { +func TestTeamsService__ListTeamMembersByID(t *testing.T) { client, mux, _, teardown := setup() defer teardown() - mux.HandleFunc("/teams/1/members", func(w http.ResponseWriter, r *http.Request) { + mux.HandleFunc("/organizations/1/team/2/members", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") testFormValues(t, r, values{"role": "member", "page": "2"}) fmt.Fprint(w, `[{"id":1}]`) }) opt := &TeamListTeamMembersOptions{Role: "member", ListOptions: ListOptions{Page: 2}} - members, _, err := client.Teams.ListTeamMembers(context.Background(), 1, opt) + members, _, err := client.Teams.ListTeamMembersByID(context.Background(), 1, 2, opt) if err != nil { - t.Errorf("Teams.ListTeamMembers returned error: %v", err) + t.Errorf("Teams.ListTeamMembersByID returned error: %v", err) } want := []*User{{ID: Int64(1)}} if !reflect.DeepEqual(members, want) { - t.Errorf("Teams.ListTeamMembers returned %+v, want %+v", members, want) + t.Errorf("Teams.ListTeamMembersByID returned %+v, want %+v", members, want) } } -func TestTeamsService__IsTeamMember_true(t *testing.T) { +func TestTeamsService__ListTeamMembersByID_notFound(t *testing.T) { client, mux, _, teardown := setup() defer teardown() - mux.HandleFunc("/teams/1/members/u", func(w http.ResponseWriter, r *http.Request) { + mux.HandleFunc("/organizations/1/team/2/members", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") + testFormValues(t, r, values{"role": "member", "page": "2"}) + w.WriteHeader(http.StatusNotFound) }) - member, _, err := client.Teams.IsTeamMember(context.Background(), 1, "u") - if err != nil { - t.Errorf("Teams.IsTeamMember returned error: %v", err) + opt := &TeamListTeamMembersOptions{Role: "member", ListOptions: ListOptions{Page: 2}} + members, resp, err := client.Teams.ListTeamMembersByID(context.Background(), 1, 2, opt) + if err == nil { + t.Errorf("Expected HTTP 404 response") + } + if got, want := resp.Response.StatusCode, http.StatusNotFound; got != want { + t.Errorf("Teams.ListTeamMembersByID returned status %d, want %d", got, want) } - if want := true; member != want { - t.Errorf("Teams.IsTeamMember returned %+v, want %+v", member, want) + if members != nil { + t.Errorf("Teams.ListTeamMembersByID returned %+v, want nil", members) } } -// ensure that a 404 response is interpreted as "false" and not an error -func TestTeamsService__IsTeamMember_false(t *testing.T) { +func TestTeamsService__ListTeamMembersBySlug(t *testing.T) { client, mux, _, teardown := setup() defer teardown() - mux.HandleFunc("/teams/1/members/u", func(w http.ResponseWriter, r *http.Request) { + mux.HandleFunc("/orgs/o/teams/s/members", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") - w.WriteHeader(http.StatusNotFound) + testFormValues(t, r, values{"role": "member", "page": "2"}) + fmt.Fprint(w, `[{"id":1}]`) }) - member, _, err := client.Teams.IsTeamMember(context.Background(), 1, "u") + opt := &TeamListTeamMembersOptions{Role: "member", ListOptions: ListOptions{Page: 2}} + members, _, err := client.Teams.ListTeamMembersBySlug(context.Background(), "o", "s", opt) if err != nil { - t.Errorf("Teams.IsTeamMember returned error: %+v", err) + t.Errorf("Teams.ListTeamMembersBySlug returned error: %v", err) } - if want := false; member != want { - t.Errorf("Teams.IsTeamMember returned %+v, want %+v", member, want) + + want := []*User{{ID: Int64(1)}} + if !reflect.DeepEqual(members, want) { + t.Errorf("Teams.ListTeamMembersBySlug returned %+v, want %+v", members, want) } } -// ensure that a 400 response is interpreted as an actual error, and not simply -// as "false" like the above case of a 404 -func TestTeamsService__IsTeamMember_error(t *testing.T) { +func TestTeamsService__ListTeamMembersBySlug_notFound(t *testing.T) { client, mux, _, teardown := setup() defer teardown() - mux.HandleFunc("/teams/1/members/u", func(w http.ResponseWriter, r *http.Request) { + mux.HandleFunc("/orgs/o/teams/s/members", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") - http.Error(w, "BadRequest", http.StatusBadRequest) + testFormValues(t, r, values{"role": "member", "page": "2"}) + w.WriteHeader(http.StatusNotFound) }) - member, _, err := client.Teams.IsTeamMember(context.Background(), 1, "u") + opt := &TeamListTeamMembersOptions{Role: "member", ListOptions: ListOptions{Page: 2}} + members, resp, err := client.Teams.ListTeamMembersBySlug(context.Background(), "o", "s", opt) if err == nil { - t.Errorf("Expected HTTP 400 response") + t.Errorf("Expected HTTP 404 response") + } + if got, want := resp.Response.StatusCode, http.StatusNotFound; got != want { + t.Errorf("Teams.ListTeamMembersBySlug returned status %d, want %d", got, want) } - if want := false; member != want { - t.Errorf("Teams.IsTeamMember returned %+v, want %+v", member, want) + if members != nil { + t.Errorf("Teams.ListTeamMembersBySlug returned %+v, want nil", members) } } -func TestTeamsService__IsTeamMember_invalidUser(t *testing.T) { +func TestTeamsService__ListTeamMembersBySlug_invalidOrg(t *testing.T) { client, _, _, teardown := setup() defer teardown() - _, _, err := client.Teams.IsTeamMember(context.Background(), 1, "%") + _, _, err := client.Teams.ListTeamMembersBySlug(context.Background(), "%", "s", nil) testURLParseError(t, err) } -func TestTeamsService__GetTeamMembership(t *testing.T) { +func TestTeamsService__GetTeamMembershipByID(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/organizations/1/team/2/memberships/u", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + fmt.Fprint(w, `{"url":"u", "state":"active"}`) + }) + + membership, _, err := client.Teams.GetTeamMembershipByID(context.Background(), 1, 2, "u") + if err != nil { + t.Errorf("Teams.GetTeamMembershipByID returned error: %v", err) + } + + want := &Membership{URL: String("u"), State: String("active")} + if !reflect.DeepEqual(membership, want) { + t.Errorf("Teams.GetTeamMembershipByID returned %+v, want %+v", membership, want) + } +} + +func TestTeamsService__GetTeamMembershipByID_notFound(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/organizations/1/team/2/memberships/u", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + w.WriteHeader(http.StatusNotFound) + }) + + membership, resp, err := client.Teams.GetTeamMembershipByID(context.Background(), 1, 2, "u") + if err == nil { + t.Errorf("Expected HTTP 404 response") + } + if got, want := resp.Response.StatusCode, http.StatusNotFound; got != want { + t.Errorf("Teams.GetTeamMembershipByID returned status %d, want %d", got, want) + } + if membership != nil { + t.Errorf("Teams.GetTeamMembershipByID returned %+v, want nil", membership) + } +} + +func TestTeamsService__GetTeamMembershipBySlug(t *testing.T) { client, mux, _, teardown := setup() defer teardown() - mux.HandleFunc("/teams/1/memberships/u", func(w http.ResponseWriter, r *http.Request) { + mux.HandleFunc("/orgs/o/teams/s/memberships/u", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") fmt.Fprint(w, `{"url":"u", "state":"active"}`) }) - membership, _, err := client.Teams.GetTeamMembership(context.Background(), 1, "u") + membership, _, err := client.Teams.GetTeamMembershipBySlug(context.Background(), "o", "s", "u") if err != nil { - t.Errorf("Teams.GetTeamMembership returned error: %v", err) + t.Errorf("Teams.GetTeamMembershipBySlug returned error: %v", err) } want := &Membership{URL: String("u"), State: String("active")} if !reflect.DeepEqual(membership, want) { - t.Errorf("Teams.GetTeamMembership returned %+v, want %+v", membership, want) + t.Errorf("Teams.GetTeamMembershipBySlug returned %+v, want %+v", membership, want) } } -func TestTeamsService__AddTeamMembership(t *testing.T) { +func TestTeamsService__GetTeamMembershipBySlug_notFound(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/orgs/o/teams/s/memberships/u", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + w.WriteHeader(http.StatusNotFound) + }) + + membership, resp, err := client.Teams.GetTeamMembershipBySlug(context.Background(), "o", "s", "u") + if err == nil { + t.Errorf("Expected HTTP 404 response") + } + if got, want := resp.Response.StatusCode, http.StatusNotFound; got != want { + t.Errorf("Teams.GetTeamMembershipBySlug returned status %d, want %d", got, want) + } + if membership != nil { + t.Errorf("Teams.GetTeamMembershipBySlug returned %+v, want nil", membership) + } +} + +func TestTeamsService__GetTeamMembershipBySlug_invalidOrg(t *testing.T) { + client, _, _, teardown := setup() + defer teardown() + + _, _, err := client.Teams.GetTeamMembershipBySlug(context.Background(), "%s", "s", "u") + testURLParseError(t, err) +} + +func TestTeamsService__AddTeamMembershipByID(t *testing.T) { client, mux, _, teardown := setup() defer teardown() opt := &TeamAddTeamMembershipOptions{Role: "maintainer"} - mux.HandleFunc("/teams/1/memberships/u", func(w http.ResponseWriter, r *http.Request) { + mux.HandleFunc("/organizations/1/team/2/memberships/u", func(w http.ResponseWriter, r *http.Request) { v := new(TeamAddTeamMembershipOptions) json.NewDecoder(r.Body).Decode(v) @@ -138,28 +220,282 @@ func TestTeamsService__AddTeamMembership(t *testing.T) { fmt.Fprint(w, `{"url":"u", "state":"pending"}`) }) - membership, _, err := client.Teams.AddTeamMembership(context.Background(), 1, "u", opt) + membership, _, err := client.Teams.AddTeamMembershipByID(context.Background(), 1, 2, "u", opt) if err != nil { - t.Errorf("Teams.AddTeamMembership returned error: %v", err) + t.Errorf("Teams.AddTeamMembershipByID returned error: %v", err) } want := &Membership{URL: String("u"), State: String("pending")} if !reflect.DeepEqual(membership, want) { - t.Errorf("Teams.AddTeamMembership returned %+v, want %+v", membership, want) + t.Errorf("Teams.AddTeamMembershipByID returned %+v, want %+v", membership, want) + } +} + +func TestTeamsService__AddTeamMembershipByID_notFound(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + opt := &TeamAddTeamMembershipOptions{Role: "maintainer"} + + mux.HandleFunc("/organizations/1/team/2/memberships/u", func(w http.ResponseWriter, r *http.Request) { + v := new(TeamAddTeamMembershipOptions) + json.NewDecoder(r.Body).Decode(v) + + testMethod(t, r, "PUT") + if !reflect.DeepEqual(v, opt) { + t.Errorf("Request body = %+v, want %+v", v, opt) + } + + w.WriteHeader(http.StatusNotFound) + }) + + membership, resp, err := client.Teams.AddTeamMembershipByID(context.Background(), 1, 2, "u", opt) + if err == nil { + t.Errorf("Expected HTTP 404 response") + } + if got, want := resp.Response.StatusCode, http.StatusNotFound; got != want { + t.Errorf("Teams.AddTeamMembershipByID returned status %d, want %d", got, want) + } + if membership != nil { + t.Errorf("Teams.AddTeamMembershipByID returned %+v, want nil", membership) } } -func TestTeamsService__RemoveTeamMembership(t *testing.T) { +func TestTeamsService__AddTeamMembershipBySlug(t *testing.T) { client, mux, _, teardown := setup() defer teardown() - mux.HandleFunc("/teams/1/memberships/u", func(w http.ResponseWriter, r *http.Request) { + opt := &TeamAddTeamMembershipOptions{Role: "maintainer"} + + mux.HandleFunc("/orgs/o/teams/s/memberships/u", func(w http.ResponseWriter, r *http.Request) { + v := new(TeamAddTeamMembershipOptions) + json.NewDecoder(r.Body).Decode(v) + + testMethod(t, r, "PUT") + if !reflect.DeepEqual(v, opt) { + t.Errorf("Request body = %+v, want %+v", v, opt) + } + + fmt.Fprint(w, `{"url":"u", "state":"pending"}`) + }) + + membership, _, err := client.Teams.AddTeamMembershipBySlug(context.Background(), "o", "s", "u", opt) + if err != nil { + t.Errorf("Teams.AddTeamMembershipBySlug returned error: %v", err) + } + + want := &Membership{URL: String("u"), State: String("pending")} + if !reflect.DeepEqual(membership, want) { + t.Errorf("Teams.AddTeamMembershipBySlug returned %+v, want %+v", membership, want) + } +} + +func TestTeamsService__AddTeamMembershipBySlug_notFound(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + opt := &TeamAddTeamMembershipOptions{Role: "maintainer"} + + mux.HandleFunc("/orgs/o/teams/s/memberships/u", func(w http.ResponseWriter, r *http.Request) { + v := new(TeamAddTeamMembershipOptions) + json.NewDecoder(r.Body).Decode(v) + + testMethod(t, r, "PUT") + if !reflect.DeepEqual(v, opt) { + t.Errorf("Request body = %+v, want %+v", v, opt) + } + + w.WriteHeader(http.StatusNotFound) + }) + + membership, resp, err := client.Teams.AddTeamMembershipBySlug(context.Background(), "o", "s", "u", opt) + if err == nil { + t.Errorf("Expected HTTP 404 response") + } + if got, want := resp.Response.StatusCode, http.StatusNotFound; got != want { + t.Errorf("Teams.AddTeamMembershipBySlug returned status %d, want %d", got, want) + } + if membership != nil { + t.Errorf("Teams.AddTeamMembershipBySlug returned %+v, want nil", membership) + } +} + +func TestTeamsService__AddTeamMembershipBySlug_invalidOrg(t *testing.T) { + client, _, _, teardown := setup() + defer teardown() + + _, _, err := client.Teams.AddTeamMembershipBySlug(context.Background(), "%", "s", "u", nil) + testURLParseError(t, err) +} + +func TestTeamsService__RemoveTeamMembershipByID(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/organizations/1/team/2/memberships/u", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "DELETE") w.WriteHeader(http.StatusNoContent) }) - _, err := client.Teams.RemoveTeamMembership(context.Background(), 1, "u") + _, err := client.Teams.RemoveTeamMembershipByID(context.Background(), 1, 2, "u") + if err != nil { + t.Errorf("Teams.RemoveTeamMembershipByID returned error: %v", err) + } +} + +func TestTeamsService__RemoveTeamMembershipByID_notFound(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/organizations/1/team/2/memberships/u", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "DELETE") + w.WriteHeader(http.StatusNotFound) + }) + + resp, err := client.Teams.RemoveTeamMembershipByID(context.Background(), 1, 2, "u") + if err == nil { + t.Errorf("Expected HTTP 404 response") + } + if got, want := resp.Response.StatusCode, http.StatusNotFound; got != want { + t.Errorf("Teams.RemoveTeamMembershipByID returned status %d, want %d", got, want) + } +} + +func TestTeamsService__RemoveTeamMembershipBySlug(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/orgs/o/teams/s/memberships/u", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "DELETE") + w.WriteHeader(http.StatusNoContent) + }) + + _, err := client.Teams.RemoveTeamMembershipBySlug(context.Background(), "o", "s", "u") + if err != nil { + t.Errorf("Teams.RemoveTeamMembershipBySlug returned error: %v", err) + } +} + +func TestTeamsService__RemoveTeamMembershipBySlug_notFound(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/orgs/o/teams/s/memberships/u", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "DELETE") + w.WriteHeader(http.StatusNotFound) + }) + + resp, err := client.Teams.RemoveTeamMembershipBySlug(context.Background(), "o", "s", "u") + if err == nil { + t.Errorf("Expected HTTP 404 response") + } + if got, want := resp.Response.StatusCode, http.StatusNotFound; got != want { + t.Errorf("Teams.RemoveTeamMembershipBySlug returned status %d, want %d", got, want) + } +} + +func TestTeamsService__RemoveTeamMembershipBySlug_invalidOrg(t *testing.T) { + client, _, _, teardown := setup() + defer teardown() + + _, err := client.Teams.RemoveTeamMembershipBySlug(context.Background(), "%", "s", "u") + testURLParseError(t, err) +} + +func TestTeamsService__ListPendingTeamInvitationsByID(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/organizations/1/team/2/invitations", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + testFormValues(t, r, values{"page": "2"}) + fmt.Fprint(w, `[{"id":1}]`) + }) + + opt := &ListOptions{Page: 2} + invitations, _, err := client.Teams.ListPendingTeamInvitationsByID(context.Background(), 1, 2, opt) if err != nil { - t.Errorf("Teams.RemoveTeamMembership returned error: %v", err) + t.Errorf("Teams.ListPendingTeamInvitationsByID returned error: %v", err) + } + + want := []*Invitation{{ID: Int64(1)}} + if !reflect.DeepEqual(invitations, want) { + t.Errorf("Teams.ListPendingTeamInvitationsByID returned %+v, want %+v", invitations, want) + } +} + +func TestTeamsService__ListPendingTeamInvitationsByID_notFound(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/organizations/1/team/2/invitations", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + testFormValues(t, r, values{"page": "2"}) + w.WriteHeader(http.StatusNotFound) + }) + + opt := &ListOptions{Page: 2} + invitations, resp, err := client.Teams.ListPendingTeamInvitationsByID(context.Background(), 1, 2, opt) + if err == nil { + t.Errorf("Expected HTTP 404 response") + } + if got, want := resp.Response.StatusCode, http.StatusNotFound; got != want { + t.Errorf("Teams.RemoveTeamMembershipByID returned status %d, want %d", got, want) + } + if invitations != nil { + t.Errorf("Teams.RemoveTeamMembershipByID returned %+v, want nil", invitations) } } + +func TestTeamsService__ListPendingTeamInvitationsBySlug(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/orgs/o/teams/s/invitations", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + testFormValues(t, r, values{"page": "2"}) + fmt.Fprint(w, `[{"id":1}]`) + }) + + opt := &ListOptions{Page: 2} + invitations, _, err := client.Teams.ListPendingTeamInvitationsBySlug(context.Background(), "o", "s", opt) + if err != nil { + t.Errorf("Teams.ListPendingTeamInvitationsByID returned error: %v", err) + } + + want := []*Invitation{{ID: Int64(1)}} + if !reflect.DeepEqual(invitations, want) { + t.Errorf("Teams.ListPendingTeamInvitationsByID returned %+v, want %+v", invitations, want) + } +} + +func TestTeamsService__ListPendingTeamInvitationsBySlug_notFound(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/orgs/o/teams/s/invitations", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + testFormValues(t, r, values{"page": "2"}) + w.WriteHeader(http.StatusNotFound) + }) + + opt := &ListOptions{Page: 2} + invitations, resp, err := client.Teams.ListPendingTeamInvitationsBySlug(context.Background(), "o", "s", opt) + if err == nil { + t.Errorf("Expected HTTP 404 response") + } + if got, want := resp.Response.StatusCode, http.StatusNotFound; got != want { + t.Errorf("Teams.RemoveTeamMembershipByID returned status %d, want %d", got, want) + } + if invitations != nil { + t.Errorf("Teams.RemoveTeamMembershipByID returned %+v, want nil", invitations) + } +} + +func TestTeamsService__ListPendingTeamInvitationsBySlug_invalidOrg(t *testing.T) { + client, _, _, teardown := setup() + defer teardown() + + _, _, err := client.Teams.ListPendingTeamInvitationsBySlug(context.Background(), "%", "s", nil) + testURLParseError(t, err) +} From ad1198b1cd40b685cf87bf14375b6f582e8fcb7c Mon Sep 17 00:00:00 2001 From: Glenn Lewis <6598971+gmlewis@users.noreply.github.com> Date: Sat, 22 Feb 2020 20:20:01 -0500 Subject: [PATCH 0136/1468] Update AUTHORS with recent contributors (#1438) --- AUTHORS | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/AUTHORS b/AUTHORS index 91ef2d84a20..4dd8d21b80d 100644 --- a/AUTHORS +++ b/AUTHORS @@ -20,9 +20,11 @@ Akhil Mohan Alec Thomas Aleks Clark Alex Bramley +Alex Orr Alexander Harkness Allen Sun Amey Sakhadeo +Anders Janmyr Andreas Garnæs Andrew Ryabchun Andy Grunwald @@ -51,6 +53,7 @@ Brandon Cook Brian Egizi Bryan Boreham Cami Diez +Carl Johnson Carlos Alexandro Becker Carlos Tadeu Panato Junior chandresh-pancholi @@ -148,8 +151,8 @@ Junya Kono Justin Abrahms Jusung Lee jzhoucliqr +kadern0 Katrina Owen -Kautilya Tripathi < tripathi.kautilya@gmail.com> Kautilya Tripathi Keita Urashima Kevin Burke @@ -166,9 +169,11 @@ Luke Evers Luke Kysow Luke Roberts Luke Young +lynn [they] Maksim Zhylinski Mark Tareshawty Martin-Louis Bright +Martins Sipenko Marwan Sulaiman Masayuki Izumi Mat Geist @@ -189,19 +194,22 @@ Nick Spragg Nikhita Raghunath Noah Zoschke ns-cweber -Oleg Kovalov Ole Orhagen +Oleg Kovalov Ondřej Kupka Palash Nigam Panagiotis Moustafellos Parham Alvani Parker Moore parkhyukjun89 +Patrick DeVivo +Patrick Marabeas Pavel Shtanko Pete Wagner Petr Shevtsov Pierre Carrier Piotr Zurek +Qais Patankar Quang Le Hong Quentin Leffray Quinn Slack @@ -211,6 +219,7 @@ Radliński Ignacy Rajat Jindal Rajendra arora Ranbir Singh +Ravi Shekhar Jethani RaviTeja Pothana rc1140 Red Hat, Inc. @@ -221,6 +230,7 @@ Ronak Jain Ruben Vereecken Ryan Leung Ryan Lower +Ryo Nakao Safwan Olaimat Sahil Dua saisi @@ -246,6 +256,7 @@ sona-tar SoundCloud, Ltd. Sridhar Mocherla SriVignessh Pss +Stefan Sedich Stian Eikeland Suhaib Mujahid Szymon Kodrebski @@ -261,6 +272,7 @@ Vaibhav Singh Varadarajan Aravamudhan Victor Castell Victor Vrantchan +vikkyomkar Vlad Ungureanu Wasim Thabraze Will Maier From 65635608af2d5b3afe0f172fe91aa5e28ae2724f Mon Sep 17 00:00:00 2001 From: Alex Orr Date: Thu, 27 Feb 2020 04:41:51 -0800 Subject: [PATCH 0137/1468] Implement support for actions artifacts (#1414) Relates to: #1399. --- github/actions_artifacts.go | 140 ++++++++++++++++ github/actions_artifacts_test.go | 277 +++++++++++++++++++++++++++++++ github/github-accessors.go | 72 ++++++++ 3 files changed, 489 insertions(+) create mode 100644 github/actions_artifacts.go create mode 100644 github/actions_artifacts_test.go diff --git a/github/actions_artifacts.go b/github/actions_artifacts.go new file mode 100644 index 00000000000..1735849584a --- /dev/null +++ b/github/actions_artifacts.go @@ -0,0 +1,140 @@ +// Copyright 2020 The go-github AUTHORS. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package github + +import ( + "context" + "fmt" + "net/http" + "net/url" +) + +// Artifact reprents a GitHub artifact. Artifacts allow sharing +// data between jobs in a workflow and provide storage for data +// once a workflow is complete. +// +// GitHub API docs: https://developer.github.com/v3/actions/artifacts/ +type Artifact struct { + ID *int64 `json:"id,omitempty"` + NodeID *string `json:"node_id,omitempty"` + Name *string `json:"name,omitempty"` + SizeInBytes *int64 `json:"size_in_bytes,omitempty"` + ArchiveDownloadURL *string `json:"archive_download_url,omitempty"` + Expired *bool `json:"expired,omitempty"` + CreatedAt *Timestamp `json:"created_at,omitempty"` + ExpiresAt *Timestamp `json:"expires_at,omitempty"` +} + +// ArtifactList represents a list of GitHub artifacts. +// +// GitHub API docs: https://developer.github.com/v3/actions/artifacts/ +type ArtifactList struct { + TotalCount *int64 `json:"total_count,omitempty"` + Artifacts []*Artifact `json:"artifacts,omitempty"` +} + +// ListWorkflowRunArtifacts lists all artifacts that belong to a workflow run. +// +// GitHub API docs: https://developer.github.com/v3/actions/artifacts/#list-workflow-run-artifacts +func (s *ActionsService) ListWorkflowRunArtifacts(ctx context.Context, owner, repo string, runID int64, opts *ListOptions) (*ArtifactList, *Response, error) { + u := fmt.Sprintf("repos/%v/%v/actions/runs/%v/artifacts", owner, repo, runID) + u, err := addOptions(u, opts) + if err != nil { + return nil, nil, err + } + + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + + artifactList := new(ArtifactList) + resp, err := s.client.Do(ctx, req, artifactList) + if err != nil { + return nil, resp, err + } + + return artifactList, resp, nil +} + +// GetArtifact gets a specific artifact for a workflow run. +// +// GitHub API docs: https://developer.github.com/v3/actions/artifacts/#get-an-artifact +func (s *ActionsService) GetArtifact(ctx context.Context, owner, repo string, artifactID int64) (*Artifact, *Response, error) { + u := fmt.Sprintf("repos/%v/%v/actions/artifacts/%v", owner, repo, artifactID) + + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + + artifact := new(Artifact) + resp, err := s.client.Do(ctx, req, artifact) + if err != nil { + return nil, resp, err + } + + return artifact, resp, nil +} + +// DownloadArtifact gets a redirect URL to download an archive for a repository. +// +// GitHub API docs: https://developer.github.com/v3/actions/artifacts/#download-an-artifact +func (s *ActionsService) DownloadArtifact(ctx context.Context, owner, repo string, artifactID int64, followRedirects bool) (*url.URL, *Response, error) { + u := fmt.Sprintf("repos/%v/%v/actions/artifacts/%v/zip", owner, repo, artifactID) + + resp, err := s.getDownloadArtifactFromURL(ctx, u, followRedirects) + if err != nil { + return nil, nil, err + } + + if resp.StatusCode != http.StatusFound { + return nil, newResponse(resp), fmt.Errorf("unexpected status code: %s", resp.Status) + } + parsedURL, err := url.Parse(resp.Header.Get("Location")) + return parsedURL, newResponse(resp), nil +} + +func (s *ActionsService) getDownloadArtifactFromURL(ctx context.Context, u string, followRedirects bool) (*http.Response, error) { + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, err + } + + var resp *http.Response + // Use http.DefaultTransport if no custom Transport is configured + req = withContext(ctx, req) + if s.client.client.Transport == nil { + resp, err = http.DefaultTransport.RoundTrip(req) + } else { + resp, err = s.client.client.Transport.RoundTrip(req) + } + if err != nil { + return nil, err + } + resp.Body.Close() + + // If redirect response is returned, follow it + if followRedirects && resp.StatusCode == http.StatusMovedPermanently { + u = resp.Header.Get("Location") + resp, err = s.getDownloadArtifactFromURL(ctx, u, false) + } + return resp, err +} + +// DeleteArtifact deletes a workflow run artifact. +// +// GitHub API docs: https://developer.github.com/v3/actions/artifacts/#delete-an-artifact +func (s *ActionsService) DeleteArtifact(ctx context.Context, owner, repo string, artifactID int64) (*Response, error) { + u := fmt.Sprintf("repos/%v/%v/actions/artifacts/%v", owner, repo, artifactID) + + req, err := s.client.NewRequest("DELETE", u, nil) + if err != nil { + return nil, err + } + + return s.client.Do(ctx, req, nil) +} diff --git a/github/actions_artifacts_test.go b/github/actions_artifacts_test.go new file mode 100644 index 00000000000..2d478e455a2 --- /dev/null +++ b/github/actions_artifacts_test.go @@ -0,0 +1,277 @@ +// Copyright 2020 The go-github AUTHORS. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package github + +import ( + "context" + "fmt" + "net/http" + "net/url" + "reflect" + "testing" +) + +func TestActionsService_ListWorkflowRunArtifacts(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/repos/o/r/actions/runs/1/artifacts", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + testFormValues(t, r, values{"page": "2"}) + fmt.Fprint(w, + `{ + "total_count":1, + "artifacts":[{"id":1}] + }`, + ) + }) + + opts := &ListOptions{Page: 2} + artifacts, _, err := client.Actions.ListWorkflowRunArtifacts(context.Background(), "o", "r", 1, opts) + if err != nil { + t.Errorf("Actions.ListWorkflowRunArtifacts returned error: %v", err) + } + + want := &ArtifactList{TotalCount: Int64(1), Artifacts: []*Artifact{{ID: Int64(1)}}} + if !reflect.DeepEqual(artifacts, want) { + t.Errorf("Actions.ListWorkflowRunArtifacts returned %+v, want %+v", artifacts, want) + } +} + +func TestActionsService_ListWorkflowRunArtifacts_invalidOwner(t *testing.T) { + client, _, _, teardown := setup() + defer teardown() + + _, _, err := client.Actions.ListWorkflowRunArtifacts(context.Background(), "%", "r", 1, nil) + testURLParseError(t, err) +} + +func TestActionsService_ListWorkflowRunArtifacts_invalidRepo(t *testing.T) { + client, _, _, teardown := setup() + defer teardown() + + _, _, err := client.Actions.ListWorkflowRunArtifacts(context.Background(), "o", "%", 1, nil) + testURLParseError(t, err) +} + +func TestActionsService_ListWorkflowRunArtifacts_notFound(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/repos/o/r/actions/runs/1/artifacts", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + w.WriteHeader(http.StatusNotFound) + }) + + artifacts, resp, err := client.Actions.ListWorkflowRunArtifacts(context.Background(), "o", "r", 1, nil) + if err == nil { + t.Errorf("Expected HTTP 404 response") + } + if got, want := resp.Response.StatusCode, http.StatusNotFound; got != want { + t.Errorf("Actions.ListWorkflowRunArtifacts return status %d, want %d", got, want) + } + if artifacts != nil { + t.Errorf("Actions.ListWorkflowRunArtifacts return %+v, want nil", artifacts) + } +} + +func TestActionsService_GetArtifact(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/repos/o/r/actions/artifacts/1", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + fmt.Fprint(w, `{ + "id":1, + "node_id":"xyz", + "name":"a", + "size_in_bytes":5, + "archive_download_url":"u" + }`) + }) + + artifact, _, err := client.Actions.GetArtifact(context.Background(), "o", "r", 1) + if err != nil { + t.Errorf("Actions.GetArtifact returned error: %v", err) + } + + want := &Artifact{ + ID: Int64(1), + NodeID: String("xyz"), + Name: String("a"), + SizeInBytes: Int64(5), + ArchiveDownloadURL: String("u"), + } + if !reflect.DeepEqual(artifact, want) { + t.Errorf("Actions.GetArtifact returned %+v, want %+v", artifact, want) + } +} + +func TestActionsService_GetArtifact_invalidOwner(t *testing.T) { + client, _, _, teardown := setup() + defer teardown() + + _, _, err := client.Actions.GetArtifact(context.Background(), "%", "r", 1) + testURLParseError(t, err) +} + +func TestActionsService_GetArtifact_invalidRepo(t *testing.T) { + client, _, _, teardown := setup() + defer teardown() + + _, _, err := client.Actions.GetArtifact(context.Background(), "o", "%", 1) + testURLParseError(t, err) +} + +func TestActionsService_GetArtifact_notFound(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/repos/o/r/actions/artifacts/1", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + w.WriteHeader(http.StatusNotFound) + }) + + artifact, resp, err := client.Actions.GetArtifact(context.Background(), "o", "r", 1) + if err == nil { + t.Errorf("Expected HTTP 404 response") + } + if got, want := resp.Response.StatusCode, http.StatusNotFound; got != want { + t.Errorf("Actions.GetArtifact return status %d, want %d", got, want) + } + if artifact != nil { + t.Errorf("Actions.GetArtifact return %+v, want nil", artifact) + } +} + +func TestActionsSerivice_DownloadArtifact(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/repos/o/r/actions/artifacts/1/zip", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + http.Redirect(w, r, "https://github.com/artifact", http.StatusFound) + }) + + url, resp, err := client.Actions.DownloadArtifact(context.Background(), "o", "r", 1, true) + if err != nil { + t.Errorf("Actions.DownloadArtifact returned error: %v", err) + } + if resp.StatusCode != http.StatusFound { + t.Errorf("Actions.DownloadArtifact returned status: %d, want %d", resp.StatusCode, http.StatusFound) + } + + want := "https://github.com/artifact" + if url.String() != want { + t.Errorf("Actions.DownloadArtifact returned %+v, want %+v", url.String(), want) + } +} + +func TestActionsService_DownloadArtifact_invalidOwner(t *testing.T) { + client, _, _, teardown := setup() + defer teardown() + + _, _, err := client.Actions.DownloadArtifact(context.Background(), "%", "r", 1, true) + testURLParseError(t, err) +} + +func TestActionsService_DownloadArtifact_invalidRepo(t *testing.T) { + client, _, _, teardown := setup() + defer teardown() + + _, _, err := client.Actions.DownloadArtifact(context.Background(), "o", "%", 1, true) + testURLParseError(t, err) +} + +func TestActionsService_DownloadArtifact_StatusMovedPermanently_dontFollowRedirects(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/repos/o/r/actions/artifacts/1/zip", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + http.Redirect(w, r, "https://github.com/artifact", http.StatusMovedPermanently) + }) + + _, resp, _ := client.Actions.DownloadArtifact(context.Background(), "o", "r", 1, false) + if resp.StatusCode != http.StatusMovedPermanently { + t.Errorf("Actions.DownloadArtifact return status %d, want %d", resp.StatusCode, http.StatusMovedPermanently) + } +} + +func TestActionsService_DownloadArtifact_StatusMovedPermanently_followRedirects(t *testing.T) { + client, mux, serverURL, teardown := setup() + defer teardown() + + mux.HandleFunc("/repos/o/r/actions/artifacts/1/zip", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + redirectURL, _ := url.Parse(serverURL + baseURLPath + "/redirect") + http.Redirect(w, r, redirectURL.String(), http.StatusMovedPermanently) + }) + mux.HandleFunc("/redirect", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + http.Redirect(w, r, "http://github.com/artifact", http.StatusFound) + }) + + url, resp, err := client.Actions.DownloadArtifact(context.Background(), "o", "r", 1, true) + if err != nil { + t.Errorf("Actions.DownloadArtifact return error: %v", err) + } + if resp.StatusCode != http.StatusFound { + t.Errorf("Actions.DownloadArtifact return status %d, want %d", resp.StatusCode, http.StatusFound) + } + want := "http://github.com/artifact" + if url.String() != want { + t.Errorf("Actions.DownloadArtifact returned %+v, want %+v", url.String(), want) + } +} + +func TestActionsService_DeleteArtifact(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/repos/o/r/actions/artifacts/1", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "DELETE") + }) + + _, err := client.Actions.DeleteArtifact(context.Background(), "o", "r", 1) + if err != nil { + t.Errorf("Actions.DeleteArtifact return error: %v", err) + } +} + +func TestActionsService_DeleteArtifact_invalidOwner(t *testing.T) { + client, _, _, teardown := setup() + defer teardown() + + _, err := client.Actions.DeleteArtifact(context.Background(), "%", "r", 1) + testURLParseError(t, err) +} + +func TestActionsService_DeleteArtifact_invalidRepo(t *testing.T) { + client, _, _, teardown := setup() + defer teardown() + + _, err := client.Actions.DeleteArtifact(context.Background(), "o", "%", 1) + testURLParseError(t, err) +} + +func TestActionsService_DeleteArtifact_notFound(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/repos/o/r/actions/artifacts/1", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "DELETE") + w.WriteHeader(http.StatusNotFound) + }) + + resp, err := client.Actions.DeleteArtifact(context.Background(), "o", "r", 1) + if err == nil { + t.Errorf("Expected HTTP 404 response") + } + if got, want := resp.Response.StatusCode, http.StatusNotFound; got != want { + t.Errorf("Actions.DeleteArtifact return status %d, want %d", got, want) + } +} diff --git a/github/github-accessors.go b/github/github-accessors.go index a1f3e0c19a3..df6af24f063 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -308,6 +308,78 @@ func (a *AppConfig) GetWebhookSecret() string { return *a.WebhookSecret } +// GetArchiveDownloadURL returns the ArchiveDownloadURL field if it's non-nil, zero value otherwise. +func (a *Artifact) GetArchiveDownloadURL() string { + if a == nil || a.ArchiveDownloadURL == nil { + return "" + } + return *a.ArchiveDownloadURL +} + +// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise. +func (a *Artifact) GetCreatedAt() Timestamp { + if a == nil || a.CreatedAt == nil { + return Timestamp{} + } + return *a.CreatedAt +} + +// GetExpired returns the Expired field if it's non-nil, zero value otherwise. +func (a *Artifact) GetExpired() bool { + if a == nil || a.Expired == nil { + return false + } + return *a.Expired +} + +// GetExpiresAt returns the ExpiresAt field if it's non-nil, zero value otherwise. +func (a *Artifact) GetExpiresAt() Timestamp { + if a == nil || a.ExpiresAt == nil { + return Timestamp{} + } + return *a.ExpiresAt +} + +// GetID returns the ID field if it's non-nil, zero value otherwise. +func (a *Artifact) GetID() int64 { + if a == nil || a.ID == nil { + return 0 + } + return *a.ID +} + +// GetName returns the Name field if it's non-nil, zero value otherwise. +func (a *Artifact) GetName() string { + if a == nil || a.Name == nil { + return "" + } + return *a.Name +} + +// GetNodeID returns the NodeID field if it's non-nil, zero value otherwise. +func (a *Artifact) GetNodeID() string { + if a == nil || a.NodeID == nil { + return "" + } + return *a.NodeID +} + +// GetSizeInBytes returns the SizeInBytes field if it's non-nil, zero value otherwise. +func (a *Artifact) GetSizeInBytes() int64 { + if a == nil || a.SizeInBytes == nil { + return 0 + } + return *a.SizeInBytes +} + +// GetTotalCount returns the TotalCount field if it's non-nil, zero value otherwise. +func (a *ArtifactList) GetTotalCount() int64 { + if a == nil || a.TotalCount == nil { + return 0 + } + return *a.TotalCount +} + // GetBody returns the Body field if it's non-nil, zero value otherwise. func (a *Attachment) GetBody() string { if a == nil || a.Body == nil { From 300f887624980b9901c9bcd6bfd29dfcd01ca58a Mon Sep 17 00:00:00 2001 From: Joshua Bezaleel Abednego Date: Thu, 27 Feb 2020 19:44:05 +0700 Subject: [PATCH 0138/1468] Implement support for actions workflow jobs (#1421) Relates to: #1399. --- github/actions_workflow_jobs.go | 137 +++++++++++++++++++++++ github/actions_workflow_jobs_test.go | 136 +++++++++++++++++++++++ github/github-accessors.go | 160 +++++++++++++++++++++++++++ 3 files changed, 433 insertions(+) create mode 100644 github/actions_workflow_jobs.go create mode 100644 github/actions_workflow_jobs_test.go diff --git a/github/actions_workflow_jobs.go b/github/actions_workflow_jobs.go new file mode 100644 index 00000000000..d9adad7de4d --- /dev/null +++ b/github/actions_workflow_jobs.go @@ -0,0 +1,137 @@ +// Copyright 2020 The go-github AUTHORS. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package github + +import ( + "context" + "fmt" + "net/http" + "net/url" +) + +// TaskStep represents a single task step from a sequence of tasks of a job. +type TaskStep struct { + Name *string `json:"name,omitempty"` + Status *string `json:"status,omitempty"` + Conclusion *string `json:"conclusion,omitempty"` + Number *int64 `json:"number,omitempty"` + StartedAt *Timestamp `json:"started_at,omitempty"` + CompletedAt *Timestamp `json:"completed_at,omitempty"` +} + +// WorkflowJob represents a repository action workflow job. +type WorkflowJob struct { + ID *int64 `json:"id,omitempty"` + RunID *int64 `json:"run_id,omitempty"` + RunURL *string `json:"run_url,omitempty"` + NodeID *string `json:"node_id,omitempty"` + HeadSHA *string `json:"head_sha,omitempty"` + URL *string `json:"url,omitempty"` + HTMLURL *string `json:"html_url,omitempty"` + Status *string `json:"status,omitempty"` + Conclusion *string `json:"conclusion,omitempty"` + StartedAt *Timestamp `json:"started_at,omitempty"` + CompletedAt *Timestamp `json:"completed_at,omitempty"` + Name *string `json:"name,omitempty"` + Steps []*TaskStep `json:"steps,omitempty"` + CheckRunURL *string `json:"check_run_url,omitempty"` +} + +// Jobs represents a slice of repository action workflow job. +type Jobs struct { + TotalCount *int `json:"total_count,omitempty"` + Jobs []*WorkflowJob `json:"jobs,omitempty"` +} + +// ListWorkflowJobs lists all jobs for a workflow run. +// +// GitHub API docs: https://developer.github.com/v3/actions/workflow_jobs/#list-jobs-for-a-workflow-run +func (s *ActionsService) ListWorkflowJobs(ctx context.Context, owner, repo string, runID int64, opts *ListOptions) (*Jobs, *Response, error) { + u := fmt.Sprintf("repos/%s/%s/actions/runs/%v/jobs", owner, repo, runID) + u, err := addOptions(u, opts) + if err != nil { + return nil, nil, err + } + + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + + jobs := new(Jobs) + resp, err := s.client.Do(ctx, req, &jobs) + if err != nil { + return nil, resp, err + } + + return jobs, resp, nil +} + +// GetWorkflowJobByID gets a specific job in a workflow run by ID. +// +// GitHub API docs: https://developer.github.com/v3/actions/workflow_jobs/#list-jobs-for-a-workflow-run +func (s *ActionsService) GetWorkflowJobByID(ctx context.Context, owner, repo string, jobID int64) (*WorkflowJob, *Response, error) { + u := fmt.Sprintf("repos/%v/%v/actions/jobs/%v", owner, repo, jobID) + + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + + job := new(WorkflowJob) + resp, err := s.client.Do(ctx, req, job) + if err != nil { + return nil, resp, err + } + + return job, resp, nil +} + +// GetWorkflowJobLogs gets a redirect URL to download a plain text file of logs for a workflow job. +// +// GitHub API docs: https://developer.github.com/v3/actions/workflow_jobs/#list-workflow-job-logs +func (s *ActionsService) GetWorkflowJobLogs(ctx context.Context, owner, repo string, jobID int64, followRedirects bool) (*url.URL, *Response, error) { + u := fmt.Sprintf("repos/%v/%v/actions/jobs/%v/logs", owner, repo, jobID) + + resp, err := s.getWorkflowJobLogsFromURL(ctx, u, followRedirects) + if err != nil { + return nil, nil, err + } + + if resp.StatusCode != http.StatusFound { + return nil, newResponse(resp), fmt.Errorf("unexpected status code: %s", resp.Status) + } + parsedURL, err := url.Parse(resp.Header.Get("Location")) + return parsedURL, newResponse(resp), err +} + +func (s *ActionsService) getWorkflowJobLogsFromURL(ctx context.Context, u string, followRedirects bool) (*http.Response, error) { + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, err + } + + var resp *http.Response + // Use http.DefaultTransport if no custom Transport is configured + req = withContext(ctx, req) + if s.client.client.Transport == nil { + resp, err = http.DefaultTransport.RoundTrip(req) + } else { + resp, err = s.client.client.Transport.RoundTrip(req) + } + if err != nil { + return nil, err + } + resp.Body.Close() + + // If redirect response is returned, follow it + if followRedirects && resp.StatusCode == http.StatusMovedPermanently { + u = resp.Header.Get("Location") + resp, err = s.getWorkflowJobLogsFromURL(ctx, u, false) + } + return resp, err + +} diff --git a/github/actions_workflow_jobs_test.go b/github/actions_workflow_jobs_test.go new file mode 100644 index 00000000000..36cf7a82ea4 --- /dev/null +++ b/github/actions_workflow_jobs_test.go @@ -0,0 +1,136 @@ +// Copyright 2020 The go-github AUTHORS. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package github + +import ( + "context" + "fmt" + "net/http" + "net/url" + "reflect" + "testing" + "time" +) + +func TestActionsService_ListWorkflowJobs(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/repos/o/r/actions/runs/29679449/jobs", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + testFormValues(t, r, values{"per_page": "2", "page": "2"}) + fmt.Fprint(w, `{"total_count":4,"jobs":[{"id":399444496,"run_id":29679449,"started_at":"2019-01-02T15:04:05Z","completed_at":"2020-01-02T15:04:05Z"},{"id":399444497,"run_id":29679449,"started_at":"2019-01-02T15:04:05Z","completed_at":"2020-01-02T15:04:05Z"}]}`) + }) + + opts := &ListOptions{Page: 2, PerPage: 2} + jobs, _, err := client.Actions.ListWorkflowJobs(context.Background(), "o", "r", 29679449, opts) + if err != nil { + t.Errorf("Actions.ListWorkflowJobs returned error: %v", err) + } + + want := &Jobs{ + TotalCount: Int(4), + Jobs: []*WorkflowJob{ + {ID: Int64(399444496), RunID: Int64(29679449), StartedAt: &Timestamp{time.Date(2019, time.January, 02, 15, 04, 05, 0, time.UTC)}, CompletedAt: &Timestamp{time.Date(2020, time.January, 02, 15, 04, 05, 0, time.UTC)}}, + {ID: Int64(399444497), RunID: Int64(29679449), StartedAt: &Timestamp{time.Date(2019, time.January, 02, 15, 04, 05, 0, time.UTC)}, CompletedAt: &Timestamp{time.Date(2020, time.January, 02, 15, 04, 05, 0, time.UTC)}}, + }, + } + if !reflect.DeepEqual(jobs, want) { + t.Errorf("Actions.ListWorkflowJobs returned %+v, want %+v", jobs, want) + } +} + +func TestActionsService_GetWorkflowJobByID(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/repos/o/r/actions/jobs/399444496", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + fmt.Fprint(w, `{"id":399444496,"started_at":"2019-01-02T15:04:05Z","completed_at":"2020-01-02T15:04:05Z"}`) + }) + + job, _, err := client.Actions.GetWorkflowJobByID(context.Background(), "o", "r", 399444496) + if err != nil { + t.Errorf("Actions.GetWorkflowJobByID returned error: %v", err) + } + + want := &WorkflowJob{ + ID: Int64(399444496), + StartedAt: &Timestamp{time.Date(2019, time.January, 02, 15, 04, 05, 0, time.UTC)}, + CompletedAt: &Timestamp{time.Date(2020, time.January, 02, 15, 04, 05, 0, time.UTC)}, + } + if !reflect.DeepEqual(job, want) { + t.Errorf("Actions.GetWorkflowJobByID returned %+v, want %+v", job, want) + } +} + +func TestActionsService_GetWorkflowJobLogs(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/repos/o/r/actions/jobs/399444496/logs", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + http.Redirect(w, r, "http://github.com/a", http.StatusFound) + }) + + url, resp, err := client.Actions.GetWorkflowJobLogs(context.Background(), "o", "r", 399444496, true) + if err != nil { + t.Errorf("Actions.GetWorkflowJobLogs returned error: %v", err) + } + if resp.StatusCode != http.StatusFound { + t.Errorf("Actions.GetWorkflowJobLogs returned status: %d, want %d", resp.StatusCode, http.StatusFound) + } + want := "http://github.com/a" + if url.String() != want { + t.Errorf("Actions.GetWorkflowJobLogs returned %+v, want %+v", url.String(), want) + } +} + +func TestActionsService_GetWorkflowJobLogs_StatusMovedPermanently_dontFollowRedirects(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/repos/o/r/actions/jobs/399444496/logs", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + http.Redirect(w, r, "http://github.com/a", http.StatusMovedPermanently) + }) + + _, resp, _ := client.Actions.GetWorkflowJobLogs(context.Background(), "o", "r", 399444496, false) + if resp.StatusCode != http.StatusMovedPermanently { + t.Errorf("Actions.GetWorkflowJobLogs returned status: %d, want %d", resp.StatusCode, http.StatusMovedPermanently) + } +} + +func TestActionsService_GetWorkflowJobLogs_StatusMovedPermanently_followRedirects(t *testing.T) { + client, mux, serverURL, teardown := setup() + defer teardown() + + // Mock a redirect link, which leads to an archive link + mux.HandleFunc("/repos/o/r/actions/jobs/399444496/logs", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + redirectURL, _ := url.Parse(serverURL + baseURLPath + "/redirect") + http.Redirect(w, r, redirectURL.String(), http.StatusMovedPermanently) + }) + + mux.HandleFunc("/redirect", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + http.Redirect(w, r, "http://github.com/a", http.StatusFound) + }) + + url, resp, err := client.Actions.GetWorkflowJobLogs(context.Background(), "o", "r", 399444496, true) + if err != nil { + t.Errorf("Actions.GetWorkflowJobLogs returned error: %v", err) + } + + if resp.StatusCode != http.StatusFound { + t.Errorf("Actions.GetWorkflowJobLogs returned status: %d, want %d", resp.StatusCode, http.StatusFound) + } + + want := "http://github.com/a" + if url.String() != want { + t.Errorf("Actions.GetWorkflowJobLogs returned %+v, want %+v", url.String(), want) + } +} diff --git a/github/github-accessors.go b/github/github-accessors.go index df6af24f063..2ad2af181e1 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -5044,6 +5044,14 @@ func (i *IssueStats) GetTotalIssues() int { return *i.TotalIssues } +// GetTotalCount returns the TotalCount field if it's non-nil, zero value otherwise. +func (j *Jobs) GetTotalCount() int { + if j == nil || j.TotalCount == nil { + return 0 + } + return *j.TotalCount +} + // GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise. func (k *Key) GetCreatedAt() Timestamp { if k == nil || k.CreatedAt == nil { @@ -11988,6 +11996,54 @@ func (t *Tag) GetVerification() *SignatureVerification { return t.Verification } +// GetCompletedAt returns the CompletedAt field if it's non-nil, zero value otherwise. +func (t *TaskStep) GetCompletedAt() Timestamp { + if t == nil || t.CompletedAt == nil { + return Timestamp{} + } + return *t.CompletedAt +} + +// GetConclusion returns the Conclusion field if it's non-nil, zero value otherwise. +func (t *TaskStep) GetConclusion() string { + if t == nil || t.Conclusion == nil { + return "" + } + return *t.Conclusion +} + +// GetName returns the Name field if it's non-nil, zero value otherwise. +func (t *TaskStep) GetName() string { + if t == nil || t.Name == nil { + return "" + } + return *t.Name +} + +// GetNumber returns the Number field if it's non-nil, zero value otherwise. +func (t *TaskStep) GetNumber() int64 { + if t == nil || t.Number == nil { + return 0 + } + return *t.Number +} + +// GetStartedAt returns the StartedAt field if it's non-nil, zero value otherwise. +func (t *TaskStep) GetStartedAt() Timestamp { + if t == nil || t.StartedAt == nil { + return Timestamp{} + } + return *t.StartedAt +} + +// GetStatus returns the Status field if it's non-nil, zero value otherwise. +func (t *TaskStep) GetStatus() string { + if t == nil || t.Status == nil { + return "" + } + return *t.Status +} + // GetDescription returns the Description field if it's non-nil, zero value otherwise. func (t *Team) GetDescription() string { if t == nil || t.Description == nil { @@ -14004,6 +14060,110 @@ func (w *Workflow) GetURL() string { return *w.URL } +// GetCheckRunURL returns the CheckRunURL field if it's non-nil, zero value otherwise. +func (w *WorkflowJob) GetCheckRunURL() string { + if w == nil || w.CheckRunURL == nil { + return "" + } + return *w.CheckRunURL +} + +// GetCompletedAt returns the CompletedAt field if it's non-nil, zero value otherwise. +func (w *WorkflowJob) GetCompletedAt() Timestamp { + if w == nil || w.CompletedAt == nil { + return Timestamp{} + } + return *w.CompletedAt +} + +// GetConclusion returns the Conclusion field if it's non-nil, zero value otherwise. +func (w *WorkflowJob) GetConclusion() string { + if w == nil || w.Conclusion == nil { + return "" + } + return *w.Conclusion +} + +// GetHeadSHA returns the HeadSHA field if it's non-nil, zero value otherwise. +func (w *WorkflowJob) GetHeadSHA() string { + if w == nil || w.HeadSHA == nil { + return "" + } + return *w.HeadSHA +} + +// GetHTMLURL returns the HTMLURL field if it's non-nil, zero value otherwise. +func (w *WorkflowJob) GetHTMLURL() string { + if w == nil || w.HTMLURL == nil { + return "" + } + return *w.HTMLURL +} + +// GetID returns the ID field if it's non-nil, zero value otherwise. +func (w *WorkflowJob) GetID() int64 { + if w == nil || w.ID == nil { + return 0 + } + return *w.ID +} + +// GetName returns the Name field if it's non-nil, zero value otherwise. +func (w *WorkflowJob) GetName() string { + if w == nil || w.Name == nil { + return "" + } + return *w.Name +} + +// GetNodeID returns the NodeID field if it's non-nil, zero value otherwise. +func (w *WorkflowJob) GetNodeID() string { + if w == nil || w.NodeID == nil { + return "" + } + return *w.NodeID +} + +// GetRunID returns the RunID field if it's non-nil, zero value otherwise. +func (w *WorkflowJob) GetRunID() int64 { + if w == nil || w.RunID == nil { + return 0 + } + return *w.RunID +} + +// GetRunURL returns the RunURL field if it's non-nil, zero value otherwise. +func (w *WorkflowJob) GetRunURL() string { + if w == nil || w.RunURL == nil { + return "" + } + return *w.RunURL +} + +// GetStartedAt returns the StartedAt field if it's non-nil, zero value otherwise. +func (w *WorkflowJob) GetStartedAt() Timestamp { + if w == nil || w.StartedAt == nil { + return Timestamp{} + } + return *w.StartedAt +} + +// GetStatus returns the Status field if it's non-nil, zero value otherwise. +func (w *WorkflowJob) GetStatus() string { + if w == nil || w.Status == nil { + return "" + } + return *w.Status +} + +// GetURL returns the URL field if it's non-nil, zero value otherwise. +func (w *WorkflowJob) GetURL() string { + if w == nil || w.URL == nil { + return "" + } + return *w.URL +} + // GetTotalCount returns the TotalCount field if it's non-nil, zero value otherwise. func (w *Workflows) GetTotalCount() int { if w == nil || w.TotalCount == nil { From 921fbd6a5b4ea07bb10df1727b022224295bf1db Mon Sep 17 00:00:00 2001 From: kadern0 Date: Fri, 28 Feb 2020 07:53:31 +1100 Subject: [PATCH 0139/1468] Update teams_discussions with ByID and BySlug endpoints (#1426) Fixes: #1424. --- github/teams_discussions.go | 134 +++++++++++++++-- github/teams_discussions_test.go | 241 ++++++++++++++++++++++++++++--- 2 files changed, 335 insertions(+), 40 deletions(-) diff --git a/github/teams_discussions.go b/github/teams_discussions.go index 433d01595a6..f0f2206ac92 100644 --- a/github/teams_discussions.go +++ b/github/teams_discussions.go @@ -42,15 +42,42 @@ type DiscussionListOptions struct { // Sorts the discussion by the date they were created. // Accepted values are asc and desc. Default is desc. Direction string `url:"direction,omitempty"` + + ListOptions +} + +// ListDiscussionsByID lists all discussions on team's page given Organization and Team ID. +// Authenticated user must grant read:discussion scope. +// +// GitHub API docs: https://developer.github.com/v3/teams/discussions/#list-discussions +func (s *TeamsService) ListDiscussionsByID(ctx context.Context, orgID, teamID int64, opts *DiscussionListOptions) ([]*TeamDiscussion, *Response, error) { + u := fmt.Sprintf("organizations/%v/team/%v/discussions", orgID, teamID) + u, err := addOptions(u, opts) + if err != nil { + return nil, nil, err + } + + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + + var teamDiscussions []*TeamDiscussion + resp, err := s.client.Do(ctx, req, &teamDiscussions) + if err != nil { + return nil, resp, err + } + + return teamDiscussions, resp, nil } -// ListDiscussions lists all discussions on team's page. +// ListDiscussionsBySlug lists all discussions on team's page given Organization name and Team's slug. // Authenticated user must grant read:discussion scope. // // GitHub API docs: https://developer.github.com/v3/teams/discussions/#list-discussions -func (s *TeamsService) ListDiscussions(ctx context.Context, teamID int64, options *DiscussionListOptions) ([]*TeamDiscussion, *Response, error) { - u := fmt.Sprintf("teams/%v/discussions", teamID) - u, err := addOptions(u, options) +func (s *TeamsService) ListDiscussionsBySlug(ctx context.Context, org, slug string, opts *DiscussionListOptions) ([]*TeamDiscussion, *Response, error) { + u := fmt.Sprintf("orgs/%v/teams/%v/discussions", org, slug) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } @@ -69,12 +96,12 @@ func (s *TeamsService) ListDiscussions(ctx context.Context, teamID int64, option return teamDiscussions, resp, nil } -// GetDiscussion gets a specific discussion on a team's page. +// GetDiscussionByID gets a specific discussion on a team's page given Organization and Team ID. // Authenticated user must grant read:discussion scope. // // GitHub API docs: https://developer.github.com/v3/teams/discussions/#get-a-single-discussion -func (s *TeamsService) GetDiscussion(ctx context.Context, teamID int64, discussionNumber int) (*TeamDiscussion, *Response, error) { - u := fmt.Sprintf("teams/%v/discussions/%v", teamID, discussionNumber) +func (s *TeamsService) GetDiscussionByID(ctx context.Context, orgID, teamID int64, discussionNumber int) (*TeamDiscussion, *Response, error) { + u := fmt.Sprintf("organizations/%v/team/%v/discussions/%v", orgID, teamID, discussionNumber) req, err := s.client.NewRequest("GET", u, nil) if err != nil { return nil, nil, err @@ -89,12 +116,32 @@ func (s *TeamsService) GetDiscussion(ctx context.Context, teamID int64, discussi return teamDiscussion, resp, nil } -// CreateDiscussion creates a new discussion post on a team's page. +// GetDiscussionBySlug gets a specific discussion on a team's page given Organization name and Team's slug. +// Authenticated user must grant read:discussion scope. +// +// GitHub API docs: https://developer.github.com/v3/teams/discussions/#get-a-single-discussion +func (s *TeamsService) GetDiscussionBySlug(ctx context.Context, org, slug string, discussionNumber int) (*TeamDiscussion, *Response, error) { + u := fmt.Sprintf("orgs/%v/teams/%v/discussions/%v", org, slug, discussionNumber) + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + + teamDiscussion := &TeamDiscussion{} + resp, err := s.client.Do(ctx, req, teamDiscussion) + if err != nil { + return nil, resp, err + } + + return teamDiscussion, resp, nil +} + +// CreateDiscussionByID creates a new discussion post on a team's page given Organization and Team ID. // Authenticated user must grant write:discussion scope. // // GitHub API docs: https://developer.github.com/v3/teams/discussions/#create-a-discussion -func (s *TeamsService) CreateDiscussion(ctx context.Context, teamID int64, discussion TeamDiscussion) (*TeamDiscussion, *Response, error) { - u := fmt.Sprintf("teams/%v/discussions", teamID) +func (s *TeamsService) CreateDiscussionByID(ctx context.Context, orgID, teamID int64, discussion TeamDiscussion) (*TeamDiscussion, *Response, error) { + u := fmt.Sprintf("organizations/%v/team/%v/discussions", orgID, teamID) req, err := s.client.NewRequest("POST", u, discussion) if err != nil { return nil, nil, err @@ -109,13 +156,54 @@ func (s *TeamsService) CreateDiscussion(ctx context.Context, teamID int64, discu return teamDiscussion, resp, nil } -// EditDiscussion edits the title and body text of a discussion post. +// CreateDiscussionBySlug creates a new discussion post on a team's page given Organization name and Team's slug. +// Authenticated user must grant write:discussion scope. +// +// GitHub API docs: https://developer.github.com/v3/teams/discussions/#create-a-discussion +func (s *TeamsService) CreateDiscussionBySlug(ctx context.Context, org, slug string, discussion TeamDiscussion) (*TeamDiscussion, *Response, error) { + u := fmt.Sprintf("orgs/%v/teams/%v/discussions", org, slug) + req, err := s.client.NewRequest("POST", u, discussion) + if err != nil { + return nil, nil, err + } + + teamDiscussion := &TeamDiscussion{} + resp, err := s.client.Do(ctx, req, teamDiscussion) + if err != nil { + return nil, resp, err + } + + return teamDiscussion, resp, nil +} + +// EditDiscussionByID edits the title and body text of a discussion post given Organization and Team ID. +// Authenticated user must grant write:discussion scope. +// User is allowed to change Title and Body of a discussion only. +// +// GitHub API docs: https://developer.github.com/v3/teams/discussions/#edit-a-discussion +func (s *TeamsService) EditDiscussionByID(ctx context.Context, orgID, teamID int64, discussionNumber int, discussion TeamDiscussion) (*TeamDiscussion, *Response, error) { + u := fmt.Sprintf("organizations/%v/team/%v/discussions/%v", orgID, teamID, discussionNumber) + req, err := s.client.NewRequest("PATCH", u, discussion) + if err != nil { + return nil, nil, err + } + + teamDiscussion := &TeamDiscussion{} + resp, err := s.client.Do(ctx, req, teamDiscussion) + if err != nil { + return nil, resp, err + } + + return teamDiscussion, resp, nil +} + +// EditDiscussionBySlug edits the title and body text of a discussion post given Organization name and Team's slug. // Authenticated user must grant write:discussion scope. // User is allowed to change Title and Body of a discussion only. // // GitHub API docs: https://developer.github.com/v3/teams/discussions/#edit-a-discussion -func (s *TeamsService) EditDiscussion(ctx context.Context, teamID int64, discussionNumber int, discussion TeamDiscussion) (*TeamDiscussion, *Response, error) { - u := fmt.Sprintf("teams/%v/discussions/%v", teamID, discussionNumber) +func (s *TeamsService) EditDiscussionBySlug(ctx context.Context, org, slug string, discussionNumber int, discussion TeamDiscussion) (*TeamDiscussion, *Response, error) { + u := fmt.Sprintf("orgs/%v/teams/%v/discussions/%v", org, slug, discussionNumber) req, err := s.client.NewRequest("PATCH", u, discussion) if err != nil { return nil, nil, err @@ -130,12 +218,26 @@ func (s *TeamsService) EditDiscussion(ctx context.Context, teamID int64, discuss return teamDiscussion, resp, nil } -// DeleteDiscussion deletes a discussion from team's page. +// DeleteDiscussionByID deletes a discussion from team's page given Organization and Team ID. +// Authenticated user must grant write:discussion scope. +// +// GitHub API docs: https://developer.github.com/v3/teams/discussions/#delete-a-discussion +func (s *TeamsService) DeleteDiscussionByID(ctx context.Context, orgID, teamID int64, discussionNumber int) (*Response, error) { + u := fmt.Sprintf("organizations/%v/team/%v/discussions/%v", orgID, teamID, discussionNumber) + req, err := s.client.NewRequest("DELETE", u, nil) + if err != nil { + return nil, err + } + + return s.client.Do(ctx, req, nil) +} + +// DeleteDiscussionBySlug deletes a discussion from team's page given Organization name and Team's slug. // Authenticated user must grant write:discussion scope. // // GitHub API docs: https://developer.github.com/v3/teams/discussions/#delete-a-discussion -func (s *TeamsService) DeleteDiscussion(ctx context.Context, teamID int64, discussionNumber int) (*Response, error) { - u := fmt.Sprintf("teams/%v/discussions/%v", teamID, discussionNumber) +func (s *TeamsService) DeleteDiscussionBySlug(ctx context.Context, org, slug string, discussionNumber int) (*Response, error) { + u := fmt.Sprintf("orgs/%v/teams/%v/discussions/%v", org, slug, discussionNumber) req, err := s.client.NewRequest("DELETE", u, nil) if err != nil { return nil, err diff --git a/github/teams_discussions_test.go b/github/teams_discussions_test.go index 65be1ce6f3d..5807bd3cb99 100644 --- a/github/teams_discussions_test.go +++ b/github/teams_discussions_test.go @@ -15,14 +15,15 @@ import ( "time" ) -func TestTeamsService_ListDiscussions(t *testing.T) { +func TestTeamsService_ListDiscussionsByID(t *testing.T) { client, mux, _, teardown := setup() defer teardown() - mux.HandleFunc("/teams/2/discussions", func(w http.ResponseWriter, r *http.Request) { + mux.HandleFunc("/organizations/1/team/2/discussions", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") testFormValues(t, r, values{ "direction": "desc", + "page": "2", }) fmt.Fprintf(w, `[ @@ -65,9 +66,9 @@ func TestTeamsService_ListDiscussions(t *testing.T) { } ]`) }) - discussions, _, err := client.Teams.ListDiscussions(context.Background(), 2, &DiscussionListOptions{"desc"}) + discussions, _, err := client.Teams.ListDiscussionsByID(context.Background(), 1, 2, &DiscussionListOptions{"desc", ListOptions{Page: 2}}) if err != nil { - t.Errorf("Teams.ListDiscussions returned error: %v", err) + t.Errorf("Teams.ListDiscussionsByID returned error: %v", err) } want := []*TeamDiscussion{ @@ -110,37 +111,157 @@ func TestTeamsService_ListDiscussions(t *testing.T) { }, } if !reflect.DeepEqual(discussions, want) { - t.Errorf("Teams.ListDiscussions returned %+v, want %+v", discussions, want) + t.Errorf("Teams.ListDiscussionsByID returned %+v, want %+v", discussions, want) } } -func TestTeamsService_GetDiscussion(t *testing.T) { +func TestTeamsService_ListDiscussionsBySlug(t *testing.T) { client, mux, _, teardown := setup() defer teardown() - mux.HandleFunc("/teams/2/discussions/3", func(w http.ResponseWriter, r *http.Request) { + mux.HandleFunc("/orgs/o/teams/s/discussions", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + testFormValues(t, r, values{ + "direction": "desc", + "page": "2", + }) + fmt.Fprintf(w, + `[ + { + "author": { + "login": "author", + "id": 0, + "avatar_url": "https://avatars1.githubusercontent.com/u/0?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/author", + "html_url": "https://github.com/author", + "followers_url": "https://api.github.com/users/author/followers", + "following_url": "https://api.github.com/users/author/following{/other_user}", + "gists_url": "https://api.github.com/users/author/gists{/gist_id}", + "starred_url": "https://api.github.com/users/author/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/author/subscriptions", + "organizations_url": "https://api.github.com/users/author/orgs", + "repos_url": "https://api.github.com/users/author/repos", + "events_url": "https://api.github.com/users/author/events{/privacy}", + "received_events_url": "https://api.github.com/users/author/received_events", + "type": "User", + "site_admin": false + }, + "body": "test", + "body_html": "

test

", + "body_version": "version", + "comments_count": 1, + "comments_url": "https://api.github.com/teams/2/discussions/3/comments", + "created_at": "2018-01-01T00:00:00Z", + "last_edited_at": null, + "html_url": "https://github.com/orgs/1/teams/2/discussions/3", + "node_id": "node", + "number": 3, + "pinned": false, + "private": false, + "team_url": "https://api.github.com/teams/2", + "title": "test", + "updated_at": "2018-01-01T00:00:00Z", + "url": "https://api.github.com/teams/2/discussions/3" + } + ]`) + }) + discussions, _, err := client.Teams.ListDiscussionsBySlug(context.Background(), "o", "s", &DiscussionListOptions{"desc", ListOptions{Page: 2}}) + if err != nil { + t.Errorf("Teams.ListDiscussionsBySlug returned error: %v", err) + } + + want := []*TeamDiscussion{ + { + Author: &User{ + Login: String("author"), + ID: Int64(0), + AvatarURL: String("https://avatars1.githubusercontent.com/u/0?v=4"), + GravatarID: String(""), + URL: String("https://api.github.com/users/author"), + HTMLURL: String("https://github.com/author"), + FollowersURL: String("https://api.github.com/users/author/followers"), + FollowingURL: String("https://api.github.com/users/author/following{/other_user}"), + GistsURL: String("https://api.github.com/users/author/gists{/gist_id}"), + StarredURL: String("https://api.github.com/users/author/starred{/owner}{/repo}"), + SubscriptionsURL: String("https://api.github.com/users/author/subscriptions"), + OrganizationsURL: String("https://api.github.com/users/author/orgs"), + ReposURL: String("https://api.github.com/users/author/repos"), + EventsURL: String("https://api.github.com/users/author/events{/privacy}"), + ReceivedEventsURL: String("https://api.github.com/users/author/received_events"), + Type: String("User"), + SiteAdmin: Bool(false), + }, + Body: String("test"), + BodyHTML: String("

test

"), + BodyVersion: String("version"), + CommentsCount: Int(1), + CommentsURL: String("https://api.github.com/teams/2/discussions/3/comments"), + CreatedAt: &Timestamp{time.Date(2018, time.January, 1, 0, 0, 0, 0, time.UTC)}, + LastEditedAt: nil, + HTMLURL: String("https://github.com/orgs/1/teams/2/discussions/3"), + NodeID: String("node"), + Number: Int(3), + Pinned: Bool(false), + Private: Bool(false), + TeamURL: String("https://api.github.com/teams/2"), + Title: String("test"), + UpdatedAt: &Timestamp{time.Date(2018, time.January, 1, 0, 0, 0, 0, time.UTC)}, + URL: String("https://api.github.com/teams/2/discussions/3"), + }, + } + if !reflect.DeepEqual(discussions, want) { + t.Errorf("Teams.ListDiscussionsBySlug returned %+v, want %+v", discussions, want) + } +} + +func TestTeamsService_GetDiscussionByID(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/organizations/1/team/2/discussions/3", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + fmt.Fprint(w, `{"number":3}`) + }) + + discussion, _, err := client.Teams.GetDiscussionByID(context.Background(), 1, 2, 3) + if err != nil { + t.Errorf("Teams.GetDiscussionByID returned error: %v", err) + } + + want := &TeamDiscussion{Number: Int(3)} + if !reflect.DeepEqual(discussion, want) { + t.Errorf("Teams.GetDiscussionByID returned %+v, want %+v", discussion, want) + } +} + +func TestTeamsService_GetDiscussionBySlug(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/orgs/o/teams/s/discussions/3", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") fmt.Fprint(w, `{"number":3}`) }) - discussion, _, err := client.Teams.GetDiscussion(context.Background(), 2, 3) + discussion, _, err := client.Teams.GetDiscussionBySlug(context.Background(), "o", "s", 3) if err != nil { - t.Errorf("Teams.GetDiscussion returned error: %v", err) + t.Errorf("Teams.GetDiscussionBySlug returned error: %v", err) } want := &TeamDiscussion{Number: Int(3)} if !reflect.DeepEqual(discussion, want) { - t.Errorf("Teams.GetDiscussion returned %+v, want %+v", discussion, want) + t.Errorf("Teams.GetDiscussionBySlug returned %+v, want %+v", discussion, want) } } -func TestTeamsService_CreateDiscussion(t *testing.T) { +func TestTeamsService_CreateDiscussionByID(t *testing.T) { client, mux, _, teardown := setup() defer teardown() input := TeamDiscussion{Title: String("c_t"), Body: String("c_b")} - mux.HandleFunc("/teams/2/discussions", func(w http.ResponseWriter, r *http.Request) { + mux.HandleFunc("/organizations/1/team/2/discussions", func(w http.ResponseWriter, r *http.Request) { v := new(TeamDiscussion) json.NewDecoder(r.Body).Decode(v) @@ -152,24 +273,53 @@ func TestTeamsService_CreateDiscussion(t *testing.T) { fmt.Fprint(w, `{"number":3}`) }) - comment, _, err := client.Teams.CreateDiscussion(context.Background(), 2, input) + comment, _, err := client.Teams.CreateDiscussionByID(context.Background(), 1, 2, input) if err != nil { - t.Errorf("Teams.CreateDiscussion returned error: %v", err) + t.Errorf("Teams.CreateDiscussionByID returned error: %v", err) } want := &TeamDiscussion{Number: Int(3)} if !reflect.DeepEqual(comment, want) { - t.Errorf("Teams.CreateDiscussion returned %+v, want %+v", comment, want) + t.Errorf("Teams.CreateDiscussionByID returned %+v, want %+v", comment, want) } } -func TestTeamsService_EditDiscussion(t *testing.T) { +func TestTeamsService_CreateDiscussionBySlug(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + input := TeamDiscussion{Title: String("c_t"), Body: String("c_b")} + + mux.HandleFunc("/orgs/o/teams/s/discussions", func(w http.ResponseWriter, r *http.Request) { + v := new(TeamDiscussion) + json.NewDecoder(r.Body).Decode(v) + + testMethod(t, r, "POST") + if !reflect.DeepEqual(v, &input) { + t.Errorf("Request body = %+v, want %+v", v, input) + } + + fmt.Fprint(w, `{"number":3}`) + }) + + comment, _, err := client.Teams.CreateDiscussionBySlug(context.Background(), "o", "s", input) + if err != nil { + t.Errorf("Teams.CreateDiscussionBySlug returned error: %v", err) + } + + want := &TeamDiscussion{Number: Int(3)} + if !reflect.DeepEqual(comment, want) { + t.Errorf("Teams.CreateDiscussionBySlug returned %+v, want %+v", comment, want) + } +} + +func TestTeamsService_EditDiscussionByID(t *testing.T) { client, mux, _, teardown := setup() defer teardown() input := TeamDiscussion{Title: String("e_t"), Body: String("e_b")} - mux.HandleFunc("/teams/2/discussions/3", func(w http.ResponseWriter, r *http.Request) { + mux.HandleFunc("/organizations/1/team/2/discussions/3", func(w http.ResponseWriter, r *http.Request) { v := new(TeamDiscussion) json.NewDecoder(r.Body).Decode(v) @@ -181,27 +331,70 @@ func TestTeamsService_EditDiscussion(t *testing.T) { fmt.Fprint(w, `{"number":3}`) }) - comment, _, err := client.Teams.EditDiscussion(context.Background(), 2, 3, input) + comment, _, err := client.Teams.EditDiscussionByID(context.Background(), 1, 2, 3, input) if err != nil { - t.Errorf("Teams.EditDiscussion returned error: %v", err) + t.Errorf("Teams.EditDiscussionByID returned error: %v", err) } want := &TeamDiscussion{Number: Int(3)} if !reflect.DeepEqual(comment, want) { - t.Errorf("Teams.EditDiscussion returned %+v, want %+v", comment, want) + t.Errorf("Teams.EditDiscussionByID returned %+v, want %+v", comment, want) + } +} + +func TestTeamsService_EditDiscussionBySlug(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + input := TeamDiscussion{Title: String("e_t"), Body: String("e_b")} + + mux.HandleFunc("/orgs/o/teams/s/discussions/3", func(w http.ResponseWriter, r *http.Request) { + v := new(TeamDiscussion) + json.NewDecoder(r.Body).Decode(v) + + testMethod(t, r, "PATCH") + if !reflect.DeepEqual(v, &input) { + t.Errorf("Request body = %+v, want %+v", v, input) + } + + fmt.Fprint(w, `{"number":3}`) + }) + + comment, _, err := client.Teams.EditDiscussionBySlug(context.Background(), "o", "s", 3, input) + if err != nil { + t.Errorf("Teams.EditDiscussionBySlug returned error: %v", err) + } + + want := &TeamDiscussion{Number: Int(3)} + if !reflect.DeepEqual(comment, want) { + t.Errorf("Teams.EditDiscussionBySlug returned %+v, want %+v", comment, want) + } +} + +func TestTeamsService_DeleteDiscussionByID(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/organizations/1/team/2/discussions/3", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "DELETE") + }) + + _, err := client.Teams.DeleteDiscussionByID(context.Background(), 1, 2, 3) + if err != nil { + t.Errorf("Teams.DeleteDiscussionByID returned error: %v", err) } } -func TestTeamsService_DeleteDiscussion(t *testing.T) { +func TestTeamsService_DeleteDiscussionBySlug(t *testing.T) { client, mux, _, teardown := setup() defer teardown() - mux.HandleFunc("/teams/2/discussions/3", func(w http.ResponseWriter, r *http.Request) { + mux.HandleFunc("/orgs/o/teams/s/discussions/3", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "DELETE") }) - _, err := client.Teams.DeleteDiscussion(context.Background(), 2, 3) + _, err := client.Teams.DeleteDiscussionBySlug(context.Background(), "o", "s", 3) if err != nil { - t.Errorf("Teams.DeleteDiscussion returned error: %v", err) + t.Errorf("Teams.DeleteDiscussionBySlug returned error: %v", err) } } From 81bbfbd0d3c400f8e1d3ed34c0a7d5093cb381fc Mon Sep 17 00:00:00 2001 From: Glenn Lewis <6598971+gmlewis@users.noreply.github.com> Date: Fri, 28 Feb 2020 09:36:00 -0500 Subject: [PATCH 0140/1468] Update workflows/tests.yml (#1444) --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 928ca47aa7e..bf3f173cdff 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -7,7 +7,7 @@ jobs: test: strategy: matrix: - go-version: [1.x, 1.12.x] + go-version: [1.x, 1.13.x] platform: [ubuntu-latest, windows-latest] runs-on: ${{ matrix.platform }} From e4b511744f5bbb020d00e172a284468137d4e5fc Mon Sep 17 00:00:00 2001 From: Glenn Lewis <6598971+gmlewis@users.noreply.github.com> Date: Fri, 28 Feb 2020 09:37:37 -0500 Subject: [PATCH 0141/1468] Add pointers to structs in slices (#1443) --- example/commitpr/main.go | 6 ++-- github/activity.go | 14 ++++----- github/activity_test.go | 16 +++++------ github/event_types.go | 14 ++++----- github/git_commits.go | 2 +- github/git_commits_test.go | 8 +++--- github/git_trees.go | 6 ++-- github/git_trees_test.go | 14 ++++----- github/issues.go | 4 +-- github/issues_test.go | 2 +- github/migrations_source_import.go | 2 +- github/pulls_test.go | 4 +-- github/repos.go | 2 +- github/repos_commits.go | 24 ++++++++-------- github/repos_commits_test.go | 12 ++++---- github/repos_hooks.go | 24 ++++++++-------- github/repos_releases.go | 24 ++++++++-------- github/repos_releases_test.go | 4 +-- github/repos_stats.go | 6 ++-- github/repos_stats_test.go | 2 +- github/repos_statuses.go | 8 +++--- github/repos_statuses_test.go | 2 +- github/search.go | 46 +++++++++++++++--------------- github/search_test.go | 21 +++++++------- github/users.go | 2 +- github/users_gpg_keys.go | 24 ++++++++-------- 26 files changed, 146 insertions(+), 147 deletions(-) diff --git a/example/commitpr/main.go b/example/commitpr/main.go index 188424dc0eb..e2ba12a4f55 100644 --- a/example/commitpr/main.go +++ b/example/commitpr/main.go @@ -87,7 +87,7 @@ func getRef() (ref *github.Reference, err error) { // of the ref you got in getRef. func getTree(ref *github.Reference) (tree *github.Tree, err error) { // Create a tree with what to commit. - entries := []github.TreeEntry{} + entries := []*github.TreeEntry{} // Load each file into the tree. for _, fileArg := range strings.Split(*sourceFiles, ",") { @@ -95,7 +95,7 @@ func getTree(ref *github.Reference) (tree *github.Tree, err error) { if err != nil { return nil, err } - entries = append(entries, github.TreeEntry{Path: github.String(file), Type: github.String("blob"), Content: github.String(string(content)), Mode: github.String("100644")}) + entries = append(entries, &github.TreeEntry{Path: github.String(file), Type: github.String("blob"), Content: github.String(string(content)), Mode: github.String("100644")}) } tree, _, err = client.Git.CreateTree(ctx, *sourceOwner, *sourceRepo, *ref.Object.SHA, entries) @@ -135,7 +135,7 @@ func pushCommit(ref *github.Reference, tree *github.Tree) (err error) { // Create the commit using the tree. date := time.Now() author := &github.CommitAuthor{Date: &date, Name: authorName, Email: authorEmail} - commit := &github.Commit{Author: author, Message: commitMessage, Tree: tree, Parents: []github.Commit{*parent.Commit}} + commit := &github.Commit{Author: author, Message: commitMessage, Tree: tree, Parents: []*github.Commit{parent.Commit}} newCommit, _, err := client.Git.CreateCommit(ctx, *sourceOwner, *sourceRepo, commit) if err != nil { return err diff --git a/github/activity.go b/github/activity.go index d6c992c7f50..f6336fcc99a 100644 --- a/github/activity.go +++ b/github/activity.go @@ -29,13 +29,13 @@ type Feeds struct { CurrentUserOrganizationURL *string `json:"current_user_organization_url,omitempty"` CurrentUserOrganizationURLs []string `json:"current_user_organization_urls,omitempty"` Links *struct { - Timeline *FeedLink `json:"timeline,omitempty"` - User *FeedLink `json:"user,omitempty"` - CurrentUserPublic *FeedLink `json:"current_user_public,omitempty"` - CurrentUser *FeedLink `json:"current_user,omitempty"` - CurrentUserActor *FeedLink `json:"current_user_actor,omitempty"` - CurrentUserOrganization *FeedLink `json:"current_user_organization,omitempty"` - CurrentUserOrganizations []FeedLink `json:"current_user_organizations,omitempty"` + Timeline *FeedLink `json:"timeline,omitempty"` + User *FeedLink `json:"user,omitempty"` + CurrentUserPublic *FeedLink `json:"current_user_public,omitempty"` + CurrentUser *FeedLink `json:"current_user,omitempty"` + CurrentUserActor *FeedLink `json:"current_user_actor,omitempty"` + CurrentUserOrganization *FeedLink `json:"current_user_organization,omitempty"` + CurrentUserOrganizations []*FeedLink `json:"current_user_organizations,omitempty"` } `json:"_links,omitempty"` } diff --git a/github/activity_test.go b/github/activity_test.go index b577118aad3..c533333c83e 100644 --- a/github/activity_test.go +++ b/github/activity_test.go @@ -116,13 +116,13 @@ var wantFeeds = &Feeds{ "https://github.com/organizations/github/defunkt.private.atom?token=abc123", }, Links: &struct { - Timeline *FeedLink `json:"timeline,omitempty"` - User *FeedLink `json:"user,omitempty"` - CurrentUserPublic *FeedLink `json:"current_user_public,omitempty"` - CurrentUser *FeedLink `json:"current_user,omitempty"` - CurrentUserActor *FeedLink `json:"current_user_actor,omitempty"` - CurrentUserOrganization *FeedLink `json:"current_user_organization,omitempty"` - CurrentUserOrganizations []FeedLink `json:"current_user_organizations,omitempty"` + Timeline *FeedLink `json:"timeline,omitempty"` + User *FeedLink `json:"user,omitempty"` + CurrentUserPublic *FeedLink `json:"current_user_public,omitempty"` + CurrentUser *FeedLink `json:"current_user,omitempty"` + CurrentUserActor *FeedLink `json:"current_user_actor,omitempty"` + CurrentUserOrganization *FeedLink `json:"current_user_organization,omitempty"` + CurrentUserOrganizations []*FeedLink `json:"current_user_organizations,omitempty"` }{ Timeline: &FeedLink{ HRef: String("https://github.com/timeline"), @@ -148,7 +148,7 @@ var wantFeeds = &Feeds{ HRef: String(""), Type: String(""), }, - CurrentUserOrganizations: []FeedLink{ + CurrentUserOrganizations: []*FeedLink{ { HRef: String("https://github.com/organizations/github/defunkt.private.atom?token=abc123"), Type: String("application/atom+xml"), diff --git a/github/event_types.go b/github/event_types.go index 4f537c8db90..bf145de095e 100644 --- a/github/event_types.go +++ b/github/event_types.go @@ -649,13 +649,13 @@ type PullRequestReviewCommentEvent struct { // // GitHub API docs: https://developer.github.com/v3/activity/events/types/#pushevent type PushEvent struct { - PushID *int64 `json:"push_id,omitempty"` - Head *string `json:"head,omitempty"` - Ref *string `json:"ref,omitempty"` - Size *int `json:"size,omitempty"` - Commits []PushEventCommit `json:"commits,omitempty"` - Before *string `json:"before,omitempty"` - DistinctSize *int `json:"distinct_size,omitempty"` + PushID *int64 `json:"push_id,omitempty"` + Head *string `json:"head,omitempty"` + Ref *string `json:"ref,omitempty"` + Size *int `json:"size,omitempty"` + Commits []*PushEventCommit `json:"commits,omitempty"` + Before *string `json:"before,omitempty"` + DistinctSize *int `json:"distinct_size,omitempty"` // The following fields are only populated by Webhook events. After *string `json:"after,omitempty"` diff --git a/github/git_commits.go b/github/git_commits.go index 741961980a1..e1dba1cf5d1 100644 --- a/github/git_commits.go +++ b/github/git_commits.go @@ -31,7 +31,7 @@ type Commit struct { Committer *CommitAuthor `json:"committer,omitempty"` Message *string `json:"message,omitempty"` Tree *Tree `json:"tree,omitempty"` - Parents []Commit `json:"parents,omitempty"` + Parents []*Commit `json:"parents,omitempty"` Stats *CommitStats `json:"stats,omitempty"` HTMLURL *string `json:"html_url,omitempty"` URL *string `json:"url,omitempty"` diff --git a/github/git_commits_test.go b/github/git_commits_test.go index 6e858baf65a..9a7e1988e31 100644 --- a/github/git_commits_test.go +++ b/github/git_commits_test.go @@ -38,7 +38,7 @@ func TestCommit_Marshal(t *testing.T) { Message: String("m"), Tree: &Tree{ SHA: String("s"), - Entries: []TreeEntry{{ + Entries: []*TreeEntry{{ SHA: String("s"), Path: String("p"), Mode: String("m"), @@ -153,7 +153,7 @@ func TestGitService_CreateCommit(t *testing.T) { input := &Commit{ Message: String("Commit Message."), Tree: &Tree{SHA: String("t")}, - Parents: []Commit{{SHA: String("p")}}, + Parents: []*Commit{{SHA: String("p")}}, } mux.HandleFunc("/repos/o/r/git/commits", func(w http.ResponseWriter, r *http.Request) { @@ -193,7 +193,7 @@ func TestGitService_CreateSignedCommit(t *testing.T) { input := &Commit{ Message: String("Commit Message."), Tree: &Tree{SHA: String("t")}, - Parents: []Commit{{SHA: String("p")}}, + Parents: []*Commit{{SHA: String("p")}}, Verification: &SignatureVerification{ Signature: String(signature), }, @@ -259,7 +259,7 @@ func TestGitService_CreateSignedCommitWithKey(t *testing.T) { input := &Commit{ Message: String("Commit Message."), Tree: &Tree{SHA: String("t")}, - Parents: []Commit{{SHA: String("p")}}, + Parents: []*Commit{{SHA: String("p")}}, SigningKey: keyring[0], Author: &author, } diff --git a/github/git_trees.go b/github/git_trees.go index 7714946cf96..7430876ad94 100644 --- a/github/git_trees.go +++ b/github/git_trees.go @@ -13,8 +13,8 @@ import ( // Tree represents a GitHub tree. type Tree struct { - SHA *string `json:"sha,omitempty"` - Entries []TreeEntry `json:"tree,omitempty"` + SHA *string `json:"sha,omitempty"` + Entries []*TreeEntry `json:"tree,omitempty"` // Truncated is true if the number of items in the tree // exceeded GitHub's maximum limit and the Entries were truncated @@ -125,7 +125,7 @@ type createTree struct { // that tree with the new path contents and write a new tree out. // // GitHub API docs: https://developer.github.com/v3/git/trees/#create-a-tree -func (s *GitService) CreateTree(ctx context.Context, owner string, repo string, baseTree string, entries []TreeEntry) (*Tree, *Response, error) { +func (s *GitService) CreateTree(ctx context.Context, owner string, repo string, baseTree string, entries []*TreeEntry) (*Tree, *Response, error) { u := fmt.Sprintf("repos/%v/%v/git/trees", owner, repo) newEntries := make([]interface{}, 0, len(entries)) diff --git a/github/git_trees_test.go b/github/git_trees_test.go index 3e76527403c..97be57b34d8 100644 --- a/github/git_trees_test.go +++ b/github/git_trees_test.go @@ -35,7 +35,7 @@ func TestGitService_GetTree(t *testing.T) { want := Tree{ SHA: String("s"), - Entries: []TreeEntry{ + Entries: []*TreeEntry{ { Type: String("blob"), }, @@ -59,7 +59,7 @@ func TestGitService_CreateTree(t *testing.T) { client, mux, _, teardown := setup() defer teardown() - input := []TreeEntry{ + input := []*TreeEntry{ { Path: String("file.rb"), Mode: String("100644"), @@ -102,7 +102,7 @@ func TestGitService_CreateTree(t *testing.T) { want := Tree{ String("cd8274d15fa3ae2ab983129fb037999f264ba9a7"), - []TreeEntry{ + []*TreeEntry{ { Path: String("file.rb"), Mode: String("100644"), @@ -123,7 +123,7 @@ func TestGitService_CreateTree_Content(t *testing.T) { client, mux, _, teardown := setup() defer teardown() - input := []TreeEntry{ + input := []*TreeEntry{ { Path: String("content.md"), Mode: String("100644"), @@ -167,7 +167,7 @@ func TestGitService_CreateTree_Content(t *testing.T) { want := Tree{ String("5c6780ad2c68743383b740fd1dab6f6a33202b11"), - []TreeEntry{ + []*TreeEntry{ { Path: String("content.md"), Mode: String("100644"), @@ -189,7 +189,7 @@ func TestGitService_CreateTree_Delete(t *testing.T) { client, mux, _, teardown := setup() defer teardown() - input := []TreeEntry{ + input := []*TreeEntry{ { Path: String("content.md"), Mode: String("100644"), @@ -232,7 +232,7 @@ func TestGitService_CreateTree_Delete(t *testing.T) { want := Tree{ String("5c6780ad2c68743383b740fd1dab6f6a33202b11"), - []TreeEntry{ + []*TreeEntry{ { Path: String("content.md"), Mode: String("100644"), diff --git a/github/issues.go b/github/issues.go index 63a5fde75c8..7199407068d 100644 --- a/github/issues.go +++ b/github/issues.go @@ -33,7 +33,7 @@ type Issue struct { Title *string `json:"title,omitempty"` Body *string `json:"body,omitempty"` User *User `json:"user,omitempty"` - Labels []Label `json:"labels,omitempty"` + Labels []*Label `json:"labels,omitempty"` Assignee *User `json:"assignee,omitempty"` Comments *int `json:"comments,omitempty"` ClosedAt *time.Time `json:"closed_at,omitempty"` @@ -55,7 +55,7 @@ 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"` + 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". diff --git a/github/issues_test.go b/github/issues_test.go index e26d7f5d75b..0a11935d2ad 100644 --- a/github/issues_test.go +++ b/github/issues_test.go @@ -169,7 +169,7 @@ func TestIssuesService_Get(t *testing.T) { want := &Issue{ Number: Int(1), - Labels: []Label{{ + Labels: []*Label{{ URL: String("u"), Name: String("n"), Color: String("c"), diff --git a/github/migrations_source_import.go b/github/migrations_source_import.go index 080a5503f6b..cbdf1ea8a13 100644 --- a/github/migrations_source_import.go +++ b/github/migrations_source_import.go @@ -106,7 +106,7 @@ type Import struct { // When the importer finds several projects or repositories at the // provided URLs, this will identify the available choices. Call // UpdateImport with the selected Import value. - ProjectChoices []Import `json:"project_choices,omitempty"` + ProjectChoices []*Import `json:"project_choices,omitempty"` } func (i Import) String() string { diff --git a/github/pulls_test.go b/github/pulls_test.go index 4adabdbd53b..d05e7a9b42c 100644 --- a/github/pulls_test.go +++ b/github/pulls_test.go @@ -467,7 +467,7 @@ func TestPullRequestsService_ListCommits(t *testing.T) { want := []*RepositoryCommit{ { SHA: String("3"), - Parents: []Commit{ + Parents: []*Commit{ { SHA: String("2"), }, @@ -475,7 +475,7 @@ func TestPullRequestsService_ListCommits(t *testing.T) { }, { SHA: String("2"), - Parents: []Commit{ + Parents: []*Commit{ { SHA: String("1"), }, diff --git a/github/repos.go b/github/repos.go index 5aa56006ee0..bce3c942743 100644 --- a/github/repos.go +++ b/github/repos.go @@ -120,7 +120,7 @@ type Repository 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"` + TextMatches []*TextMatch `json:"text_matches,omitempty"` } func (r Repository) String() string { diff --git a/github/repos_commits.go b/github/repos_commits.go index d6960124d7a..77bd748187f 100644 --- a/github/repos_commits.go +++ b/github/repos_commits.go @@ -16,20 +16,20 @@ import ( // Note that it's wrapping a Commit, so author/committer information is in two places, // but contain different details about them: in RepositoryCommit "github details", in Commit - "git details". type RepositoryCommit struct { - NodeID *string `json:"node_id,omitempty"` - SHA *string `json:"sha,omitempty"` - Commit *Commit `json:"commit,omitempty"` - Author *User `json:"author,omitempty"` - Committer *User `json:"committer,omitempty"` - Parents []Commit `json:"parents,omitempty"` - HTMLURL *string `json:"html_url,omitempty"` - URL *string `json:"url,omitempty"` - CommentsURL *string `json:"comments_url,omitempty"` + NodeID *string `json:"node_id,omitempty"` + SHA *string `json:"sha,omitempty"` + Commit *Commit `json:"commit,omitempty"` + Author *User `json:"author,omitempty"` + Committer *User `json:"committer,omitempty"` + Parents []*Commit `json:"parents,omitempty"` + HTMLURL *string `json:"html_url,omitempty"` + URL *string `json:"url,omitempty"` + CommentsURL *string `json:"comments_url,omitempty"` // Details about how many changes were made in this commit. Only filled in during GetCommit! Stats *CommitStats `json:"stats,omitempty"` // Details about which files, and how this commit touched. Only filled in during GetCommit! - Files []CommitFile `json:"files,omitempty"` + Files []*CommitFile `json:"files,omitempty"` } func (r RepositoryCommit) String() string { @@ -78,9 +78,9 @@ type CommitsComparison struct { BehindBy *int `json:"behind_by,omitempty"` TotalCommits *int `json:"total_commits,omitempty"` - Commits []RepositoryCommit `json:"commits,omitempty"` + Commits []*RepositoryCommit `json:"commits,omitempty"` - Files []CommitFile `json:"files,omitempty"` + Files []*CommitFile `json:"files,omitempty"` HTMLURL *string `json:"html_url,omitempty"` PermalinkURL *string `json:"permalink_url,omitempty"` diff --git a/github/repos_commits_test.go b/github/repos_commits_test.go index 1c4fd77462c..221ddaf7d44 100644 --- a/github/repos_commits_test.go +++ b/github/repos_commits_test.go @@ -96,7 +96,7 @@ func TestRepositoriesService_GetCommit(t *testing.T) { Committer: &User{ Login: String("l"), }, - Parents: []Commit{ + Parents: []*Commit{ { SHA: String("s"), }, @@ -106,7 +106,7 @@ func TestRepositoriesService_GetCommit(t *testing.T) { Deletions: Int(4), Total: Int(108), }, - Files: []CommitFile{ + Files: []*CommitFile{ { Filename: String("f"), Additions: Int(10), @@ -358,7 +358,7 @@ func TestRepositoriesService_CompareCommits(t *testing.T) { }, Author: &User{Login: String("l")}, Committer: &User{Login: String("l")}, - Parents: []Commit{ + Parents: []*Commit{ { SHA: String("s"), }, @@ -368,7 +368,7 @@ func TestRepositoriesService_CompareCommits(t *testing.T) { AheadBy: Int(1), BehindBy: Int(2), TotalCommits: Int(1), - Commits: []RepositoryCommit{ + Commits: []*RepositoryCommit{ { SHA: String("s"), Commit: &Commit{ @@ -376,14 +376,14 @@ func TestRepositoriesService_CompareCommits(t *testing.T) { }, Author: &User{Login: String("l")}, Committer: &User{Login: String("l")}, - Parents: []Commit{ + Parents: []*Commit{ { SHA: String("s"), }, }, }, }, - Files: []CommitFile{ + Files: []*CommitFile{ { Filename: String("f"), }, diff --git a/github/repos_hooks.go b/github/repos_hooks.go index 86728223844..5af71dfd11f 100644 --- a/github/repos_hooks.go +++ b/github/repos_hooks.go @@ -19,18 +19,18 @@ import ( // // GitHub API docs: https://help.github.com/articles/post-receive-hooks type WebHookPayload struct { - After *string `json:"after,omitempty"` - Before *string `json:"before,omitempty"` - Commits []WebHookCommit `json:"commits,omitempty"` - Compare *string `json:"compare,omitempty"` - Created *bool `json:"created,omitempty"` - Deleted *bool `json:"deleted,omitempty"` - Forced *bool `json:"forced,omitempty"` - HeadCommit *WebHookCommit `json:"head_commit,omitempty"` - Pusher *User `json:"pusher,omitempty"` - Ref *string `json:"ref,omitempty"` - Repo *Repository `json:"repository,omitempty"` - Sender *User `json:"sender,omitempty"` + After *string `json:"after,omitempty"` + Before *string `json:"before,omitempty"` + Commits []*WebHookCommit `json:"commits,omitempty"` + Compare *string `json:"compare,omitempty"` + Created *bool `json:"created,omitempty"` + Deleted *bool `json:"deleted,omitempty"` + Forced *bool `json:"forced,omitempty"` + HeadCommit *WebHookCommit `json:"head_commit,omitempty"` + Pusher *User `json:"pusher,omitempty"` + Ref *string `json:"ref,omitempty"` + Repo *Repository `json:"repository,omitempty"` + Sender *User `json:"sender,omitempty"` } func (w WebHookPayload) String() string { diff --git a/github/repos_releases.go b/github/repos_releases.go index 645f980a535..6cd64c7ff82 100644 --- a/github/repos_releases.go +++ b/github/repos_releases.go @@ -27,18 +27,18 @@ type RepositoryRelease struct { Prerelease *bool `json:"prerelease,omitempty"` // The following fields are not used in CreateRelease or EditRelease: - ID *int64 `json:"id,omitempty"` - CreatedAt *Timestamp `json:"created_at,omitempty"` - PublishedAt *Timestamp `json:"published_at,omitempty"` - URL *string `json:"url,omitempty"` - HTMLURL *string `json:"html_url,omitempty"` - AssetsURL *string `json:"assets_url,omitempty"` - Assets []ReleaseAsset `json:"assets,omitempty"` - UploadURL *string `json:"upload_url,omitempty"` - ZipballURL *string `json:"zipball_url,omitempty"` - TarballURL *string `json:"tarball_url,omitempty"` - Author *User `json:"author,omitempty"` - NodeID *string `json:"node_id,omitempty"` + ID *int64 `json:"id,omitempty"` + CreatedAt *Timestamp `json:"created_at,omitempty"` + PublishedAt *Timestamp `json:"published_at,omitempty"` + URL *string `json:"url,omitempty"` + HTMLURL *string `json:"html_url,omitempty"` + AssetsURL *string `json:"assets_url,omitempty"` + Assets []*ReleaseAsset `json:"assets,omitempty"` + UploadURL *string `json:"upload_url,omitempty"` + ZipballURL *string `json:"zipball_url,omitempty"` + TarballURL *string `json:"tarball_url,omitempty"` + Author *User `json:"author,omitempty"` + NodeID *string `json:"node_id,omitempty"` } func (r RepositoryRelease) String() string { diff --git a/github/repos_releases_test.go b/github/repos_releases_test.go index 9ccf9ac451d..242c2811564 100644 --- a/github/repos_releases_test.go +++ b/github/repos_releases_test.go @@ -112,7 +112,7 @@ func TestRepositoriesService_CreateRelease(t *testing.T) { URL: String("http://url/"), HTMLURL: String("http://htmlurl/"), AssetsURL: String("http://assetsurl/"), - Assets: []ReleaseAsset{{ID: Int64(5)}}, + Assets: []*ReleaseAsset{{ID: Int64(5)}}, UploadURL: String("http://uploadurl/"), ZipballURL: String("http://zipballurl/"), TarballURL: String("http://tarballurl/"), @@ -156,7 +156,7 @@ func TestRepositoriesService_EditRelease(t *testing.T) { URL: String("http://url/"), HTMLURL: String("http://htmlurl/"), AssetsURL: String("http://assetsurl/"), - Assets: []ReleaseAsset{{ID: Int64(5)}}, + Assets: []*ReleaseAsset{{ID: Int64(5)}}, UploadURL: String("http://uploadurl/"), ZipballURL: String("http://zipballurl/"), TarballURL: String("http://tarballurl/"), diff --git a/github/repos_stats.go b/github/repos_stats.go index bb355aeadd3..e9c6d3fff4d 100644 --- a/github/repos_stats.go +++ b/github/repos_stats.go @@ -14,9 +14,9 @@ import ( // ContributorStats represents a contributor to a repository and their // weekly contributions to a given repo. type ContributorStats struct { - Author *Contributor `json:"author,omitempty"` - Total *int `json:"total,omitempty"` - Weeks []WeeklyStats `json:"weeks,omitempty"` + Author *Contributor `json:"author,omitempty"` + Total *int `json:"total,omitempty"` + Weeks []*WeeklyStats `json:"weeks,omitempty"` } func (c ContributorStats) String() string { diff --git a/github/repos_stats_test.go b/github/repos_stats_test.go index 4668cf18629..d838239a900 100644 --- a/github/repos_stats_test.go +++ b/github/repos_stats_test.go @@ -54,7 +54,7 @@ func TestRepositoriesService_ListContributorsStats(t *testing.T) { NodeID: String("nodeid-1"), }, Total: Int(135), - Weeks: []WeeklyStats{ + Weeks: []*WeeklyStats{ { Week: &Timestamp{time.Date(2013, time.May, 05, 00, 00, 00, 0, time.UTC).Local()}, Additions: Int(6898), diff --git a/github/repos_statuses.go b/github/repos_statuses.go index 5576d311255..cd7e424174a 100644 --- a/github/repos_statuses.go +++ b/github/repos_statuses.go @@ -91,10 +91,10 @@ type CombinedStatus struct { // failure, pending, or success. State *string `json:"state,omitempty"` - Name *string `json:"name,omitempty"` - SHA *string `json:"sha,omitempty"` - TotalCount *int `json:"total_count,omitempty"` - Statuses []RepoStatus `json:"statuses,omitempty"` + Name *string `json:"name,omitempty"` + SHA *string `json:"sha,omitempty"` + TotalCount *int `json:"total_count,omitempty"` + Statuses []*RepoStatus `json:"statuses,omitempty"` CommitURL *string `json:"commit_url,omitempty"` RepositoryURL *string `json:"repository_url,omitempty"` diff --git a/github/repos_statuses_test.go b/github/repos_statuses_test.go index b556b716695..df52ec92446 100644 --- a/github/repos_statuses_test.go +++ b/github/repos_statuses_test.go @@ -96,7 +96,7 @@ func TestRepositoriesService_GetCombinedStatus(t *testing.T) { t.Errorf("Repositories.GetCombinedStatus returned error: %v", err) } - want := &CombinedStatus{State: String("success"), Statuses: []RepoStatus{{ID: Int64(1)}}} + want := &CombinedStatus{State: String("success"), Statuses: []*RepoStatus{{ID: Int64(1)}}} if !reflect.DeepEqual(status, want) { t.Errorf("Repositories.GetCombinedStatus returned %+v, want %+v", status, want) } diff --git a/github/search.go b/github/search.go index 80587a3e76b..f08b3eb080a 100644 --- a/github/search.go +++ b/github/search.go @@ -62,9 +62,9 @@ type searchParameters struct { // RepositoriesSearchResult represents the result of a repositories search. type RepositoriesSearchResult struct { - Total *int `json:"total_count,omitempty"` - IncompleteResults *bool `json:"incomplete_results,omitempty"` - Repositories []Repository `json:"items,omitempty"` + Total *int `json:"total_count,omitempty"` + IncompleteResults *bool `json:"incomplete_results,omitempty"` + Repositories []*Repository `json:"items,omitempty"` } // Repositories searches repositories via various criteria. @@ -140,9 +140,9 @@ func (s *SearchService) Commits(ctx context.Context, query string, opts *SearchO // IssuesSearchResult represents the result of an issues search. type IssuesSearchResult struct { - Total *int `json:"total_count,omitempty"` - IncompleteResults *bool `json:"incomplete_results,omitempty"` - Issues []Issue `json:"items,omitempty"` + Total *int `json:"total_count,omitempty"` + IncompleteResults *bool `json:"incomplete_results,omitempty"` + Issues []*Issue `json:"items,omitempty"` } // Issues searches issues via various criteria. @@ -156,9 +156,9 @@ func (s *SearchService) Issues(ctx context.Context, query string, opts *SearchOp // UsersSearchResult represents the result of a users search. type UsersSearchResult struct { - Total *int `json:"total_count,omitempty"` - IncompleteResults *bool `json:"incomplete_results,omitempty"` - Users []User `json:"items,omitempty"` + Total *int `json:"total_count,omitempty"` + IncompleteResults *bool `json:"incomplete_results,omitempty"` + Users []*User `json:"items,omitempty"` } // Users searches users via various criteria. @@ -178,11 +178,11 @@ type Match struct { // TextMatch represents a text match for a SearchResult type TextMatch struct { - ObjectURL *string `json:"object_url,omitempty"` - ObjectType *string `json:"object_type,omitempty"` - Property *string `json:"property,omitempty"` - Fragment *string `json:"fragment,omitempty"` - Matches []Match `json:"matches,omitempty"` + ObjectURL *string `json:"object_url,omitempty"` + ObjectType *string `json:"object_type,omitempty"` + Property *string `json:"property,omitempty"` + Fragment *string `json:"fragment,omitempty"` + Matches []*Match `json:"matches,omitempty"` } func (tm TextMatch) String() string { @@ -191,19 +191,19 @@ func (tm TextMatch) String() string { // CodeSearchResult represents the result of a code search. type CodeSearchResult struct { - Total *int `json:"total_count,omitempty"` - IncompleteResults *bool `json:"incomplete_results,omitempty"` - CodeResults []CodeResult `json:"items,omitempty"` + Total *int `json:"total_count,omitempty"` + IncompleteResults *bool `json:"incomplete_results,omitempty"` + CodeResults []*CodeResult `json:"items,omitempty"` } // CodeResult represents a single search result. type CodeResult struct { - Name *string `json:"name,omitempty"` - Path *string `json:"path,omitempty"` - SHA *string `json:"sha,omitempty"` - HTMLURL *string `json:"html_url,omitempty"` - Repository *Repository `json:"repository,omitempty"` - TextMatches []TextMatch `json:"text_matches,omitempty"` + Name *string `json:"name,omitempty"` + Path *string `json:"path,omitempty"` + SHA *string `json:"sha,omitempty"` + HTMLURL *string `json:"html_url,omitempty"` + Repository *Repository `json:"repository,omitempty"` + TextMatches []*TextMatch `json:"text_matches,omitempty"` } func (c CodeResult) String() string { diff --git a/github/search_test.go b/github/search_test.go index 7b60756914b..e6d19734a7e 100644 --- a/github/search_test.go +++ b/github/search_test.go @@ -10,7 +10,6 @@ import ( "fmt" "net/http" "reflect" - "testing" ) @@ -40,7 +39,7 @@ func TestSearchService_Repositories(t *testing.T) { want := &RepositoriesSearchResult{ Total: Int(4), IncompleteResults: Bool(false), - Repositories: []Repository{{ID: Int64(1)}, {ID: Int64(2)}}, + Repositories: []*Repository{{ID: Int64(1)}, {ID: Int64(2)}}, } if !reflect.DeepEqual(result, want) { t.Errorf("Search.Repositories returned %+v, want %+v", result, want) @@ -135,7 +134,7 @@ func TestSearchService_Issues(t *testing.T) { want := &IssuesSearchResult{ Total: Int(4), IncompleteResults: Bool(true), - Issues: []Issue{{Number: Int(1)}, {Number: Int(2)}}, + Issues: []*Issue{{Number: Int(1)}, {Number: Int(2)}}, } if !reflect.DeepEqual(result, want) { t.Errorf("Search.Issues returned %+v, want %+v", result, want) @@ -172,7 +171,7 @@ func TestSearchService_Issues_withQualifiersNoOpts(t *testing.T) { want := &IssuesSearchResult{ Total: Int(4), IncompleteResults: Bool(true), - Issues: []Issue{{Number: Int(1)}, {Number: Int(2)}}, + Issues: []*Issue{{Number: Int(1)}, {Number: Int(2)}}, } if !reflect.DeepEqual(result, want) { t.Errorf("Search.Issues returned %+v, want %+v", result, want) @@ -210,7 +209,7 @@ func TestSearchService_Issues_withQualifiersAndOpts(t *testing.T) { want := &IssuesSearchResult{ Total: Int(4), IncompleteResults: Bool(true), - Issues: []Issue{{Number: Int(1)}, {Number: Int(2)}}, + Issues: []*Issue{{Number: Int(1)}, {Number: Int(2)}}, } if !reflect.DeepEqual(result, want) { t.Errorf("Search.Issues returned %+v, want %+v", result, want) @@ -243,7 +242,7 @@ func TestSearchService_Users(t *testing.T) { want := &UsersSearchResult{ Total: Int(4), IncompleteResults: Bool(false), - Users: []User{{ID: Int64(1)}, {ID: Int64(2)}}, + Users: []*User{{ID: Int64(1)}, {ID: Int64(2)}}, } if !reflect.DeepEqual(result, want) { t.Errorf("Search.Users returned %+v, want %+v", result, want) @@ -276,7 +275,7 @@ func TestSearchService_Code(t *testing.T) { want := &CodeSearchResult{ Total: Int(4), IncompleteResults: Bool(false), - CodeResults: []CodeResult{{Name: String("1")}, {Name: String("2")}}, + CodeResults: []*CodeResult{{Name: String("1")}, {Name: String("2")}}, } if !reflect.DeepEqual(result, want) { t.Errorf("Search.Code returned %+v, want %+v", result, want) @@ -325,11 +324,11 @@ func TestSearchService_CodeTextMatch(t *testing.T) { t.Errorf("Search.Code returned error: %v", err) } - wantedCodeResult := CodeResult{ + wantedCodeResult := &CodeResult{ Name: String("gopher1"), - TextMatches: []TextMatch{{ + TextMatches: []*TextMatch{{ Fragment: String("I'm afraid my friend what you have found\nIs a gopher who lives to feed"), - Matches: []Match{{Text: String("gopher"), Indices: []int{14, 21}}}, + Matches: []*Match{{Text: String("gopher"), Indices: []int{14, 21}}}, }, }, } @@ -337,7 +336,7 @@ func TestSearchService_CodeTextMatch(t *testing.T) { want := &CodeSearchResult{ Total: Int(1), IncompleteResults: Bool(false), - CodeResults: []CodeResult{wantedCodeResult}, + CodeResults: []*CodeResult{wantedCodeResult}, } if !reflect.DeepEqual(result, want) { t.Errorf("Search.Code returned %+v, want %+v", result, want) diff --git a/github/users.go b/github/users.go index f7c77c61d87..8b6ce5d87b9 100644 --- a/github/users.go +++ b/github/users.go @@ -63,7 +63,7 @@ type User 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"` + TextMatches []*TextMatch `json:"text_matches,omitempty"` // Permissions identifies the permissions that a user has on a given // repository. This is only populated when calling Repositories.ListCollaborators. diff --git a/github/users_gpg_keys.go b/github/users_gpg_keys.go index 42638eb541c..1d4dab045af 100644 --- a/github/users_gpg_keys.go +++ b/github/users_gpg_keys.go @@ -15,18 +15,18 @@ import ( // // https://developer.github.com/changes/2016-04-04-git-signing-api-preview/ type GPGKey struct { - ID *int64 `json:"id,omitempty"` - PrimaryKeyID *int64 `json:"primary_key_id,omitempty"` - KeyID *string `json:"key_id,omitempty"` - PublicKey *string `json:"public_key,omitempty"` - Emails []GPGEmail `json:"emails,omitempty"` - Subkeys []GPGKey `json:"subkeys,omitempty"` - CanSign *bool `json:"can_sign,omitempty"` - CanEncryptComms *bool `json:"can_encrypt_comms,omitempty"` - CanEncryptStorage *bool `json:"can_encrypt_storage,omitempty"` - CanCertify *bool `json:"can_certify,omitempty"` - CreatedAt *time.Time `json:"created_at,omitempty"` - ExpiresAt *time.Time `json:"expires_at,omitempty"` + ID *int64 `json:"id,omitempty"` + PrimaryKeyID *int64 `json:"primary_key_id,omitempty"` + KeyID *string `json:"key_id,omitempty"` + PublicKey *string `json:"public_key,omitempty"` + Emails []*GPGEmail `json:"emails,omitempty"` + Subkeys []*GPGKey `json:"subkeys,omitempty"` + CanSign *bool `json:"can_sign,omitempty"` + CanEncryptComms *bool `json:"can_encrypt_comms,omitempty"` + CanEncryptStorage *bool `json:"can_encrypt_storage,omitempty"` + CanCertify *bool `json:"can_certify,omitempty"` + CreatedAt *time.Time `json:"created_at,omitempty"` + ExpiresAt *time.Time `json:"expires_at,omitempty"` } // String stringifies a GPGKey. From 82c570e9f2a73189bde55555c9dc845acafdb8e8 Mon Sep 17 00:00:00 2001 From: Pratik Mallya Date: Sun, 1 Mar 2020 05:05:08 -0800 Subject: [PATCH 0142/1468] Allow empty commitMessage for merging pulls (#1447) --- github/pulls.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/github/pulls.go b/github/pulls.go index bd799cede13..00692088647 100644 --- a/github/pulls.go +++ b/github/pulls.go @@ -449,7 +449,7 @@ type PullRequestOptions struct { } type pullRequestMergeRequest struct { - CommitMessage string `json:"commit_message"` + CommitMessage string `json:"commit_message,omitempty"` CommitTitle string `json:"commit_title,omitempty"` MergeMethod string `json:"merge_method,omitempty"` SHA string `json:"sha,omitempty"` From d913de9ce1e8ed5550283b448b37b721b61cc3b3 Mon Sep 17 00:00:00 2001 From: Weslei Juan Novaes Pereira Date: Sun, 1 Mar 2020 10:06:42 -0300 Subject: [PATCH 0143/1468] Add support to delete commit comment reaction (#1445) --- github/reactions.go | 31 +++++++++++++++++++++++++++++++ github/reactions_test.go | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+) diff --git a/github/reactions.go b/github/reactions.go index 43c863af61d..c2c9ced3193 100644 --- a/github/reactions.go +++ b/github/reactions.go @@ -8,6 +8,7 @@ package github import ( "context" "fmt" + "net/http" ) // ReactionsService provides access to the reactions-related functions in the @@ -109,6 +110,36 @@ func (s ReactionsService) CreateCommentReaction(ctx context.Context, owner, repo return m, resp, nil } +// DeleteCommentReaction deletes the reaction for a commit comment. +// +// GitHub API docs: https://developer.github.com/v3/reactions/#delete-a-commit-comment-reaction +func (s *ReactionsService) DeleteCommentReaction(ctx context.Context, owner, repo string, commentID, reactionID int64) (*Response, error) { + u := fmt.Sprintf("repos/%v/%v/comments/%v/reactions/%v", owner, repo, commentID, reactionID) + + return s.deleteCommentReaction(ctx, u) +} + +// DeleteCommentReactionByRepoID deletes the reaction for a commit comment by repository ID. +// +// GitHub API docs: https://developer.github.com/v3/reactions/#delete-a-commit-comment-reaction +func (s *ReactionsService) DeleteCommentReactionByRepoID(ctx context.Context, repoID, commentID, reactionID int64) (*Response, error) { + u := fmt.Sprintf("repositories/%v/comments/%v/reactions/%v", repoID, commentID, reactionID) + + return s.deleteCommentReaction(ctx, u) +} + +func (s ReactionsService) deleteCommentReaction(ctx context.Context, url string) (*Response, error) { + req, err := s.client.NewRequest(http.MethodDelete, url, nil) + if err != nil { + return nil, err + } + + // TODO: remove custom Accept headers when APIs fully launch. + req.Header.Set("Accept", mediaTypeReactionsPreview) + + return s.client.Do(ctx, req, nil) +} + // ListIssueReactions lists the reactions for an issue. // // GitHub API docs: https://developer.github.com/v3/reactions/#list-reactions-for-an-issue diff --git a/github/reactions_test.go b/github/reactions_test.go index c32274dec53..90b9eaafc28 100644 --- a/github/reactions_test.go +++ b/github/reactions_test.go @@ -340,3 +340,35 @@ func TestReactionsService_DeleteReaction(t *testing.T) { t.Errorf("DeleteReaction returned error: %v", err) } } + +func TestReactionsService_DeleteCommitCommentReaction(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/repos/o/r/comments/1/reactions/2", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "DELETE") + testHeader(t, r, "Accept", mediaTypeReactionsPreview) + + w.WriteHeader(http.StatusNoContent) + }) + + if _, err := client.Reactions.DeleteCommentReaction(context.Background(), "o", "r", 1, 2); err != nil { + t.Errorf("DeleteCommentReaction returned error: %v", err) + } +} + +func TestReactionsService_DeleteCommitCommentReactionByRepoID(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/repositories/1/comments/2/reactions/3", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "DELETE") + testHeader(t, r, "Accept", mediaTypeReactionsPreview) + + w.WriteHeader(http.StatusNoContent) + }) + + if _, err := client.Reactions.DeleteCommentReactionByRepoID(context.Background(), 1, 2, 3); err != nil { + t.Errorf("DeleteCommentReactionByRepoID returned error: %v", err) + } +} From 5f66efb9dc289856ded80c805b9febda19e72a32 Mon Sep 17 00:00:00 2001 From: Will Norris Date: Sun, 1 Mar 2020 22:56:34 +0000 Subject: [PATCH 0144/1468] scrape: support textarea, radio, and checkbox improve form parsing to support textarea elements, as well as proper handling of radio and checkbox inputs (only include the value if the "checked" attribute is set). also allow nil setValue func for fetchAndSubmitForm. While I don't know of a case (yet) where we want to do this, there's no point in panicking in this case. --- scrape/forms.go | 31 ++++++++++++++++++++++++++----- scrape/forms_test.go | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 5 deletions(-) diff --git a/scrape/forms.go b/scrape/forms.go index ee559395eb6..6e01171e155 100644 --- a/scrape/forms.go +++ b/scrape/forms.go @@ -13,6 +13,7 @@ import ( "fmt" "net/http" "net/url" + "strings" "github.com/PuerkitoBio/goquery" "golang.org/x/net/html" @@ -29,8 +30,8 @@ type htmlForm struct { } // parseForms parses and returns all form elements beneath node. Form values -// include all nested input elements within the form (textarea is not currently -// supported). +// include all input and textarea elements within the form. The values of radio +// and checkbox inputs are included only if they are checked. // // In the future, we might want to allow a custom selector to be passed in to // further restrict what forms will be returned. @@ -47,10 +48,28 @@ func parseForms(node *html.Node) (forms []htmlForm) { s.Find("input").Each(func(_ int, s *goquery.Selection) { name, _ := s.Attr("name") + if name == "" { + return + } + + typ, _ := s.Attr("type") + typ = strings.ToLower(typ) + _, checked := s.Attr("checked") + if (typ == "radio" || typ == "checkbox") && !checked { + return + } + value, _ := s.Attr("value") - if name != "" { - form.Values.Add(name, value) + form.Values.Add(name, value) + }) + s.Find("textarea").Each(func(_ int, s *goquery.Selection) { + name, _ := s.Attr("name") + if name == "" { + return } + + value := s.Text() + form.Values.Add(name, value) }) forms = append(forms, form) }) @@ -87,7 +106,9 @@ func fetchAndSubmitForm(client *http.Client, urlStr string, setValues func(url.V actionURL = resp.Request.URL.ResolveReference(actionURL) // allow caller to fill out the form - setValues(form.Values) + if setValues != nil { + setValues(form.Values) + } resp, err = client.PostForm(actionURL.String(), form.Values) if err != nil { diff --git a/scrape/forms_test.go b/scrape/forms_test.go index f45010cf9bc..2c7b9fef520 100644 --- a/scrape/forms_test.go +++ b/scrape/forms_test.go @@ -35,6 +35,38 @@ func Test_ParseForms(t *testing.T) { {Action: "a2", Method: "m2", Values: url.Values{"n2": {"v2"}}}, }, }, + { + "form with radio buttons (none checked)", + `
+ + + +
`, + []htmlForm{{Values: url.Values{}}}, + }, + { + "form with radio buttons", + `
+ + + +
`, + []htmlForm{{Values: url.Values{"n1": {"v3"}}}}, + }, + { + "form with checkboxes", + `
+ + + +
`, + []htmlForm{{Values: url.Values{"n1": {"v1"}, "n3": {"v3"}}}}, + }, + { + "single form with textarea", + `
`, + []htmlForm{{Values: url.Values{"n1": {"v1"}}}}, + }, } for _, tt := range tests { From bf4e9281481bcbc811e5f8001c18cbe11613bffd Mon Sep 17 00:00:00 2001 From: Aynur Zulkarnaev <50375356+ayzu@users.noreply.github.com> Date: Tue, 3 Mar 2020 01:52:19 +0100 Subject: [PATCH 0145/1468] Implement support for actions workflow runs (#1449) --- github/actions_workflow_jobs.go | 6 +- github/actions_workflow_runs.go | 181 +++++++++++++++ github/actions_workflow_runs_test.go | 202 ++++++++++++++++ github/event_types.go | 22 +- github/github-accessors.go | 330 +++++++++++++++++++++------ github/github-stringify_test.go | 40 ++-- github/strings_test.go | 2 +- 7 files changed, 675 insertions(+), 108 deletions(-) create mode 100644 github/actions_workflow_runs.go create mode 100644 github/actions_workflow_runs_test.go diff --git a/github/actions_workflow_jobs.go b/github/actions_workflow_jobs.go index d9adad7de4d..e3593b6a8a0 100644 --- a/github/actions_workflow_jobs.go +++ b/github/actions_workflow_jobs.go @@ -96,7 +96,7 @@ func (s *ActionsService) GetWorkflowJobByID(ctx context.Context, owner, repo str func (s *ActionsService) GetWorkflowJobLogs(ctx context.Context, owner, repo string, jobID int64, followRedirects bool) (*url.URL, *Response, error) { u := fmt.Sprintf("repos/%v/%v/actions/jobs/%v/logs", owner, repo, jobID) - resp, err := s.getWorkflowJobLogsFromURL(ctx, u, followRedirects) + resp, err := s.getWorkflowLogsFromURL(ctx, u, followRedirects) if err != nil { return nil, nil, err } @@ -108,7 +108,7 @@ func (s *ActionsService) GetWorkflowJobLogs(ctx context.Context, owner, repo str return parsedURL, newResponse(resp), err } -func (s *ActionsService) getWorkflowJobLogsFromURL(ctx context.Context, u string, followRedirects bool) (*http.Response, error) { +func (s *ActionsService) getWorkflowLogsFromURL(ctx context.Context, u string, followRedirects bool) (*http.Response, error) { req, err := s.client.NewRequest("GET", u, nil) if err != nil { return nil, err @@ -130,7 +130,7 @@ func (s *ActionsService) getWorkflowJobLogsFromURL(ctx context.Context, u string // If redirect response is returned, follow it if followRedirects && resp.StatusCode == http.StatusMovedPermanently { u = resp.Header.Get("Location") - resp, err = s.getWorkflowJobLogsFromURL(ctx, u, false) + resp, err = s.getWorkflowLogsFromURL(ctx, u, false) } return resp, err diff --git a/github/actions_workflow_runs.go b/github/actions_workflow_runs.go new file mode 100644 index 00000000000..b365bb1c75a --- /dev/null +++ b/github/actions_workflow_runs.go @@ -0,0 +1,181 @@ +// Copyright 2020 The go-github AUTHORS. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package github + +import ( + "context" + "fmt" + "net/http" + "net/url" +) + +// WorkflowRun represents a repository action workflow run. +type WorkflowRun struct { + ID *int64 `json:"id,omitempty"` + NodeID *string `json:"node_id,omitempty"` + HeadBranch *string `json:"head_branch,omitempty"` + HeadSHA *string `json:"head_sha,omitempty"` + RunNumber *int `json:"run_number,omitempty"` + Event *string `json:"event,omitempty"` + Status *string `json:"status,omitempty"` + Conclusion *string `json:"conclusion,omitempty"` + URL *string `json:"url,omitempty"` + HTMLURL *string `json:"html_url,omitempty"` + PullRequests []*PullRequest `json:"pull_requests,omitempty"` + CreatedAt *Timestamp `json:"created_at,omitempty"` + UpdatedAt *Timestamp `json:"updated_at,omitempty"` + JobsURL *string `json:"jobs_url,omitempty"` + LogsURL *string `json:"logs_url,omitempty"` + CheckSuiteURL *string `json:"check_suite_url,omitempty"` + ArtifactsURL *string `json:"artifacts_url,omitempty"` + CancelURL *string `json:"cancel_url,omitempty"` + RerunURL *string `json:"rerun_url,omitempty"` + HeadCommit *HeadCommit `json:"head_commit,omitempty"` + WorkflowURL *string `json:"workflow_url,omitempty"` + Repository *Repository `json:"repository,omitempty"` + HeadRepository *Repository `json:"head_repository,omitempty"` +} + +// WorkflowRuns represents a slice of repository action workflow run. +type WorkflowRuns struct { + TotalCount *int `json:"total_count,omitempty"` + WorkflowRuns []*WorkflowRun `json:"workflow_runs,omitempty"` +} + +// ListWorkflowRunsOptions specifies optional parameters to ListWorkflowRuns. +type ListWorkflowRunsOptions struct { + Actor string `url:"actor,omitempty"` + Branch string `url:"branch,omitempty"` + Event string `url:"event,omitempty"` + Status string `url:"status,omitempty"` + ListOptions +} + +func (s *ActionsService) listWorkflowRuns(ctx context.Context, endpoint string, opts *ListWorkflowRunsOptions) (*WorkflowRuns, *Response, error) { + u, err := addOptions(endpoint, opts) + if err != nil { + return nil, nil, err + } + + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + + runs := new(WorkflowRuns) + resp, err := s.client.Do(ctx, req, &runs) + if err != nil { + return nil, resp, err + } + + return runs, resp, nil +} + +// ListWorkflowRunsByID lists all workflow runs by workflow ID. +// +// GitHub API docs: https://developer.github.com/v3/actions/workflow_runs/#list-workflow-runs +func (s *ActionsService) ListWorkflowRunsByID(ctx context.Context, owner, repo string, workflowID int64, opts *ListWorkflowRunsOptions) (*WorkflowRuns, *Response, error) { + u := fmt.Sprintf("repos/%s/%s/actions/workflows/%v/runs", owner, repo, workflowID) + return s.listWorkflowRuns(ctx, u, opts) +} + +// ListWorkflowRunsByFileName lists all workflow runs by workflow file name. +// +// GitHub API docs: https://developer.github.com/v3/actions/workflow_runs/#list-workflow-runs +func (s *ActionsService) ListWorkflowRunsByFileName(ctx context.Context, owner, repo, workflowFileName string, opts *ListWorkflowRunsOptions) (*WorkflowRuns, *Response, error) { + u := fmt.Sprintf("repos/%s/%s/actions/workflows/%v/runs", owner, repo, workflowFileName) + return s.listWorkflowRuns(ctx, u, opts) +} + +// ListRepositoryWorkflowRuns lists all workflow runs for a repository. +// +// GitHub API docs: https://developer.github.com/v3/actions/workflow_runs/#list-repository-workflow-runs +func (s *ActionsService) ListRepositoryWorkflowRuns(ctx context.Context, owner, repo string, opts *ListOptions) (*WorkflowRuns, *Response, error) { + u := fmt.Sprintf("repos/%s/%s/actions/runs", owner, repo) + u, err := addOptions(u, opts) + if err != nil { + return nil, nil, err + } + + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + + runs := new(WorkflowRuns) + resp, err := s.client.Do(ctx, req, &runs) + if err != nil { + return nil, resp, err + } + + return runs, resp, nil +} + +// GetWorkflowRunByID gets a specific workflow run by ID. +// +// GitHub API docs: https://developer.github.com/v3/actions/workflow_runs/#get-a-workflow-run +func (s *ActionsService) GetWorkflowRunByID(ctx context.Context, owner, repo string, runID int64) (*WorkflowRun, *Response, error) { + u := fmt.Sprintf("repos/%v/%v/actions/runs/%v", owner, repo, runID) + + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + + run := new(WorkflowRun) + resp, err := s.client.Do(ctx, req, run) + if err != nil { + return nil, resp, err + } + + return run, resp, nil +} + +// RerunWorkflow re-runs a workflow by ID. +// +// GitHub API docs: https://developer.github.com/v3/actions/workflow_runs/#re-run-a-workflow +func (s *ActionsService) RerunWorkflowByID(ctx context.Context, owner, repo string, runID int64) (*Response, error) { + u := fmt.Sprintf("repos/%v/%v/actions/runs/%v/rerun", owner, repo, runID) + + req, err := s.client.NewRequest("POST", u, nil) + if err != nil { + return nil, err + } + + return s.client.Do(ctx, req, nil) +} + +// CancelWorkflowRunByID cancels a workflow run by ID. +// +// GitHub API docs: https://developer.github.com/v3/actions/workflow_runs/#cancel-a-workflow-run +func (s *ActionsService) CancelWorkflowRunByID(ctx context.Context, owner, repo string, runID int64) (*Response, error) { + u := fmt.Sprintf("repos/%v/%v/actions/runs/%v/cancel", owner, repo, runID) + + req, err := s.client.NewRequest("POST", u, nil) + if err != nil { + return nil, err + } + + return s.client.Do(ctx, req, nil) +} + +// GetWorkflowRunLogs gets a redirect URL to download a plain text file of logs for a workflow run. +// +// GitHub API docs: https://developer.github.com/v3/actions/workflow_runs/#list-workflow-run-logs +func (s *ActionsService) GetWorkflowRunLogs(ctx context.Context, owner, repo string, runID int64, followRedirects bool) (*url.URL, *Response, error) { + u := fmt.Sprintf("repos/%v/%v/actions/runs/%v/logs", owner, repo, runID) + + resp, err := s.getWorkflowLogsFromURL(ctx, u, followRedirects) + if err != nil { + return nil, nil, err + } + + if resp.StatusCode != http.StatusFound { + return nil, newResponse(resp), fmt.Errorf("unexpected status code: %s", resp.Status) + } + parsedURL, err := url.Parse(resp.Header.Get("Location")) + return parsedURL, newResponse(resp), err +} diff --git a/github/actions_workflow_runs_test.go b/github/actions_workflow_runs_test.go new file mode 100644 index 00000000000..b31ca18d11e --- /dev/null +++ b/github/actions_workflow_runs_test.go @@ -0,0 +1,202 @@ +// Copyright 2020 The go-github AUTHORS. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package github + +import ( + "context" + "fmt" + "net/http" + "net/url" + "reflect" + "testing" + "time" +) + +func TestActionsService_ListWorkflowRunsByID(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/repos/o/r/actions/workflows/29679449/runs", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + testFormValues(t, r, values{"per_page": "2", "page": "2"}) + fmt.Fprint(w, `{"total_count":4,"workflow_runs":[{"id":399444496,"run_number":296,"created_at":"2019-01-02T15:04:05Z","updated_at":"2020-01-02T15:04:05Z"},{"id":399444497,"run_number":296,"created_at":"2019-01-02T15:04:05Z","updated_at":"2020-01-02T15:04:05Z"}]}`) + }) + + opts := &ListWorkflowRunsOptions{ListOptions: ListOptions{Page: 2, PerPage: 2}} + runs, _, err := client.Actions.ListWorkflowRunsByID(context.Background(), "o", "r", 29679449, opts) + if err != nil { + t.Errorf("Actions.ListWorkFlowRunsByID returned error: %v", err) + } + + want := &WorkflowRuns{ + TotalCount: Int(4), + WorkflowRuns: []*WorkflowRun{ + {ID: Int64(399444496), RunNumber: Int(296), CreatedAt: &Timestamp{time.Date(2019, time.January, 02, 15, 04, 05, 0, time.UTC)}, UpdatedAt: &Timestamp{time.Date(2020, time.January, 02, 15, 04, 05, 0, time.UTC)}}, + {ID: Int64(399444497), RunNumber: Int(296), CreatedAt: &Timestamp{time.Date(2019, time.January, 02, 15, 04, 05, 0, time.UTC)}, UpdatedAt: &Timestamp{time.Date(2020, time.January, 02, 15, 04, 05, 0, time.UTC)}}, + }, + } + if !reflect.DeepEqual(runs, want) { + t.Errorf("Actions.ListWorkflowRunsByID returned %+v, want %+v", runs, want) + } +} + +func TestActionsService_ListWorkflowRunsFileName(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/repos/o/r/actions/workflows/29679449/runs", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + testFormValues(t, r, values{"per_page": "2", "page": "2"}) + fmt.Fprint(w, `{"total_count":4,"workflow_runs":[{"id":399444496,"run_number":296,"created_at":"2019-01-02T15:04:05Z","updated_at":"2020-01-02T15:04:05Z"},{"id":399444497,"run_number":296,"created_at":"2019-01-02T15:04:05Z","updated_at":"2020-01-02T15:04:05Z"}]}`) + }) + + opts := &ListWorkflowRunsOptions{ListOptions: ListOptions{Page: 2, PerPage: 2}} + runs, _, err := client.Actions.ListWorkflowRunsByFileName(context.Background(), "o", "r", "29679449", opts) + if err != nil { + t.Errorf("Actions.ListWorkFlowRunsByFileName returned error: %v", err) + } + + want := &WorkflowRuns{ + TotalCount: Int(4), + WorkflowRuns: []*WorkflowRun{ + {ID: Int64(399444496), RunNumber: Int(296), CreatedAt: &Timestamp{time.Date(2019, time.January, 02, 15, 04, 05, 0, time.UTC)}, UpdatedAt: &Timestamp{time.Date(2020, time.January, 02, 15, 04, 05, 0, time.UTC)}}, + {ID: Int64(399444497), RunNumber: Int(296), CreatedAt: &Timestamp{time.Date(2019, time.January, 02, 15, 04, 05, 0, time.UTC)}, UpdatedAt: &Timestamp{time.Date(2020, time.January, 02, 15, 04, 05, 0, time.UTC)}}, + }, + } + if !reflect.DeepEqual(runs, want) { + t.Errorf("Actions.ListWorkflowRunsByFileName returned %+v, want %+v", runs, want) + } +} + +func TestActionsService_GetWorkflowRunByID(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/repos/o/r/actions/runs/29679449", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + fmt.Fprint(w, `{"id":399444496,"run_number":296,"created_at":"2019-01-02T15:04:05Z","updated_at":"2020-01-02T15:04:05Z"}}`) + }) + + runs, _, err := client.Actions.GetWorkflowRunByID(context.Background(), "o", "r", 29679449) + if err != nil { + t.Errorf("Actions.ListWorkFlowRunsByFileName returned error: %v", err) + } + + want := &WorkflowRun{ + ID: Int64(399444496), + RunNumber: Int(296), + CreatedAt: &Timestamp{time.Date(2019, time.January, 02, 15, 04, 05, 0, time.UTC)}, + UpdatedAt: &Timestamp{time.Date(2020, time.January, 02, 15, 04, 05, 0, time.UTC)}, + } + + if !reflect.DeepEqual(runs, want) { + t.Errorf("Actions.GetWorkflowRunByID returned %+v, want %+v", runs, want) + } +} + +func TestActionsService_RerunWorkflowRunByID(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/repos/o/r/actions/runs/3434/rerun", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "POST") + w.WriteHeader(http.StatusCreated) + }) + + resp, err := client.Actions.RerunWorkflowByID(context.Background(), "o", "r", 3434) + if err != nil { + t.Errorf("Actions.RerunWorkflowByID returned error: %v", err) + } + if resp.StatusCode != http.StatusCreated { + t.Errorf("Actions.RerunWorkflowRunByID returned status: %d, want %d", resp.StatusCode, http.StatusCreated) + } +} + +func TestActionsService_CancelWorkflowRunByID(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/repos/o/r/actions/runs/3434/cancel", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "POST") + w.WriteHeader(http.StatusAccepted) + }) + + resp, err := client.Actions.CancelWorkflowRunByID(context.Background(), "o", "r", 3434) + if _, ok := err.(*AcceptedError); !ok { + t.Errorf("Actions.CancelWorkflowRunByID returned error: %v (want AcceptedError)", err) + } + if resp.StatusCode != http.StatusAccepted { + t.Errorf("Actions.CancelWorkflowRunByID returned status: %d, want %d", resp.StatusCode, http.StatusAccepted) + } +} + +func TestActionsService_GetWorkflowRunLogs(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/repos/o/r/actions/runs/399444496/logs", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + http.Redirect(w, r, "http://github.com/a", http.StatusFound) + }) + + url, resp, err := client.Actions.GetWorkflowRunLogs(context.Background(), "o", "r", 399444496, true) + if err != nil { + t.Errorf("Actions.GetWorkflowRunLogs returned error: %v", err) + } + if resp.StatusCode != http.StatusFound { + t.Errorf("Actions.GetWorkflowRunLogs returned status: %d, want %d", resp.StatusCode, http.StatusFound) + } + want := "http://github.com/a" + if url.String() != want { + t.Errorf("Actions.GetWorkflowRunLogs returned %+v, want %+v", url.String(), want) + } +} + +func TestActionsService_GetWorkflowRunLogs_StatusMovedPermanently_dontFollowRedirects(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/repos/o/r/actions/runs/399444496/logs", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + http.Redirect(w, r, "http://github.com/a", http.StatusMovedPermanently) + }) + + _, resp, _ := client.Actions.GetWorkflowRunLogs(context.Background(), "o", "r", 399444496, false) + if resp.StatusCode != http.StatusMovedPermanently { + t.Errorf("Actions.GetWorkflowJobLogs returned status: %d, want %d", resp.StatusCode, http.StatusMovedPermanently) + } +} + +func TestActionsService_GetWorkflowRunLogs_StatusMovedPermanently_followRedirects(t *testing.T) { + client, mux, serverURL, teardown := setup() + defer teardown() + + // Mock a redirect link, which leads to an archive link + mux.HandleFunc("/repos/o/r/actions/runs/399444496/logs", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + redirectURL, _ := url.Parse(serverURL + baseURLPath + "/redirect") + http.Redirect(w, r, redirectURL.String(), http.StatusMovedPermanently) + }) + + mux.HandleFunc("/redirect", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + http.Redirect(w, r, "http://github.com/a", http.StatusFound) + }) + + url, resp, err := client.Actions.GetWorkflowRunLogs(context.Background(), "o", "r", 399444496, true) + if err != nil { + t.Errorf("Actions.GetWorkflowJobLogs returned error: %v", err) + } + + if resp.StatusCode != http.StatusFound { + t.Errorf("Actions.GetWorkflowJobLogs returned status: %d, want %d", resp.StatusCode, http.StatusFound) + } + + want := "http://github.com/a" + if url.String() != want { + t.Errorf("Actions.GetWorkflowJobLogs returned %+v, want %+v", url.String(), want) + } +} diff --git a/github/event_types.go b/github/event_types.go index bf145de095e..2c18de6c13f 100644 --- a/github/event_types.go +++ b/github/event_types.go @@ -649,13 +649,13 @@ type PullRequestReviewCommentEvent struct { // // GitHub API docs: https://developer.github.com/v3/activity/events/types/#pushevent type PushEvent struct { - PushID *int64 `json:"push_id,omitempty"` - Head *string `json:"head,omitempty"` - Ref *string `json:"ref,omitempty"` - Size *int `json:"size,omitempty"` - Commits []*PushEventCommit `json:"commits,omitempty"` - Before *string `json:"before,omitempty"` - DistinctSize *int `json:"distinct_size,omitempty"` + PushID *int64 `json:"push_id,omitempty"` + Head *string `json:"head,omitempty"` + Ref *string `json:"ref,omitempty"` + Size *int `json:"size,omitempty"` + Commits []*HeadCommit `json:"commits,omitempty"` + Before *string `json:"before,omitempty"` + DistinctSize *int `json:"distinct_size,omitempty"` // The following fields are only populated by Webhook events. After *string `json:"after,omitempty"` @@ -665,7 +665,7 @@ type PushEvent struct { BaseRef *string `json:"base_ref,omitempty"` Compare *string `json:"compare,omitempty"` Repo *PushEventRepository `json:"repository,omitempty"` - HeadCommit *PushEventCommit `json:"head_commit,omitempty"` + HeadCommit *HeadCommit `json:"head_commit,omitempty"` Pusher *User `json:"pusher,omitempty"` Sender *User `json:"sender,omitempty"` Installation *Installation `json:"installation,omitempty"` @@ -675,8 +675,8 @@ func (p PushEvent) String() string { return Stringify(p) } -// PushEventCommit represents a git commit in a GitHub PushEvent. -type PushEventCommit struct { +// HeadCommit represents a git commit in a GitHub PushEvent. +type HeadCommit struct { Message *string `json:"message,omitempty"` Author *CommitAuthor `json:"author,omitempty"` URL *string `json:"url,omitempty"` @@ -695,7 +695,7 @@ type PushEventCommit struct { Modified []string `json:"modified,omitempty"` } -func (p PushEventCommit) String() string { +func (p HeadCommit) String() string { return Stringify(p) } diff --git a/github/github-accessors.go b/github/github-accessors.go index 2ad2af181e1..f58ab0f5504 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -3628,6 +3628,78 @@ func (g *Grant) GetURL() string { return *g.URL } +// GetAuthor returns the Author field. +func (h *HeadCommit) GetAuthor() *CommitAuthor { + if h == nil { + return nil + } + return h.Author +} + +// GetCommitter returns the Committer field. +func (h *HeadCommit) GetCommitter() *CommitAuthor { + if h == nil { + return nil + } + return h.Committer +} + +// GetDistinct returns the Distinct field if it's non-nil, zero value otherwise. +func (h *HeadCommit) GetDistinct() bool { + if h == nil || h.Distinct == nil { + return false + } + return *h.Distinct +} + +// GetID returns the ID field if it's non-nil, zero value otherwise. +func (h *HeadCommit) GetID() string { + if h == nil || h.ID == nil { + return "" + } + return *h.ID +} + +// GetMessage returns the Message field if it's non-nil, zero value otherwise. +func (h *HeadCommit) GetMessage() string { + if h == nil || h.Message == nil { + return "" + } + return *h.Message +} + +// GetSHA returns the SHA field if it's non-nil, zero value otherwise. +func (h *HeadCommit) GetSHA() string { + if h == nil || h.SHA == nil { + return "" + } + return *h.SHA +} + +// GetTimestamp returns the Timestamp field if it's non-nil, zero value otherwise. +func (h *HeadCommit) GetTimestamp() Timestamp { + if h == nil || h.Timestamp == nil { + return Timestamp{} + } + return *h.Timestamp +} + +// GetTreeID returns the TreeID field if it's non-nil, zero value otherwise. +func (h *HeadCommit) GetTreeID() string { + if h == nil || h.TreeID == nil { + return "" + } + return *h.TreeID +} + +// GetURL returns the URL field if it's non-nil, zero value otherwise. +func (h *HeadCommit) GetURL() string { + if h == nil || h.URL == nil { + return "" + } + return *h.URL +} + // GetActive returns the Active field if it's non-nil, zero value otherwise. func (h *Hook) GetActive() bool { if h == nil || h.Active == nil { @@ -9197,7 +9269,7 @@ func (p *PushEvent) GetHead() string { } // GetHeadCommit returns the HeadCommit field. -func (p *PushEvent) GetHeadCommit() *PushEventCommit { +func (p *PushEvent) GetHeadCommit() *HeadCommit { if p == nil { return nil } @@ -9260,78 +9332,6 @@ func (p *PushEvent) GetSize() int { return *p.Size } -// GetAuthor returns the Author field. -func (p *PushEventCommit) GetAuthor() *CommitAuthor { - if p == nil { - return nil - } - return p.Author -} - -// GetCommitter returns the Committer field. -func (p *PushEventCommit) GetCommitter() *CommitAuthor { - if p == nil { - return nil - } - return p.Committer -} - -// GetDistinct returns the Distinct field if it's non-nil, zero value otherwise. -func (p *PushEventCommit) GetDistinct() bool { - if p == nil || p.Distinct == nil { - return false - } - return *p.Distinct -} - -// GetID returns the ID field if it's non-nil, zero value otherwise. -func (p *PushEventCommit) GetID() string { - if p == nil || p.ID == nil { - return "" - } - return *p.ID -} - -// GetMessage returns the Message field if it's non-nil, zero value otherwise. -func (p *PushEventCommit) GetMessage() string { - if p == nil || p.Message == nil { - return "" - } - return *p.Message -} - -// GetSHA returns the SHA field if it's non-nil, zero value otherwise. -func (p *PushEventCommit) GetSHA() string { - if p == nil || p.SHA == nil { - return "" - } - return *p.SHA -} - -// GetTimestamp returns the Timestamp field if it's non-nil, zero value otherwise. -func (p *PushEventCommit) GetTimestamp() Timestamp { - if p == nil || p.Timestamp == nil { - return Timestamp{} - } - return *p.Timestamp -} - -// GetTreeID returns the TreeID field if it's non-nil, zero value otherwise. -func (p *PushEventCommit) GetTreeID() string { - if p == nil || p.TreeID == nil { - return "" - } - return *p.TreeID -} - -// GetURL returns the URL field if it's non-nil, zero value otherwise. -func (p *PushEventCommit) GetURL() string { - if p == nil || p.URL == nil { - return "" - } - return *p.URL -} - // GetEmail returns the Email field if it's non-nil, zero value otherwise. func (p *PushEventRepoOwner) GetEmail() string { if p == nil || p.Email == nil { @@ -14164,6 +14164,190 @@ func (w *WorkflowJob) GetURL() string { return *w.URL } +// GetArtifactsURL returns the ArtifactsURL field if it's non-nil, zero value otherwise. +func (w *WorkflowRun) GetArtifactsURL() string { + if w == nil || w.ArtifactsURL == nil { + return "" + } + return *w.ArtifactsURL +} + +// GetCancelURL returns the CancelURL field if it's non-nil, zero value otherwise. +func (w *WorkflowRun) GetCancelURL() string { + if w == nil || w.CancelURL == nil { + return "" + } + return *w.CancelURL +} + +// GetCheckSuiteURL returns the CheckSuiteURL field if it's non-nil, zero value otherwise. +func (w *WorkflowRun) GetCheckSuiteURL() string { + if w == nil || w.CheckSuiteURL == nil { + return "" + } + return *w.CheckSuiteURL +} + +// GetConclusion returns the Conclusion field if it's non-nil, zero value otherwise. +func (w *WorkflowRun) GetConclusion() string { + if w == nil || w.Conclusion == nil { + return "" + } + return *w.Conclusion +} + +// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise. +func (w *WorkflowRun) GetCreatedAt() Timestamp { + if w == nil || w.CreatedAt == nil { + return Timestamp{} + } + return *w.CreatedAt +} + +// GetEvent returns the Event field if it's non-nil, zero value otherwise. +func (w *WorkflowRun) GetEvent() string { + if w == nil || w.Event == nil { + return "" + } + return *w.Event +} + +// GetHeadBranch returns the HeadBranch field if it's non-nil, zero value otherwise. +func (w *WorkflowRun) GetHeadBranch() string { + if w == nil || w.HeadBranch == nil { + return "" + } + return *w.HeadBranch +} + +// GetHeadCommit returns the HeadCommit field. +func (w *WorkflowRun) GetHeadCommit() *HeadCommit { + if w == nil { + return nil + } + return w.HeadCommit +} + +// GetHeadRepository returns the HeadRepository field. +func (w *WorkflowRun) GetHeadRepository() *Repository { + if w == nil { + return nil + } + return w.HeadRepository +} + +// GetHeadSHA returns the HeadSHA field if it's non-nil, zero value otherwise. +func (w *WorkflowRun) GetHeadSHA() string { + if w == nil || w.HeadSHA == nil { + return "" + } + return *w.HeadSHA +} + +// GetHTMLURL returns the HTMLURL field if it's non-nil, zero value otherwise. +func (w *WorkflowRun) GetHTMLURL() string { + if w == nil || w.HTMLURL == nil { + return "" + } + return *w.HTMLURL +} + +// GetID returns the ID field if it's non-nil, zero value otherwise. +func (w *WorkflowRun) GetID() int64 { + if w == nil || w.ID == nil { + return 0 + } + return *w.ID +} + +// GetJobsURL returns the JobsURL field if it's non-nil, zero value otherwise. +func (w *WorkflowRun) GetJobsURL() string { + if w == nil || w.JobsURL == nil { + return "" + } + return *w.JobsURL +} + +// GetLogsURL returns the LogsURL field if it's non-nil, zero value otherwise. +func (w *WorkflowRun) GetLogsURL() string { + if w == nil || w.LogsURL == nil { + return "" + } + return *w.LogsURL +} + +// GetNodeID returns the NodeID field if it's non-nil, zero value otherwise. +func (w *WorkflowRun) GetNodeID() string { + if w == nil || w.NodeID == nil { + return "" + } + return *w.NodeID +} + +// GetRepository returns the Repository field. +func (w *WorkflowRun) GetRepository() *Repository { + if w == nil { + return nil + } + return w.Repository +} + +// GetRerunURL returns the RerunURL field if it's non-nil, zero value otherwise. +func (w *WorkflowRun) GetRerunURL() string { + if w == nil || w.RerunURL == nil { + return "" + } + return *w.RerunURL +} + +// GetRunNumber returns the RunNumber field if it's non-nil, zero value otherwise. +func (w *WorkflowRun) GetRunNumber() int { + if w == nil || w.RunNumber == nil { + return 0 + } + return *w.RunNumber +} + +// GetStatus returns the Status field if it's non-nil, zero value otherwise. +func (w *WorkflowRun) GetStatus() string { + if w == nil || w.Status == nil { + return "" + } + return *w.Status +} + +// GetUpdatedAt returns the UpdatedAt field if it's non-nil, zero value otherwise. +func (w *WorkflowRun) GetUpdatedAt() Timestamp { + if w == nil || w.UpdatedAt == nil { + return Timestamp{} + } + return *w.UpdatedAt +} + +// GetURL returns the URL field if it's non-nil, zero value otherwise. +func (w *WorkflowRun) GetURL() string { + if w == nil || w.URL == nil { + return "" + } + return *w.URL +} + +// GetWorkflowURL returns the WorkflowURL field if it's non-nil, zero value otherwise. +func (w *WorkflowRun) GetWorkflowURL() string { + if w == nil || w.WorkflowURL == nil { + return "" + } + return *w.WorkflowURL +} + +// GetTotalCount returns the TotalCount field if it's non-nil, zero value otherwise. +func (w *WorkflowRuns) GetTotalCount() int { + if w == nil || w.TotalCount == nil { + return 0 + } + return *w.TotalCount +} + // GetTotalCount returns the TotalCount field if it's non-nil, zero value otherwise. func (w *Workflows) GetTotalCount() int { if w == nil || w.TotalCount == nil { diff --git a/github/github-stringify_test.go b/github/github-stringify_test.go index a8050964e61..375f3b6abaf 100644 --- a/github/github-stringify_test.go +++ b/github/github-stringify_test.go @@ -484,6 +484,24 @@ func TestGrant_String(t *testing.T) { } } +func TestHeadCommit_String(t *testing.T) { + v := HeadCommit{ + Message: String(""), + Author: &CommitAuthor{}, + URL: String(""), + Distinct: Bool(false), + SHA: String(""), + ID: String(""), + TreeID: String(""), + Timestamp: &Timestamp{}, + Committer: &CommitAuthor{}, + } + want := `github.HeadCommit{Message:"", Author:github.CommitAuthor{}, URL:"", Distinct:false, SHA:"", ID:"", TreeID:"", Timestamp:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, Committer:github.CommitAuthor{}}` + if got := v.String(); got != want { + t.Errorf("HeadCommit.String = %v, want %v", got, want) + } +} + func TestHook_String(t *testing.T) { v := Hook{ URL: String(""), @@ -1079,35 +1097,17 @@ func TestPushEvent_String(t *testing.T) { BaseRef: String(""), Compare: String(""), Repo: &PushEventRepository{}, - HeadCommit: &PushEventCommit{}, + HeadCommit: &HeadCommit{}, Pusher: &User{}, Sender: &User{}, Installation: &Installation{}, } - want := `github.PushEvent{PushID:0, Head:"", Ref:"", Size:0, Before:"", DistinctSize:0, After:"", Created:false, Deleted:false, Forced:false, BaseRef:"", Compare:"", Repo:github.PushEventRepository{}, HeadCommit:github.PushEventCommit{}, Pusher:github.User{}, Sender:github.User{}, Installation:github.Installation{}}` + want := `github.PushEvent{PushID:0, Head:"", Ref:"", Size:0, Before:"", DistinctSize:0, After:"", Created:false, Deleted:false, Forced:false, BaseRef:"", Compare:"", Repo:github.PushEventRepository{}, HeadCommit:github.HeadCommit{}, Pusher:github.User{}, Sender:github.User{}, Installation:github.Installation{}}` if got := v.String(); got != want { t.Errorf("PushEvent.String = %v, want %v", got, want) } } -func TestPushEventCommit_String(t *testing.T) { - v := PushEventCommit{ - Message: String(""), - Author: &CommitAuthor{}, - URL: String(""), - Distinct: Bool(false), - SHA: String(""), - ID: String(""), - TreeID: String(""), - Timestamp: &Timestamp{}, - Committer: &CommitAuthor{}, - } - want := `github.PushEventCommit{Message:"", Author:github.CommitAuthor{}, URL:"", Distinct:false, SHA:"", ID:"", TreeID:"", Timestamp:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, Committer:github.CommitAuthor{}}` - if got := v.String(); got != want { - t.Errorf("PushEventCommit.String = %v, want %v", got, want) - } -} - func TestRate_String(t *testing.T) { v := Rate{ Limit: 0, diff --git a/github/strings_test.go b/github/strings_test.go index e16d4a5475b..f86feb75f8e 100644 --- a/github/strings_test.go +++ b/github/strings_test.go @@ -113,7 +113,7 @@ func TestString(t *testing.T) { {DraftReviewComment{Position: Int(1)}, `github.DraftReviewComment{Position:1}`}, {PullRequestReviewRequest{Body: String("r")}, `github.PullRequestReviewRequest{Body:"r"}`}, {PullRequestReviewDismissalRequest{Message: String("r")}, `github.PullRequestReviewDismissalRequest{Message:"r"}`}, - {PushEventCommit{SHA: String("s")}, `github.PushEventCommit{SHA:"s"}`}, + {HeadCommit{SHA: String("s")}, `github.HeadCommit{SHA:"s"}`}, {PushEvent{PushID: Int64(1)}, `github.PushEvent{PushID:1}`}, {Reference{Ref: String("r")}, `github.Reference{Ref:"r"}`}, {ReleaseAsset{ID: Int64(1)}, `github.ReleaseAsset{ID:1}`}, From 5a0c02dff48b10470db5615d1a46a7784cb3cb22 Mon Sep 17 00:00:00 2001 From: Ryan Mast Date: Mon, 2 Mar 2020 16:54:58 -0800 Subject: [PATCH 0146/1468] Implement support for actions runners (#1446) Fixes #1399. --- github/actions_runners.go | 155 +++++++++++++++++++++++++++++++++ github/actions_runners_test.go | 147 +++++++++++++++++++++++++++++++ github/github-accessors.go | 96 ++++++++++++++++++++ 3 files changed, 398 insertions(+) create mode 100644 github/actions_runners.go create mode 100644 github/actions_runners_test.go diff --git a/github/actions_runners.go b/github/actions_runners.go new file mode 100644 index 00000000000..bab3963136d --- /dev/null +++ b/github/actions_runners.go @@ -0,0 +1,155 @@ +// Copyright 2020 The go-github AUTHORS. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package github + +import ( + "context" + "fmt" +) + +// RunnerApplicationDownload represents a binary for the self-hosted runner application that can be downloaded. +type RunnerApplicationDownload struct { + OS *string `json:"os,omitempty"` + Architecture *string `json:"architecture,omitempty"` + DownloadURL *string `json:"download_url,omitempty"` + Filename *string `json:"filename,omitempty"` +} + +// ListRunnerApplicationDownloads lists self-hosted runner application binaries that can be downloaded and run. +// +// GitHub API docs: https://developer.github.com/v3/actions/self_hosted_runners/#list-downloads-for-the-self-hosted-runner-application +func (s *ActionsService) ListRunnerApplicationDownloads(ctx context.Context, owner, repo string) ([]*RunnerApplicationDownload, *Response, error) { + u := fmt.Sprintf("repos/%v/%v/actions/runners/downloads", owner, repo) + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + + var rads []*RunnerApplicationDownload + resp, err := s.client.Do(ctx, req, &rads) + if err != nil { + return nil, resp, err + } + + return rads, resp, nil +} + +// RegistrationToken represents a token that can be used to add a self-hosted runner to a repository. +type RegistrationToken struct { + Token *string `json:"token,omitempty"` + ExpiresAt *Timestamp `json:"expires_at,omitempty"` +} + +// CreateRegistrationToken creates a token that can be used to add a self-hosted runner. +// +// GitHub API docs: https://developer.github.com/v3/actions/self_hosted_runners/#create-a-registration-token +func (s *ActionsService) CreateRegistrationToken(ctx context.Context, owner, repo string) (*RegistrationToken, *Response, error) { + u := fmt.Sprintf("repos/%v/%v/actions/runners/registration-token", owner, repo) + + req, err := s.client.NewRequest("POST", u, nil) + if err != nil { + return nil, nil, err + } + + registrationToken := new(RegistrationToken) + resp, err := s.client.Do(ctx, req, registrationToken) + if err != nil { + return nil, resp, err + } + + return registrationToken, resp, nil +} + +// Runner represents a self-hosted runner registered with a repository. +type Runner struct { + ID *int64 `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + OS *string `json:"os,omitempty"` + Status *string `json:"status,omitempty"` +} + +// ListRunners lists all the self-hosted runners for a repository. +// +// GitHub API docs: https://developer.github.com/v3/actions/self_hosted_runners/#list-self-hosted-runners-for-a-repository +func (s *ActionsService) ListRunners(ctx context.Context, owner, repo string, opts *ListOptions) ([]*Runner, *Response, error) { + u := fmt.Sprintf("repos/%v/%v/actions/runners", owner, repo) + u, err := addOptions(u, opts) + if err != nil { + return nil, nil, err + } + + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + + var runners []*Runner + resp, err := s.client.Do(ctx, req, &runners) + if err != nil { + return nil, resp, err + } + + return runners, resp, nil +} + +// GetRunner gets a specific self-hosted runner for a repository using its runner ID. +// +// GitHub API docs: https://developer.github.com/v3/actions/self_hosted_runners/#get-a-self-hosted-runner +func (s *ActionsService) GetRunner(ctx context.Context, owner, repo string, runnerID int64) (*Runner, *Response, error) { + u := fmt.Sprintf("repos/%v/%v/actions/runners/%v", owner, repo, runnerID) + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + + runner := new(Runner) + resp, err := s.client.Do(ctx, req, runner) + if err != nil { + return nil, resp, err + } + + return runner, resp, nil +} + +// RemoveToken represents a token that can be used to remove a self-hosted runner from a repository. +type RemoveToken struct { + Token *string `json:"token,omitempty"` + ExpiresAt *Timestamp `json:"expires_at,omitempty"` +} + +// CreateRemoveToken creates a token that can be used to remove a self-hosted runner from a repository. +// +// GitHub API docs: https://developer.github.com/v3/actions/self_hosted_runners/#create-a-remove-token +func (s *ActionsService) CreateRemoveToken(ctx context.Context, owner, repo string) (*RemoveToken, *Response, error) { + u := fmt.Sprintf("repos/%v/%v/actions/runners/remove-token", owner, repo) + + req, err := s.client.NewRequest("POST", u, nil) + if err != nil { + return nil, nil, err + } + + removeToken := new(RemoveToken) + resp, err := s.client.Do(ctx, req, removeToken) + if err != nil { + return nil, resp, err + } + + return removeToken, resp, nil +} + +// RemoveRunner forces the removal of a self-hosted runner in a repository using the runner id. +// +// GitHub API docs: https://developer.github.com/v3/actions/self_hosted_runners/#remove-a-self-hosted-runner +func (s *ActionsService) RemoveRunner(ctx context.Context, owner, repo string, runnerID int64) (*Response, error) { + u := fmt.Sprintf("repos/%v/%v/actions/runners/%v", owner, repo, runnerID) + + req, err := s.client.NewRequest("DELETE", u, nil) + if err != nil { + return nil, err + } + + return s.client.Do(ctx, req, nil) +} diff --git a/github/actions_runners_test.go b/github/actions_runners_test.go new file mode 100644 index 00000000000..6739b28addd --- /dev/null +++ b/github/actions_runners_test.go @@ -0,0 +1,147 @@ +// Copyright 2020 The go-github AUTHORS. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package github + +import ( + "context" + "fmt" + "net/http" + "reflect" + "testing" + "time" +) + +func TestActionsService_ListRunnerApplicationDownloads(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/repos/o/r/actions/runners/downloads", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + fmt.Fprint(w, `[{"os":"osx","architecture":"x64","download_url":"https://github.com/actions/runner/releases/download/v2.164.0/actions-runner-osx-x64-2.164.0.tar.gz","filename":"actions-runner-osx-x64-2.164.0.tar.gz"},{"os":"linux","architecture":"x64","download_url":"https://github.com/actions/runner/releases/download/v2.164.0/actions-runner-linux-x64-2.164.0.tar.gz","filename":"actions-runner-linux-x64-2.164.0.tar.gz"},{"os": "linux","architecture":"arm","download_url":"https://github.com/actions/runner/releases/download/v2.164.0/actions-runner-linux-arm-2.164.0.tar.gz","filename":"actions-runner-linux-arm-2.164.0.tar.gz"},{"os":"win","architecture":"x64","download_url":"https://github.com/actions/runner/releases/download/v2.164.0/actions-runner-win-x64-2.164.0.zip","filename":"actions-runner-win-x64-2.164.0.zip"},{"os":"linux","architecture":"arm64","download_url":"https://github.com/actions/runner/releases/download/v2.164.0/actions-runner-linux-arm64-2.164.0.tar.gz","filename":"actions-runner-linux-arm64-2.164.0.tar.gz"}]`) + }) + + downloads, _, err := client.Actions.ListRunnerApplicationDownloads(context.Background(), "o", "r") + if err != nil { + t.Errorf("Actions.ListRunnerApplicationDownloads returned error: %v", err) + } + + want := []*RunnerApplicationDownload{ + {OS: String("osx"), Architecture: String("x64"), DownloadURL: String("https://github.com/actions/runner/releases/download/v2.164.0/actions-runner-osx-x64-2.164.0.tar.gz"), Filename: String("actions-runner-osx-x64-2.164.0.tar.gz")}, + {OS: String("linux"), Architecture: String("x64"), DownloadURL: String("https://github.com/actions/runner/releases/download/v2.164.0/actions-runner-linux-x64-2.164.0.tar.gz"), Filename: String("actions-runner-linux-x64-2.164.0.tar.gz")}, + {OS: String("linux"), Architecture: String("arm"), DownloadURL: String("https://github.com/actions/runner/releases/download/v2.164.0/actions-runner-linux-arm-2.164.0.tar.gz"), Filename: String("actions-runner-linux-arm-2.164.0.tar.gz")}, + {OS: String("win"), Architecture: String("x64"), DownloadURL: String("https://github.com/actions/runner/releases/download/v2.164.0/actions-runner-win-x64-2.164.0.zip"), Filename: String("actions-runner-win-x64-2.164.0.zip")}, + {OS: String("linux"), Architecture: String("arm64"), DownloadURL: String("https://github.com/actions/runner/releases/download/v2.164.0/actions-runner-linux-arm64-2.164.0.tar.gz"), Filename: String("actions-runner-linux-arm64-2.164.0.tar.gz")}, + } + if !reflect.DeepEqual(downloads, want) { + t.Errorf("Actions.ListRunnerApplicationDownloads returned %+v, want %+v", downloads, want) + } +} + +func TestActionsService_CreateRegistrationToken(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/repos/o/r/actions/runners/registration-token", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "POST") + fmt.Fprint(w, `{"token":"LLBF3JGZDX3P5PMEXLND6TS6FCWO6","expires_at":"2020-01-22T12:13:35.123Z"}`) + }) + + token, _, err := client.Actions.CreateRegistrationToken(context.Background(), "o", "r") + if err != nil { + t.Errorf("Actions.CreateRegistrationToken returned error: %v", err) + } + + want := &RegistrationToken{Token: String("LLBF3JGZDX3P5PMEXLND6TS6FCWO6"), + ExpiresAt: &Timestamp{time.Date(2020, time.January, 22, 12, 13, 35, + 123000000, time.UTC)}} + if !reflect.DeepEqual(token, want) { + t.Errorf("Actions.CreateRegistrationToken returned %+v, want %+v", token, want) + } +} + +func TestActionsService_ListRunners(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/repos/o/r/actions/runners", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + testFormValues(t, r, values{"per_page": "2", "page": "2"}) + fmt.Fprint(w, `[{"id":23,"name":"MBP","os":"macos","status":"online"},{"id":24,"name":"iMac","os":"macos","status":"offline"}]`) + }) + + opts := &ListOptions{Page: 2, PerPage: 2} + runners, _, err := client.Actions.ListRunners(context.Background(), "o", "r", opts) + if err != nil { + t.Errorf("Actions.ListRunners returned error: %v", err) + } + + want := []*Runner{ + {ID: Int64(23), Name: String("MBP"), OS: String("macos"), Status: String("online")}, + {ID: Int64(24), Name: String("iMac"), OS: String("macos"), Status: String("offline")}, + } + if !reflect.DeepEqual(runners, want) { + t.Errorf("Actions.ListRunners returned %+v, want %+v", runners, want) + } +} + +func TestActionsService_GetRunner(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/repos/o/r/actions/runners/23", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + fmt.Fprint(w, `{"id":23,"name":"MBP","os":"macos","status":"online"}`) + }) + + runner, _, err := client.Actions.GetRunner(context.Background(), "o", "r", 23) + if err != nil { + t.Errorf("Actions.GetRunner returned error: %v", err) + } + + want := &Runner{ + ID: Int64(23), + Name: String("MBP"), + OS: String("macos"), + Status: String("online"), + } + if !reflect.DeepEqual(runner, want) { + t.Errorf("Actions.GetRunner returned %+v, want %+v", runner, want) + } +} + +func TestActionsService_CreateRemoveToken(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/repos/o/r/actions/runners/remove-token", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "POST") + fmt.Fprint(w, `{"token":"AABF3JGZDX3P5PMEXLND6TS6FCWO6","expires_at":"2020-01-29T12:13:35.123Z"}`) + }) + + token, _, err := client.Actions.CreateRemoveToken(context.Background(), "o", "r") + if err != nil { + t.Errorf("Actions.CreateRemoveToken returned error: %v", err) + } + + want := &RemoveToken{Token: String("AABF3JGZDX3P5PMEXLND6TS6FCWO6"), ExpiresAt: &Timestamp{time.Date(2020, time.January, 29, 12, 13, 35, 123000000, time.UTC)}} + if !reflect.DeepEqual(token, want) { + t.Errorf("Actions.CreateRemoveToken returned %+v, want %+v", token, want) + } +} + +func TestActionsService_RemoveRunner(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/repos/o/r/actions/runners/21", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "DELETE") + }) + + _, err := client.Actions.RemoveRunner(context.Background(), "o", "r", 21) + if err != nil { + t.Errorf("Actions.RemoveRunner returned error: %v", err) + } +} diff --git a/github/github-accessors.go b/github/github-accessors.go index f58ab0f5504..8598de67f6e 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -9780,6 +9780,22 @@ func (r *Reference) GetURL() string { return *r.URL } +// GetExpiresAt returns the ExpiresAt field if it's non-nil, zero value otherwise. +func (r *RegistrationToken) GetExpiresAt() Timestamp { + if r == nil || r.ExpiresAt == nil { + return Timestamp{} + } + return *r.ExpiresAt +} + +// GetToken returns the Token field if it's non-nil, zero value otherwise. +func (r *RegistrationToken) GetToken() string { + if r == nil || r.Token == nil { + return "" + } + return *r.Token +} + // GetBrowserDownloadURL returns the BrowserDownloadURL field if it's non-nil, zero value otherwise. func (r *ReleaseAsset) GetBrowserDownloadURL() string { if r == nil || r.BrowserDownloadURL == nil { @@ -9924,6 +9940,22 @@ func (r *ReleaseEvent) GetSender() *User { return r.Sender } +// GetExpiresAt returns the ExpiresAt field if it's non-nil, zero value otherwise. +func (r *RemoveToken) GetExpiresAt() Timestamp { + if r == nil || r.ExpiresAt == nil { + return Timestamp{} + } + return *r.ExpiresAt +} + +// GetToken returns the Token field if it's non-nil, zero value otherwise. +func (r *RemoveToken) GetToken() string { + if r == nil || r.Token == nil { + return "" + } + return *r.Token +} + // GetFrom returns the From field if it's non-nil, zero value otherwise. func (r *Rename) GetFrom() string { if r == nil || r.From == nil { @@ -11572,6 +11604,70 @@ func (r *ReviewersRequest) GetNodeID() string { return *r.NodeID } +// GetID returns the ID field if it's non-nil, zero value otherwise. +func (r *Runner) GetID() int64 { + if r == nil || r.ID == nil { + return 0 + } + return *r.ID +} + +// GetName returns the Name field if it's non-nil, zero value otherwise. +func (r *Runner) GetName() string { + if r == nil || r.Name == nil { + return "" + } + return *r.Name +} + +// GetOS returns the OS field if it's non-nil, zero value otherwise. +func (r *Runner) GetOS() string { + if r == nil || r.OS == nil { + return "" + } + return *r.OS +} + +// GetStatus returns the Status field if it's non-nil, zero value otherwise. +func (r *Runner) GetStatus() string { + if r == nil || r.Status == nil { + return "" + } + return *r.Status +} + +// GetArchitecture returns the Architecture field if it's non-nil, zero value otherwise. +func (r *RunnerApplicationDownload) GetArchitecture() string { + if r == nil || r.Architecture == nil { + return "" + } + return *r.Architecture +} + +// GetDownloadURL returns the DownloadURL field if it's non-nil, zero value otherwise. +func (r *RunnerApplicationDownload) GetDownloadURL() string { + if r == nil || r.DownloadURL == nil { + return "" + } + return *r.DownloadURL +} + +// GetFilename returns the Filename field if it's non-nil, zero value otherwise. +func (r *RunnerApplicationDownload) GetFilename() string { + if r == nil || r.Filename == nil { + return "" + } + return *r.Filename +} + +// GetOS returns the OS field if it's non-nil, zero value otherwise. +func (r *RunnerApplicationDownload) GetOS() string { + if r == nil || r.OS == nil { + return "" + } + return *r.OS +} + // GetName returns the Name field if it's non-nil, zero value otherwise. func (s *ServiceHook) GetName() string { if s == nil || s.Name == nil { From 89b491a18424e050bbc26c4a57e9289d11a97172 Mon Sep 17 00:00:00 2001 From: Patrick Marabeas Date: Tue, 10 Mar 2020 01:52:32 +1100 Subject: [PATCH 0147/1468] Implement support for update pages API (#1453) Fixes: #1361. --- github/github-accessors.go | 16 +++++++++++ github/repos_pages.go | 29 +++++++++++++++++++ github/repos_pages_test.go | 58 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 103 insertions(+) diff --git a/github/github-accessors.go b/github/github-accessors.go index 8598de67f6e..69547c4f09a 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -7220,6 +7220,22 @@ func (p *PageStats) GetTotalPages() int { return *p.TotalPages } +// GetCNAME returns the CNAME field if it's non-nil, zero value otherwise. +func (p *PagesUpdate) GetCNAME() string { + if p == nil || p.CNAME == nil { + return "" + } + return *p.CNAME +} + +// GetSource returns the Source field if it's non-nil, zero value otherwise. +func (p *PagesUpdate) GetSource() string { + if p == nil || p.Source == nil { + return "" + } + return *p.Source +} + // GetHook returns the Hook field. func (p *PingEvent) GetHook() *Hook { if p == nil { diff --git a/github/repos_pages.go b/github/repos_pages.go index ff8d2d55b9c..58826527d9d 100644 --- a/github/repos_pages.go +++ b/github/repos_pages.go @@ -75,6 +75,35 @@ func (s *RepositoriesService) EnablePages(ctx context.Context, owner, repo strin return enable, resp, nil } +// PagesUpdate sets up parameters needed to update a GitHub Pages site. +type PagesUpdate struct { + // CNAME represents a custom domain for the repository. + // Leaving CNAME empty will remove the custom domain. + CNAME *string `json:"cname"` + // Source must include the branch name, and may optionally specify the subdirectory "/docs". + // Possible values are: "gh-pages", "master", and "master /docs". + Source *string `json:"source,omitempty"` +} + +// UpdatePages updates GitHub Pages for the named repo. +// +// GitHub API docs: https://developer.github.com/v3/repos/pages/#update-information-about-a-pages-site +func (s *RepositoriesService) UpdatePages(ctx context.Context, owner, repo string, opts *PagesUpdate) (*Response, error) { + u := fmt.Sprintf("repos/%v/%v/pages", owner, repo) + + req, err := s.client.NewRequest("PUT", u, opts) + if err != nil { + return nil, err + } + + resp, err := s.client.Do(ctx, req, nil) + if err != nil { + return resp, err + } + + return resp, nil +} + // DisablePages disables GitHub Pages for the named repo. // // GitHub API docs: https://developer.github.com/v3/repos/pages/#disable-a-pages-site diff --git a/github/repos_pages_test.go b/github/repos_pages_test.go index 8fe38eb3e24..b2aa272939a 100644 --- a/github/repos_pages_test.go +++ b/github/repos_pages_test.go @@ -6,9 +6,11 @@ package github import ( + "bytes" "context" "encoding/json" "fmt" + "io/ioutil" "net/http" "reflect" "testing" @@ -52,6 +54,62 @@ func TestRepositoriesService_EnablePages(t *testing.T) { } } +func TestRepositoriesService_UpdatePages(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + input := &PagesUpdate{ + CNAME: String("www.my-domain.com"), + Source: String("gh-pages"), + } + + mux.HandleFunc("/repos/o/r/pages", func(w http.ResponseWriter, r *http.Request) { + v := new(PagesUpdate) + json.NewDecoder(r.Body).Decode(v) + + testMethod(t, r, "PUT") + want := &PagesUpdate{CNAME: String("www.my-domain.com"), Source: String("gh-pages")} + if !reflect.DeepEqual(v, want) { + t.Errorf("Request body = %+v, want %+v", v, want) + } + + fmt.Fprint(w, `{"cname":"www.my-domain.com","source":"gh-pages"}`) + }) + + _, err := client.Repositories.UpdatePages(context.Background(), "o", "r", input) + if err != nil { + t.Errorf("Repositories.UpdatePages returned error: %v", err) + } +} + +func TestRepositoriesService_UpdatePages_NullCNAME(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + input := &PagesUpdate{ + Source: String("gh-pages"), + } + + mux.HandleFunc("/repos/o/r/pages", func(w http.ResponseWriter, r *http.Request) { + got, err := ioutil.ReadAll(r.Body) + if err != nil { + t.Fatalf("unable to read body: %v", err) + } + + want := []byte(`{"cname":null,"source":"gh-pages"}` + "\n") + if !bytes.Equal(got, want) { + t.Errorf("Request body = %+v, want %+v", got, want) + } + + fmt.Fprint(w, `{"cname":null,"source":"gh-pages"}`) + }) + + _, err := client.Repositories.UpdatePages(context.Background(), "o", "r", input) + if err != nil { + t.Errorf("Repositories.UpdatePages returned error: %v", err) + } +} + func TestRepositoriesService_DisablePages(t *testing.T) { client, mux, _, teardown := setup() defer teardown() From 6e0f6ebdef7d6db18d0eb92bb6f7aa9c0c7d4101 Mon Sep 17 00:00:00 2001 From: Ryan Mast Date: Tue, 10 Mar 2020 16:28:33 -0700 Subject: [PATCH 0148/1468] Add support for filter parameter to the list workflow jobs endpoint (#1455) Fixes #1454. --- github/actions_workflow_jobs.go | 14 ++++++++++++- github/actions_workflow_jobs_test.go | 30 +++++++++++++++++++++++++++- 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/github/actions_workflow_jobs.go b/github/actions_workflow_jobs.go index e3593b6a8a0..8cb7c6aa876 100644 --- a/github/actions_workflow_jobs.go +++ b/github/actions_workflow_jobs.go @@ -46,10 +46,22 @@ type Jobs struct { Jobs []*WorkflowJob `json:"jobs,omitempty"` } +// ListWorkflowJobsOptions specifies optional parameters to ListWorkflowJobs. +type ListWorkflowJobsOptions struct { + // Filter specifies how jobs should be filtered by their completed_at timestamp. + // Possible values are: + // latest - Returns jobs from the most recent execution of the workflow run + // all - Returns all jobs for a workflow run, including from old executions of the workflow run + // + // Default value is "latest". + Filter string `url:"filter,omitempty"` + ListOptions +} + // ListWorkflowJobs lists all jobs for a workflow run. // // GitHub API docs: https://developer.github.com/v3/actions/workflow_jobs/#list-jobs-for-a-workflow-run -func (s *ActionsService) ListWorkflowJobs(ctx context.Context, owner, repo string, runID int64, opts *ListOptions) (*Jobs, *Response, error) { +func (s *ActionsService) ListWorkflowJobs(ctx context.Context, owner, repo string, runID int64, opts *ListWorkflowJobsOptions) (*Jobs, *Response, error) { u := fmt.Sprintf("repos/%s/%s/actions/runs/%v/jobs", owner, repo, runID) u, err := addOptions(u, opts) if err != nil { diff --git a/github/actions_workflow_jobs_test.go b/github/actions_workflow_jobs_test.go index 36cf7a82ea4..3cf17ae7a96 100644 --- a/github/actions_workflow_jobs_test.go +++ b/github/actions_workflow_jobs_test.go @@ -25,7 +25,35 @@ func TestActionsService_ListWorkflowJobs(t *testing.T) { fmt.Fprint(w, `{"total_count":4,"jobs":[{"id":399444496,"run_id":29679449,"started_at":"2019-01-02T15:04:05Z","completed_at":"2020-01-02T15:04:05Z"},{"id":399444497,"run_id":29679449,"started_at":"2019-01-02T15:04:05Z","completed_at":"2020-01-02T15:04:05Z"}]}`) }) - opts := &ListOptions{Page: 2, PerPage: 2} + opts := &ListWorkflowJobsOptions{ListOptions: ListOptions{Page: 2, PerPage: 2}} + jobs, _, err := client.Actions.ListWorkflowJobs(context.Background(), "o", "r", 29679449, opts) + if err != nil { + t.Errorf("Actions.ListWorkflowJobs returned error: %v", err) + } + + want := &Jobs{ + TotalCount: Int(4), + Jobs: []*WorkflowJob{ + {ID: Int64(399444496), RunID: Int64(29679449), StartedAt: &Timestamp{time.Date(2019, time.January, 02, 15, 04, 05, 0, time.UTC)}, CompletedAt: &Timestamp{time.Date(2020, time.January, 02, 15, 04, 05, 0, time.UTC)}}, + {ID: Int64(399444497), RunID: Int64(29679449), StartedAt: &Timestamp{time.Date(2019, time.January, 02, 15, 04, 05, 0, time.UTC)}, CompletedAt: &Timestamp{time.Date(2020, time.January, 02, 15, 04, 05, 0, time.UTC)}}, + }, + } + if !reflect.DeepEqual(jobs, want) { + t.Errorf("Actions.ListWorkflowJobs returned %+v, want %+v", jobs, want) + } +} + +func TestActionsService_ListWorkflowJobs_Filter(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/repos/o/r/actions/runs/29679449/jobs", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + testFormValues(t, r, values{"filter": "all", "per_page": "2", "page": "2"}) + fmt.Fprint(w, `{"total_count":4,"jobs":[{"id":399444496,"run_id":29679449,"started_at":"2019-01-02T15:04:05Z","completed_at":"2020-01-02T15:04:05Z"},{"id":399444497,"run_id":29679449,"started_at":"2019-01-02T15:04:05Z","completed_at":"2020-01-02T15:04:05Z"}]}`) + }) + + opts := &ListWorkflowJobsOptions{Filter: "all", ListOptions: ListOptions{Page: 2, PerPage: 2}} jobs, _, err := client.Actions.ListWorkflowJobs(context.Background(), "o", "r", 29679449, opts) if err != nil { t.Errorf("Actions.ListWorkflowJobs returned error: %v", err) From dce4b6b4e504a59d5213424591c4af8d8839efaa Mon Sep 17 00:00:00 2001 From: ajz01 Date: Mon, 16 Mar 2020 19:05:20 -0400 Subject: [PATCH 0149/1468] Add test for APIMeta JSON marshaling (#1457) Relates to #55. --- github/misc_test.go | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/github/misc_test.go b/github/misc_test.go index b7144f9091e..0e7569acfff 100644 --- a/github/misc_test.go +++ b/github/misc_test.go @@ -128,6 +128,26 @@ func TestGetCodeOfConduct(t *testing.T) { } } +func TestAPIMeta_marshal(t *testing.T) { + testJSONMarshal(t, &APIMeta{}, "{}") + + a := &APIMeta{ + Hooks: []string{"h"}, + Git: []string{"g"}, + VerifiablePasswordAuthentication: Bool(true), + Pages: []string{"p"}, + Importer: []string{"i"}, + } + want := `{ + "hooks":["h"], + "git":["g"], + "verifiable_password_authentication":true, + "pages":["p"],"importer":["i"] + }` + + testJSONMarshal(t, a, want) +} + func TestAPIMeta(t *testing.T) { client, mux, _, teardown := setup() defer teardown() From 419f07c399bbced679719c419ae683618018556c Mon Sep 17 00:00:00 2001 From: Clark Bynum Date: Tue, 17 Mar 2020 08:10:52 -0500 Subject: [PATCH 0150/1468] Update and remove OAuth endpoints (#1461) Fixes #1331. --- github/authorizations.go | 229 ++++---------------- github/authorizations_test.go | 269 ++---------------------- github/github.go | 3 + test/integration/authorizations_test.go | 111 +--------- 4 files changed, 65 insertions(+), 547 deletions(-) diff --git a/github/authorizations.go b/github/authorizations.go index a73c37fd079..7447e2fbf73 100644 --- a/github/authorizations.go +++ b/github/authorizations.go @@ -134,137 +134,6 @@ func (a AuthorizationUpdateRequest) String() string { return Stringify(a) } -// List the authorizations for the authenticated user. -// -// GitHub API docs: https://developer.github.com/v3/oauth_authorizations/#list-your-authorizations -func (s *AuthorizationsService) List(ctx context.Context, opts *ListOptions) ([]*Authorization, *Response, error) { - u := "authorizations" - u, err := addOptions(u, opts) - if err != nil { - return nil, nil, err - } - - req, err := s.client.NewRequest("GET", u, nil) - if err != nil { - return nil, nil, err - } - - var auths []*Authorization - resp, err := s.client.Do(ctx, req, &auths) - if err != nil { - return nil, resp, err - } - return auths, resp, nil -} - -// Get a single authorization. -// -// GitHub API docs: https://developer.github.com/v3/oauth_authorizations/#get-a-single-authorization -func (s *AuthorizationsService) Get(ctx context.Context, id int64) (*Authorization, *Response, error) { - u := fmt.Sprintf("authorizations/%d", id) - - req, err := s.client.NewRequest("GET", u, nil) - if err != nil { - return nil, nil, err - } - - a := new(Authorization) - resp, err := s.client.Do(ctx, req, a) - if err != nil { - return nil, resp, err - } - return a, resp, nil -} - -// Create a new authorization for the specified OAuth application. -// -// GitHub API docs: https://developer.github.com/v3/oauth_authorizations/#create-a-new-authorization -func (s *AuthorizationsService) Create(ctx context.Context, auth *AuthorizationRequest) (*Authorization, *Response, error) { - u := "authorizations" - - req, err := s.client.NewRequest("POST", u, auth) - if err != nil { - return nil, nil, err - } - - a := new(Authorization) - resp, err := s.client.Do(ctx, req, a) - if err != nil { - return nil, resp, err - } - return a, resp, nil -} - -// GetOrCreateForApp creates a new authorization for the specified OAuth -// application, only if an authorization for that application doesn’t already -// exist for the user. -// -// If a new token is created, the HTTP status code will be "201 Created", and -// the returned Authorization.Token field will be populated. If an existing -// token is returned, the status code will be "200 OK" and the -// Authorization.Token field will be empty. -// -// clientID is the OAuth Client ID with which to create the token. -// -// GitHub API docs: -// https://developer.github.com/v3/oauth_authorizations/#get-or-create-an-authorization-for-a-specific-app -// https://developer.github.com/v3/oauth_authorizations/#get-or-create-an-authorization-for-a-specific-app-and-fingerprint -func (s *AuthorizationsService) GetOrCreateForApp(ctx context.Context, clientID string, auth *AuthorizationRequest) (*Authorization, *Response, error) { - var u string - if auth.Fingerprint == nil || *auth.Fingerprint == "" { - u = fmt.Sprintf("authorizations/clients/%v", clientID) - } else { - u = fmt.Sprintf("authorizations/clients/%v/%v", clientID, *auth.Fingerprint) - } - - req, err := s.client.NewRequest("PUT", u, auth) - if err != nil { - return nil, nil, err - } - - a := new(Authorization) - resp, err := s.client.Do(ctx, req, a) - if err != nil { - return nil, resp, err - } - - return a, resp, nil -} - -// Edit a single authorization. -// -// GitHub API docs: https://developer.github.com/v3/oauth_authorizations/#update-an-existing-authorization -func (s *AuthorizationsService) Edit(ctx context.Context, id int64, auth *AuthorizationUpdateRequest) (*Authorization, *Response, error) { - u := fmt.Sprintf("authorizations/%d", id) - - req, err := s.client.NewRequest("PATCH", u, auth) - if err != nil { - return nil, nil, err - } - - a := new(Authorization) - resp, err := s.client.Do(ctx, req, a) - if err != nil { - return nil, resp, err - } - - return a, resp, nil -} - -// Delete a single authorization. -// -// GitHub API docs: https://developer.github.com/v3/oauth_authorizations/#delete-an-authorization -func (s *AuthorizationsService) Delete(ctx context.Context, id int64) (*Response, error) { - u := fmt.Sprintf("authorizations/%d", id) - - req, err := s.client.NewRequest("DELETE", u, nil) - if err != nil { - return nil, err - } - - return s.client.Do(ctx, req, nil) -} - // Check if an OAuth token is valid for a specific app. // // Note that this operation requires the use of BasicAuth, but where the @@ -273,14 +142,19 @@ func (s *AuthorizationsService) Delete(ctx context.Context, id int64) (*Response // // The returned Authorization.User field will be populated. // -// GitHub API docs: https://developer.github.com/v3/oauth_authorizations/#check-an-authorization -func (s *AuthorizationsService) Check(ctx context.Context, clientID string, token string) (*Authorization, *Response, error) { - u := fmt.Sprintf("applications/%v/tokens/%v", clientID, token) +// GitHub API docs: https://developer.github.com/v3/apps/oauth_applications/#check-a-token +func (s *AuthorizationsService) Check(ctx context.Context, clientID, accessToken string) (*Authorization, *Response, error) { + u := fmt.Sprintf("applications/%v/token", clientID) + + reqBody := &struct { + AccessToken string `json:"access_token"` + }{AccessToken: accessToken} - req, err := s.client.NewRequest("GET", u, nil) + req, err := s.client.NewRequest("POST", u, reqBody) if err != nil { return nil, nil, err } + req.Header.Set("Accept", mediaTypeOAuthAppPreview) a := new(Authorization) resp, err := s.client.Do(ctx, req, a) @@ -301,14 +175,19 @@ func (s *AuthorizationsService) Check(ctx context.Context, clientID string, toke // // The returned Authorization.User field will be populated. // -// GitHub API docs: https://developer.github.com/v3/oauth_authorizations/#reset-an-authorization -func (s *AuthorizationsService) Reset(ctx context.Context, clientID string, token string) (*Authorization, *Response, error) { - u := fmt.Sprintf("applications/%v/tokens/%v", clientID, token) +// GitHub API docs: https://developer.github.com/v3/apps/oauth_applications/#reset-a-token +func (s *AuthorizationsService) Reset(ctx context.Context, clientID, accessToken string) (*Authorization, *Response, error) { + u := fmt.Sprintf("applications/%v/token", clientID) - req, err := s.client.NewRequest("POST", u, nil) + reqBody := &struct { + AccessToken string `json:"access_token"` + }{AccessToken: accessToken} + + req, err := s.client.NewRequest("PATCH", u, reqBody) if err != nil { return nil, nil, err } + req.Header.Set("Accept", mediaTypeOAuthAppPreview) a := new(Authorization) resp, err := s.client.Do(ctx, req, a) @@ -325,74 +204,40 @@ func (s *AuthorizationsService) Reset(ctx context.Context, clientID string, toke // username is the OAuth application clientID, and the password is its // clientSecret. Invalid tokens will return a 404 Not Found. // -// GitHub API docs: https://developer.github.com/v3/oauth_authorizations/#revoke-an-authorization-for-an-application -func (s *AuthorizationsService) Revoke(ctx context.Context, clientID string, token string) (*Response, error) { - u := fmt.Sprintf("applications/%v/tokens/%v", clientID, token) +// GitHub API docs: https://developer.github.com/v3/apps/oauth_applications/#delete-an-app-token +func (s *AuthorizationsService) Revoke(ctx context.Context, clientID, accessToken string) (*Response, error) { + u := fmt.Sprintf("applications/%v/token", clientID) - req, err := s.client.NewRequest("DELETE", u, nil) + reqBody := &struct { + AccessToken string `json:"access_token"` + }{AccessToken: accessToken} + + req, err := s.client.NewRequest("DELETE", u, reqBody) if err != nil { return nil, err } + req.Header.Set("Accept", mediaTypeOAuthAppPreview) return s.client.Do(ctx, req, nil) } -// ListGrants lists the set of OAuth applications that have been granted -// access to a user's account. This will return one entry for each application -// that has been granted access to the account, regardless of the number of -// tokens an application has generated for the user. -// -// GitHub API docs: https://developer.github.com/v3/oauth_authorizations/#list-your-grants -func (s *AuthorizationsService) ListGrants(ctx context.Context, opts *ListOptions) ([]*Grant, *Response, error) { - u, err := addOptions("applications/grants", opts) - if err != nil { - return nil, nil, err - } - - req, err := s.client.NewRequest("GET", u, nil) - if err != nil { - return nil, nil, err - } - - grants := []*Grant{} - resp, err := s.client.Do(ctx, req, &grants) - if err != nil { - return nil, resp, err - } - - return grants, resp, nil -} - -// GetGrant gets a single OAuth application grant. -// -// GitHub API docs: https://developer.github.com/v3/oauth_authorizations/#get-a-single-grant -func (s *AuthorizationsService) GetGrant(ctx context.Context, id int64) (*Grant, *Response, error) { - u := fmt.Sprintf("applications/grants/%d", id) - req, err := s.client.NewRequest("GET", u, nil) - if err != nil { - return nil, nil, err - } - - grant := new(Grant) - resp, err := s.client.Do(ctx, req, grant) - if err != nil { - return nil, resp, err - } - - return grant, resp, nil -} - // DeleteGrant deletes an OAuth application grant. Deleting an application's // grant will also delete all OAuth tokens associated with the application for // the user. // -// GitHub API docs: https://developer.github.com/v3/oauth_authorizations/#delete-a-grant -func (s *AuthorizationsService) DeleteGrant(ctx context.Context, id int64) (*Response, error) { - u := fmt.Sprintf("applications/grants/%d", id) - req, err := s.client.NewRequest("DELETE", u, nil) +// GitHub API docs: https://developer.github.com/v3/apps/oauth_applications/#delete-an-app-authorization +func (s *AuthorizationsService) DeleteGrant(ctx context.Context, clientID, accessToken string) (*Response, error) { + u := fmt.Sprintf("applications/%v/grant", clientID) + + reqBody := &struct { + AccessToken string `json:"access_token"` + }{AccessToken: accessToken} + + req, err := s.client.NewRequest("DELETE", u, reqBody) if err != nil { return nil, err } + req.Header.Set("Accept", mediaTypeOAuthAppPreview) return s.client.Do(ctx, req, nil) } diff --git a/github/authorizations_test.go b/github/authorizations_test.go index faf25749cdc..3e9a8be46d3 100644 --- a/github/authorizations_test.go +++ b/github/authorizations_test.go @@ -7,205 +7,24 @@ package github import ( "context" - "encoding/json" "fmt" "net/http" "reflect" "testing" ) -func TestAuthorizationsService_List(t *testing.T) { - client, mux, _, teardown := setup() - defer teardown() - - mux.HandleFunc("/authorizations", func(w http.ResponseWriter, r *http.Request) { - testMethod(t, r, "GET") - testFormValues(t, r, values{"page": "1", "per_page": "2"}) - fmt.Fprint(w, `[{"id":1}]`) - }) - - opt := &ListOptions{Page: 1, PerPage: 2} - got, _, err := client.Authorizations.List(context.Background(), opt) - if err != nil { - t.Errorf("Authorizations.List returned error: %v", err) - } - - want := []*Authorization{{ID: Int64(1)}} - if !reflect.DeepEqual(got, want) { - t.Errorf("Authorizations.List returned %+v, want %+v", *got[0].ID, *want[0].ID) - } -} - -func TestAuthorizationsService_Get(t *testing.T) { - client, mux, _, teardown := setup() - defer teardown() - - mux.HandleFunc("/authorizations/1", func(w http.ResponseWriter, r *http.Request) { - testMethod(t, r, "GET") - fmt.Fprint(w, `{"id":1}`) - }) - - got, _, err := client.Authorizations.Get(context.Background(), 1) - if err != nil { - t.Errorf("Authorizations.Get returned error: %v", err) - } - - want := &Authorization{ID: Int64(1)} - if !reflect.DeepEqual(got, want) { - t.Errorf("Authorizations.Get returned auth %+v, want %+v", got, want) - } -} - -func TestAuthorizationsService_Create(t *testing.T) { - client, mux, _, teardown := setup() - defer teardown() - - input := &AuthorizationRequest{ - Note: String("test"), - } - - mux.HandleFunc("/authorizations", func(w http.ResponseWriter, r *http.Request) { - v := new(AuthorizationRequest) - json.NewDecoder(r.Body).Decode(v) - - testMethod(t, r, "POST") - if !reflect.DeepEqual(v, input) { - t.Errorf("Request body = %+v, want %+v", v, input) - } - - fmt.Fprint(w, `{"ID":1}`) - }) - - got, _, err := client.Authorizations.Create(context.Background(), input) - if err != nil { - t.Errorf("Authorizations.Create returned error: %v", err) - } - - want := &Authorization{ID: Int64(1)} - if !reflect.DeepEqual(got, want) { - t.Errorf("Authorization.Create returned %+v, want %+v", got, want) - } -} - -func TestAuthorizationsService_GetOrCreateForApp(t *testing.T) { - client, mux, _, teardown := setup() - defer teardown() - - input := &AuthorizationRequest{ - Note: String("test"), - } - - mux.HandleFunc("/authorizations/clients/id", func(w http.ResponseWriter, r *http.Request) { - v := new(AuthorizationRequest) - json.NewDecoder(r.Body).Decode(v) - - testMethod(t, r, "PUT") - if !reflect.DeepEqual(v, input) { - t.Errorf("Request body = %+v, want %+v", v, input) - } - - fmt.Fprint(w, `{"ID":1}`) - }) - - got, _, err := client.Authorizations.GetOrCreateForApp(context.Background(), "id", input) - if err != nil { - t.Errorf("Authorizations.GetOrCreateForApp returned error: %v", err) - } - - want := &Authorization{ID: Int64(1)} - if !reflect.DeepEqual(got, want) { - t.Errorf("Authorization.GetOrCreateForApp returned %+v, want %+v", got, want) - } -} - -func TestAuthorizationsService_GetOrCreateForApp_Fingerprint(t *testing.T) { - client, mux, _, teardown := setup() - defer teardown() - - input := &AuthorizationRequest{ - Note: String("test"), - Fingerprint: String("fp"), - } - - mux.HandleFunc("/authorizations/clients/id/fp", func(w http.ResponseWriter, r *http.Request) { - v := new(AuthorizationRequest) - json.NewDecoder(r.Body).Decode(v) - - testMethod(t, r, "PUT") - if !reflect.DeepEqual(v, input) { - t.Errorf("Request body = %+v, want %+v", v, input) - } - - fmt.Fprint(w, `{"ID":1}`) - }) - - got, _, err := client.Authorizations.GetOrCreateForApp(context.Background(), "id", input) - if err != nil { - t.Errorf("Authorizations.GetOrCreateForApp returned error: %v", err) - } - - want := &Authorization{ID: Int64(1)} - if !reflect.DeepEqual(got, want) { - t.Errorf("Authorization.GetOrCreateForApp returned %+v, want %+v", got, want) - } -} - -func TestAuthorizationsService_Edit(t *testing.T) { - client, mux, _, teardown := setup() - defer teardown() - - input := &AuthorizationUpdateRequest{ - Note: String("test"), - } - - mux.HandleFunc("/authorizations/1", func(w http.ResponseWriter, r *http.Request) { - v := new(AuthorizationUpdateRequest) - json.NewDecoder(r.Body).Decode(v) - - testMethod(t, r, "PATCH") - if !reflect.DeepEqual(v, input) { - t.Errorf("Request body = %+v, want %+v", v, input) - } - - fmt.Fprint(w, `{"ID":1}`) - }) - - got, _, err := client.Authorizations.Edit(context.Background(), 1, input) - if err != nil { - t.Errorf("Authorizations.Edit returned error: %v", err) - } - - want := &Authorization{ID: Int64(1)} - if !reflect.DeepEqual(got, want) { - t.Errorf("Authorization.Update returned %+v, want %+v", got, want) - } -} - -func TestAuthorizationsService_Delete(t *testing.T) { - client, mux, _, teardown := setup() - defer teardown() - - mux.HandleFunc("/authorizations/1", func(w http.ResponseWriter, r *http.Request) { - testMethod(t, r, "DELETE") - w.WriteHeader(http.StatusNoContent) - }) - - _, err := client.Authorizations.Delete(context.Background(), 1) - if err != nil { - t.Errorf("Authorizations.Delete returned error: %v", err) - } -} - func TestAuthorizationsService_Check(t *testing.T) { client, mux, _, teardown := setup() defer teardown() - mux.HandleFunc("/applications/id/tokens/t", func(w http.ResponseWriter, r *http.Request) { - testMethod(t, r, "GET") + mux.HandleFunc("/applications/id/token", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "POST") + testBody(t, r, `{"access_token":"a"}`+"\n") + testHeader(t, r, "Accept", mediaTypeOAuthAppPreview) fmt.Fprint(w, `{"id":1}`) }) - got, _, err := client.Authorizations.Check(context.Background(), "id", "t") + got, _, err := client.Authorizations.Check(context.Background(), "id", "a") if err != nil { t.Errorf("Authorizations.Check returned error: %v", err) } @@ -220,12 +39,14 @@ func TestAuthorizationsService_Reset(t *testing.T) { client, mux, _, teardown := setup() defer teardown() - mux.HandleFunc("/applications/id/tokens/t", func(w http.ResponseWriter, r *http.Request) { - testMethod(t, r, "POST") + mux.HandleFunc("/applications/id/token", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "PATCH") + testBody(t, r, `{"access_token":"a"}`+"\n") + testHeader(t, r, "Accept", mediaTypeOAuthAppPreview) fmt.Fprint(w, `{"ID":1}`) }) - got, _, err := client.Authorizations.Reset(context.Background(), "id", "t") + got, _, err := client.Authorizations.Reset(context.Background(), "id", "a") if err != nil { t.Errorf("Authorizations.Reset returned error: %v", err) } @@ -240,84 +61,30 @@ func TestAuthorizationsService_Revoke(t *testing.T) { client, mux, _, teardown := setup() defer teardown() - mux.HandleFunc("/applications/id/tokens/t", func(w http.ResponseWriter, r *http.Request) { + mux.HandleFunc("/applications/id/token", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "DELETE") + testBody(t, r, `{"access_token":"a"}`+"\n") + testHeader(t, r, "Accept", mediaTypeOAuthAppPreview) w.WriteHeader(http.StatusNoContent) }) - _, err := client.Authorizations.Revoke(context.Background(), "id", "t") + _, err := client.Authorizations.Revoke(context.Background(), "id", "a") if err != nil { t.Errorf("Authorizations.Revoke returned error: %v", err) } } -func TestListGrants(t *testing.T) { - client, mux, _, teardown := setup() - defer teardown() - - mux.HandleFunc("/applications/grants", func(w http.ResponseWriter, r *http.Request) { - testMethod(t, r, "GET") - fmt.Fprint(w, `[{"id": 1}]`) - }) - - got, _, err := client.Authorizations.ListGrants(context.Background(), nil) - if err != nil { - t.Errorf("OAuthAuthorizations.ListGrants returned error: %v", err) - } - - want := []*Grant{{ID: Int64(1)}} - if !reflect.DeepEqual(got, want) { - t.Errorf("OAuthAuthorizations.ListGrants = %+v, want %+v", got, want) - } -} - -func TestListGrants_withOptions(t *testing.T) { - client, mux, _, teardown := setup() - defer teardown() - - mux.HandleFunc("/applications/grants", func(w http.ResponseWriter, r *http.Request) { - testMethod(t, r, "GET") - testFormValues(t, r, values{ - "page": "2", - }) - fmt.Fprint(w, `[{"id": 1}]`) - }) - - _, _, err := client.Authorizations.ListGrants(context.Background(), &ListOptions{Page: 2}) - if err != nil { - t.Errorf("OAuthAuthorizations.ListGrants returned error: %v", err) - } -} - -func TestGetGrant(t *testing.T) { - client, mux, _, teardown := setup() - defer teardown() - - mux.HandleFunc("/applications/grants/1", func(w http.ResponseWriter, r *http.Request) { - testMethod(t, r, "GET") - fmt.Fprint(w, `{"id": 1}`) - }) - - got, _, err := client.Authorizations.GetGrant(context.Background(), 1) - if err != nil { - t.Errorf("OAuthAuthorizations.GetGrant returned error: %v", err) - } - - want := &Grant{ID: Int64(1)} - if !reflect.DeepEqual(got, want) { - t.Errorf("OAuthAuthorizations.GetGrant = %+v, want %+v", got, want) - } -} - func TestDeleteGrant(t *testing.T) { client, mux, _, teardown := setup() defer teardown() - mux.HandleFunc("/applications/grants/1", func(w http.ResponseWriter, r *http.Request) { + mux.HandleFunc("/applications/id/grant", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "DELETE") + testBody(t, r, `{"access_token":"a"}`+"\n") + testHeader(t, r, "Accept", mediaTypeOAuthAppPreview) }) - _, err := client.Authorizations.DeleteGrant(context.Background(), 1) + _, err := client.Authorizations.DeleteGrant(context.Background(), "id", "a") if err != nil { t.Errorf("OAuthAuthorizations.DeleteGrant returned error: %v", err) } diff --git a/github/github.go b/github/github.go index 696684b931f..644e230baec 100644 --- a/github/github.go +++ b/github/github.go @@ -135,6 +135,9 @@ const ( // https://developer.github.com/changes/2019-10-03-multi-line-comments/ mediaTypeMultiLineCommentsPreview = "application/vnd.github.comfort-fade-preview+json" + + // https://developer.github.com/changes/2019-11-05-deprecated-passwords-and-authorizations-api/ + mediaTypeOAuthAppPreview = "application/vnd.github.doctor-strange-preview+json" ) // A Client manages communication with the GitHub API. diff --git a/test/integration/authorizations_test.go b/test/integration/authorizations_test.go index 7eaeca392b8..90f09083051 100644 --- a/test/integration/authorizations_test.go +++ b/test/integration/authorizations_test.go @@ -24,124 +24,27 @@ const envKeyGitHubUsername = "GITHUB_USERNAME" const envKeyGitHubPassword = "GITHUB_PASSWORD" const envKeyClientID = "GITHUB_CLIENT_ID" const envKeyClientSecret = "GITHUB_CLIENT_SECRET" +const envKeyAccessToken = "GITHUB_ACCESS_TOKEN" const InvalidTokenValue = "iamnotacroken" -// TestAuthorizationsBasicOperations tests the basic CRUD operations of the API (mostly for -// the Personal Access Token scenario). -func TestAuthorizationsBasicOperations(t *testing.T) { - - client := getUserPassClient(t) - - auths, resp, err := client.Authorizations.List(context.Background(), nil) - failOnError(t, err) - failIfNotStatusCode(t, resp, 200) - - initialAuthCount := len(auths) - - authReq := generatePersonalAuthTokenRequest() - - createdAuth, resp, err := client.Authorizations.Create(context.Background(), authReq) - failOnError(t, err) - failIfNotStatusCode(t, resp, 201) - - if *authReq.Note != *createdAuth.Note { - t.Fatal("Returned Authorization does not match the requested Authorization.") - } - - auths, resp, err = client.Authorizations.List(context.Background(), nil) - failOnError(t, err) - failIfNotStatusCode(t, resp, 200) - - if len(auths) != initialAuthCount+1 { - t.Fatalf("The number of Authorizations should have increased. Expected [%v], was [%v]", initialAuthCount+1, len(auths)) - } - - // Test updating the authorization - authUpdate := new(github.AuthorizationUpdateRequest) - authUpdate.Note = github.String("Updated note: " + randString()) - - updatedAuth, resp, err := client.Authorizations.Edit(context.Background(), *createdAuth.ID, authUpdate) - failOnError(t, err) - failIfNotStatusCode(t, resp, 200) - - if *updatedAuth.Note != *authUpdate.Note { - t.Fatal("The returned Authorization does not match the requested updated value.") - } - - // Verify that the Get operation also reflects the update - retrievedAuth, resp, err := client.Authorizations.Get(context.Background(), *createdAuth.ID) - failOnError(t, err) - failIfNotStatusCode(t, resp, 200) - - if *retrievedAuth.Note != *updatedAuth.Note { - t.Fatal("The retrieved Authorization does not match the expected (updated) value.") - } - - // Now, let's delete... - resp, err = client.Authorizations.Delete(context.Background(), *createdAuth.ID) - failOnError(t, err) - failIfNotStatusCode(t, resp, 204) - - // Verify that we can no longer retrieve the auth - retrievedAuth, resp, err = client.Authorizations.Get(context.Background(), *createdAuth.ID) - if err == nil { - t.Fatal("Should have failed due to 404") - } - failIfNotStatusCode(t, resp, 404) - - // Verify that our count reset back to the initial value - auths, resp, err = client.Authorizations.List(context.Background(), nil) - failOnError(t, err) - failIfNotStatusCode(t, resp, 200) - - if len(auths) != initialAuthCount { - t.Fatalf("The number of Authorizations should match the initial count Expected [%v], got [%v]", initialAuthCount, len(auths)) - } - -} - // TestAuthorizationsAppOperations tests the application/token related operations, such // as creating, testing, resetting and revoking application OAuth tokens. func TestAuthorizationsAppOperations(t *testing.T) { - userAuthenticatedClient := getUserPassClient(t) - appAuthenticatedClient := getOAuthAppClient(t) // We know these vars are set because getOAuthAppClient would have // skipped the test by now clientID := os.Getenv(envKeyClientID) - clientSecret := os.Getenv(envKeyClientSecret) - - authRequest := generateAppAuthTokenRequest(clientID, clientSecret) - - createdAuth, resp, err := userAuthenticatedClient.Authorizations.GetOrCreateForApp(context.Background(), clientID, authRequest) - failOnError(t, err) - failIfNotStatusCode(t, resp, 201) - - // Quick sanity check: - if *createdAuth.Note != *authRequest.Note { - t.Fatal("The returned auth does not match expected value.") - } - - // Let's try the same request again, this time it should return the same - // auth instead of creating a new one - secondAuth, resp, err := userAuthenticatedClient.Authorizations.GetOrCreateForApp(context.Background(), clientID, authRequest) - failOnError(t, err) - failIfNotStatusCode(t, resp, 200) - - // Verify that the IDs are the same - if *createdAuth.ID != *secondAuth.ID { - t.Fatalf("The ID of the second returned auth should be the same as the first. Expected [%v], got [%v]", createdAuth.ID, secondAuth.ID) - } + accessToken := os.Getenv(envKeyAccessToken) // Verify the token - appAuth, resp, err := appAuthenticatedClient.Authorizations.Check(context.Background(), clientID, *createdAuth.Token) + appAuth, resp, err := appAuthenticatedClient.Authorizations.Check(context.Background(), clientID, accessToken) failOnError(t, err) failIfNotStatusCode(t, resp, 200) // Quick sanity check - if *appAuth.ID != *createdAuth.ID || *appAuth.Token != *createdAuth.Token { + if *appAuth.Token != accessToken { t.Fatal("The returned auth/token does not match.") } @@ -153,7 +56,7 @@ func TestAuthorizationsAppOperations(t *testing.T) { failIfNotStatusCode(t, resp, 404) // Let's reset the token - resetAuth, resp, err := appAuthenticatedClient.Authorizations.Reset(context.Background(), clientID, *createdAuth.Token) + resetAuth, resp, err := appAuthenticatedClient.Authorizations.Reset(context.Background(), clientID, accessToken) failOnError(t, err) failIfNotStatusCode(t, resp, 200) @@ -165,7 +68,7 @@ func TestAuthorizationsAppOperations(t *testing.T) { failIfNotStatusCode(t, resp, 404) // Verify that the token has changed - if resetAuth.Token == createdAuth.Token { + if *resetAuth.Token == accessToken { t.Fatal("The reset token should be different from the original.") } @@ -175,7 +78,7 @@ func TestAuthorizationsAppOperations(t *testing.T) { } // Verify that the original token is now invalid - _, resp, err = appAuthenticatedClient.Authorizations.Check(context.Background(), clientID, *createdAuth.Token) + _, resp, err = appAuthenticatedClient.Authorizations.Check(context.Background(), clientID, accessToken) if err == nil { t.Fatal("The original token should be invalid.") } From 5baa174a7d3b79056e73f152e3b773c0927df7a9 Mon Sep 17 00:00:00 2001 From: Vikky Omkar Date: Wed, 18 Mar 2020 18:44:24 +0530 Subject: [PATCH 0151/1468] Added AuthorAssociation field in issue struct (#1462) Fixes #1458. --- github/github-accessors.go | 8 +++++ github/github-stringify_test.go | 49 +++++++++++++++--------------- github/issues.go | 53 +++++++++++++++++---------------- github/issues_test.go | 5 ++-- 4 files changed, 63 insertions(+), 52 deletions(-) diff --git a/github/github-accessors.go b/github/github-accessors.go index 69547c4f09a..519123cdcf7 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -4484,6 +4484,14 @@ func (i *Issue) GetAssignee() *User { return i.Assignee } +// GetAuthorAssociation returns the AuthorAssociation field if it's non-nil, zero value otherwise. +func (i *Issue) GetAuthorAssociation() string { + if i == nil || i.AuthorAssociation == nil { + return "" + } + return *i.AuthorAssociation +} + // GetBody returns the Body field if it's non-nil, zero value otherwise. func (i *Issue) GetBody() string { if i == nil || i.Body == nil { diff --git a/github/github-stringify_test.go b/github/github-stringify_test.go index 375f3b6abaf..b85d3a62c30 100644 --- a/github/github-stringify_test.go +++ b/github/github-stringify_test.go @@ -599,30 +599,31 @@ func TestInvitation_String(t *testing.T) { func TestIssue_String(t *testing.T) { v := Issue{ - ID: Int64(0), - Number: Int(0), - State: String(""), - Locked: Bool(false), - Title: String(""), - Body: String(""), - User: &User{}, - Assignee: &User{}, - Comments: Int(0), - ClosedBy: &User{}, - URL: String(""), - HTMLURL: String(""), - CommentsURL: String(""), - EventsURL: String(""), - LabelsURL: String(""), - RepositoryURL: String(""), - Milestone: &Milestone{}, - PullRequestLinks: &PullRequestLinks{}, - Repository: &Repository{}, - Reactions: &Reactions{}, - NodeID: String(""), - ActiveLockReason: String(""), - } - want := `github.Issue{ID:0, Number:0, State:"", Locked:false, Title:"", Body:"", User:github.User{}, Assignee:github.User{}, Comments:0, ClosedBy:github.User{}, URL:"", HTMLURL:"", CommentsURL:"", EventsURL:"", LabelsURL:"", RepositoryURL:"", Milestone:github.Milestone{}, PullRequestLinks:github.PullRequestLinks{}, Repository:github.Repository{}, Reactions:github.Reactions{}, NodeID:"", ActiveLockReason:""}` + ID: Int64(0), + Number: Int(0), + State: String(""), + Locked: Bool(false), + Title: String(""), + Body: String(""), + AuthorAssociation: String(""), + User: &User{}, + Assignee: &User{}, + Comments: Int(0), + ClosedBy: &User{}, + URL: String(""), + HTMLURL: String(""), + CommentsURL: String(""), + EventsURL: String(""), + LabelsURL: String(""), + RepositoryURL: String(""), + Milestone: &Milestone{}, + PullRequestLinks: &PullRequestLinks{}, + Repository: &Repository{}, + Reactions: &Reactions{}, + NodeID: String(""), + ActiveLockReason: String(""), + } + want := `github.Issue{ID:0, Number:0, State:"", Locked:false, Title:"", Body:"", AuthorAssociation:"", User:github.User{}, Assignee:github.User{}, Comments:0, ClosedBy:github.User{}, URL:"", HTMLURL:"", CommentsURL:"", EventsURL:"", LabelsURL:"", RepositoryURL:"", Milestone:github.Milestone{}, PullRequestLinks:github.PullRequestLinks{}, Repository:github.Repository{}, Reactions:github.Reactions{}, NodeID:"", ActiveLockReason:""}` if got := v.String(); got != want { t.Errorf("Issue.String = %v, want %v", got, want) } diff --git a/github/issues.go b/github/issues.go index 7199407068d..b53a2603e8b 100644 --- a/github/issues.go +++ b/github/issues.go @@ -26,32 +26,33 @@ type IssuesService service // this is an issue, and if PullRequestLinks is not nil, this is a pull request. // The IsPullRequest helper method can be used to check that. type Issue struct { - ID *int64 `json:"id,omitempty"` - Number *int `json:"number,omitempty"` - State *string `json:"state,omitempty"` - Locked *bool `json:"locked,omitempty"` - Title *string `json:"title,omitempty"` - Body *string `json:"body,omitempty"` - User *User `json:"user,omitempty"` - Labels []*Label `json:"labels,omitempty"` - Assignee *User `json:"assignee,omitempty"` - Comments *int `json:"comments,omitempty"` - ClosedAt *time.Time `json:"closed_at,omitempty"` - CreatedAt *time.Time `json:"created_at,omitempty"` - UpdatedAt *time.Time `json:"updated_at,omitempty"` - ClosedBy *User `json:"closed_by,omitempty"` - URL *string `json:"url,omitempty"` - HTMLURL *string `json:"html_url,omitempty"` - CommentsURL *string `json:"comments_url,omitempty"` - EventsURL *string `json:"events_url,omitempty"` - LabelsURL *string `json:"labels_url,omitempty"` - RepositoryURL *string `json:"repository_url,omitempty"` - Milestone *Milestone `json:"milestone,omitempty"` - PullRequestLinks *PullRequestLinks `json:"pull_request,omitempty"` - Repository *Repository `json:"repository,omitempty"` - Reactions *Reactions `json:"reactions,omitempty"` - Assignees []*User `json:"assignees,omitempty"` - NodeID *string `json:"node_id,omitempty"` + ID *int64 `json:"id,omitempty"` + Number *int `json:"number,omitempty"` + State *string `json:"state,omitempty"` + Locked *bool `json:"locked,omitempty"` + Title *string `json:"title,omitempty"` + Body *string `json:"body,omitempty"` + AuthorAssociation *string `json:"author_association,omitempty"` + User *User `json:"user,omitempty"` + Labels []*Label `json:"labels,omitempty"` + Assignee *User `json:"assignee,omitempty"` + Comments *int `json:"comments,omitempty"` + ClosedAt *time.Time `json:"closed_at,omitempty"` + CreatedAt *time.Time `json:"created_at,omitempty"` + UpdatedAt *time.Time `json:"updated_at,omitempty"` + ClosedBy *User `json:"closed_by,omitempty"` + URL *string `json:"url,omitempty"` + HTMLURL *string `json:"html_url,omitempty"` + CommentsURL *string `json:"comments_url,omitempty"` + EventsURL *string `json:"events_url,omitempty"` + LabelsURL *string `json:"labels_url,omitempty"` + RepositoryURL *string `json:"repository_url,omitempty"` + Milestone *Milestone `json:"milestone,omitempty"` + PullRequestLinks *PullRequestLinks `json:"pull_request,omitempty"` + Repository *Repository `json:"repository,omitempty"` + Reactions *Reactions `json:"reactions,omitempty"` + Assignees []*User `json:"assignees,omitempty"` + NodeID *string `json:"node_id,omitempty"` // TextMatches is only populated from search results that request text matches // See: search.go and https://developer.github.com/v3/search/#text-match-metadata diff --git a/github/issues_test.go b/github/issues_test.go index 0a11935d2ad..6792db02cc6 100644 --- a/github/issues_test.go +++ b/github/issues_test.go @@ -159,7 +159,7 @@ func TestIssuesService_Get(t *testing.T) { mux.HandleFunc("/repos/o/r/issues/1", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", ")) - fmt.Fprint(w, `{"number":1, "labels": [{"url": "u", "name": "n", "color": "c"}]}`) + fmt.Fprint(w, `{"number":1, "author_association": "MEMBER","labels": [{"url": "u", "name": "n", "color": "c"}]}`) }) issue, _, err := client.Issues.Get(context.Background(), "o", "r", 1) @@ -168,7 +168,8 @@ func TestIssuesService_Get(t *testing.T) { } want := &Issue{ - Number: Int(1), + Number: Int(1), + AuthorAssociation: String("MEMBER"), Labels: []*Label{{ URL: String("u"), Name: String("n"), From e5d8dd691c294eb6373a3dd5f58bec1e0d2ed3b1 Mon Sep 17 00:00:00 2001 From: Weslei Juan Novaes Pereira Date: Wed, 18 Mar 2020 06:23:50 -0700 Subject: [PATCH 0152/1468] Support new "Delete Reactions" endpoints (#1451) Fixes #1442. --- github/reactions.go | 117 ++++++++++++++++++++++----- github/reactions_test.go | 168 ++++++++++++++++++++++++++++++++++++--- 2 files changed, 251 insertions(+), 34 deletions(-) diff --git a/github/reactions.go b/github/reactions.go index c2c9ced3193..1602032e221 100644 --- a/github/reactions.go +++ b/github/reactions.go @@ -116,28 +116,16 @@ func (s ReactionsService) CreateCommentReaction(ctx context.Context, owner, repo func (s *ReactionsService) DeleteCommentReaction(ctx context.Context, owner, repo string, commentID, reactionID int64) (*Response, error) { u := fmt.Sprintf("repos/%v/%v/comments/%v/reactions/%v", owner, repo, commentID, reactionID) - return s.deleteCommentReaction(ctx, u) + return s.deleteReaction(ctx, u) } -// DeleteCommentReactionByRepoID deletes the reaction for a commit comment by repository ID. +// DeleteCommentReactionByID deletes the reaction for a commit comment by repository ID. // // GitHub API docs: https://developer.github.com/v3/reactions/#delete-a-commit-comment-reaction -func (s *ReactionsService) DeleteCommentReactionByRepoID(ctx context.Context, repoID, commentID, reactionID int64) (*Response, error) { +func (s *ReactionsService) DeleteCommentReactionByID(ctx context.Context, repoID, commentID, reactionID int64) (*Response, error) { u := fmt.Sprintf("repositories/%v/comments/%v/reactions/%v", repoID, commentID, reactionID) - return s.deleteCommentReaction(ctx, u) -} - -func (s ReactionsService) deleteCommentReaction(ctx context.Context, url string) (*Response, error) { - req, err := s.client.NewRequest(http.MethodDelete, url, nil) - if err != nil { - return nil, err - } - - // TODO: remove custom Accept headers when APIs fully launch. - req.Header.Set("Accept", mediaTypeReactionsPreview) - - return s.client.Do(ctx, req, nil) + return s.deleteReaction(ctx, u) } // ListIssueReactions lists the reactions for an issue. @@ -194,6 +182,24 @@ func (s ReactionsService) CreateIssueReaction(ctx context.Context, owner, repo s return m, resp, nil } +// DeleteIssueReaction deletes the reaction to an issue. +// +// GitHub API docs: https://developer.github.com/v3/reactions/#delete-an-issue-reaction +func (s *ReactionsService) DeleteIssueReaction(ctx context.Context, owner, repo string, issueNumber int, reactionID int64) (*Response, error) { + url := fmt.Sprintf("repos/%v/%v/issues/%v/reactions/%v", owner, repo, issueNumber, reactionID) + + return s.deleteReaction(ctx, url) +} + +// DeleteIssueReactionByID deletes the reaction to an issue by repository ID. +// +// GitHub API docs: https://developer.github.com/v3/reactions/#delete-an-issue-reaction +func (s *ReactionsService) DeleteIssueReactionByID(ctx context.Context, repoID, issueNumber int, reactionID int64) (*Response, error) { + url := fmt.Sprintf("repositories/%v/issues/%v/reactions/%v", repoID, issueNumber, reactionID) + + return s.deleteReaction(ctx, url) +} + // ListIssueCommentReactions lists the reactions for an issue comment. // // GitHub API docs: https://developer.github.com/v3/reactions/#list-reactions-for-an-issue-comment @@ -248,6 +254,24 @@ func (s ReactionsService) CreateIssueCommentReaction(ctx context.Context, owner, return m, resp, nil } +// DeleteIssueCommentReaction deletes the reaction to an issue comment. +// +// GitHub API docs: https://developer.github.com/v3/reactions/#delete-an-issue-comment-reaction +func (s *ReactionsService) DeleteIssueCommentReaction(ctx context.Context, owner, repo string, commentID, reactionID int64) (*Response, error) { + url := fmt.Sprintf("repos/%v/%v/issues/comments/%v/reactions/%v", owner, repo, commentID, reactionID) + + return s.deleteReaction(ctx, url) +} + +// DeleteIssueCommentReactionByID deletes the reaction to an issue comment by repository ID. +// +// GitHub API docs: https://developer.github.com/v3/reactions/#delete-an-issue-comment-reaction +func (s *ReactionsService) DeleteIssueCommentReactionByID(ctx context.Context, repoID, commentID, reactionID int64) (*Response, error) { + url := fmt.Sprintf("repositories/%v/issues/comments/%v/reactions/%v", repoID, commentID, reactionID) + + return s.deleteReaction(ctx, url) +} + // ListPullRequestCommentReactions lists the reactions for a pull request review comment. // // GitHub API docs: https://developer.github.com/v3/reactions/#list-reactions-for-an-issue-comment @@ -302,6 +326,24 @@ func (s ReactionsService) CreatePullRequestCommentReaction(ctx context.Context, return m, resp, nil } +// DeletePullRequestCommentReaction deletes the reaction to a pull request review comment. +// +// GitHub API docs: https://developer.github.com/v3/reactions/#delete-a-pull-request-comment-reaction +func (s *ReactionsService) DeletePullRequestCommentReaction(ctx context.Context, owner, repo string, commentID, reactionID int64) (*Response, error) { + url := fmt.Sprintf("repos/%v/%v/pulls/comments/%v/reactions/%v", owner, repo, commentID, reactionID) + + return s.deleteReaction(ctx, url) +} + +// DeletePullRequestCommentReactionByID deletes the reaction to a pull request review comment by repository ID. +// +// GitHub API docs: https://developer.github.com/v3/reactions/#delete-a-pull-request-comment-reaction +func (s *ReactionsService) DeletePullRequestCommentReactionByID(ctx context.Context, repoID, commentID, reactionID int64) (*Response, error) { + url := fmt.Sprintf("repositories/%v/pulls/comments/%v/reactions/%v", repoID, commentID, reactionID) + + return s.deleteReaction(ctx, url) +} + // ListTeamDiscussionReactions lists the reactions for a team discussion. // // GitHub API docs: https://developer.github.com/v3/reactions/#list-reactions-for-a-team-discussion @@ -352,6 +394,24 @@ func (s *ReactionsService) CreateTeamDiscussionReaction(ctx context.Context, tea return m, resp, nil } +// DeleteTeamDiscussionReaction deletes the reaction to a team discussion. +// +// GitHub API docs: https://developer.github.com/v3/reactions/#delete-team-discussion-reaction +func (s *ReactionsService) DeleteTeamDiscussionReaction(ctx context.Context, org, teamSlug string, discussionNumber int, reactionID int64) (*Response, error) { + url := fmt.Sprintf("orgs/%v/teams/%v/discussions/%v/reactions/%v", org, teamSlug, discussionNumber, reactionID) + + return s.deleteReaction(ctx, url) +} + +// DeleteTeamDiscussionReactionByOrgIDAndTeamID deletes the reaction to a team discussion by organization ID and team ID. +// +// GitHub API docs: https://developer.github.com/v3/reactions/#delete-team-discussion-reaction +func (s *ReactionsService) DeleteTeamDiscussionReactionByOrgIDAndTeamID(ctx context.Context, orgID, teamID, discussionNumber int, reactionID int64) (*Response, error) { + url := fmt.Sprintf("organizations/%v/team/%v/discussions/%v/reactions/%v", orgID, teamID, discussionNumber, reactionID) + + return s.deleteReaction(ctx, url) +} + // ListTeamDiscussionCommentReactions lists the reactions for a team discussion comment. // // GitHub API docs: https://developer.github.com/v3/reactions/#list-reactions-for-a-team-discussion-comment @@ -401,18 +461,31 @@ func (s *ReactionsService) CreateTeamDiscussionCommentReaction(ctx context.Conte return m, resp, nil } -// DeleteReaction deletes a reaction. +// DeleteTeamDiscussionCommentReaction deletes the reaction to a team discussion comment. +// +// GitHub API docs: https://developer.github.com/v3/reactions/#delete-team-discussion-comment-reaction +func (s *ReactionsService) DeleteTeamDiscussionCommentReaction(ctx context.Context, org, teamSlug string, discussionNumber, commentNumber int, reactionID int64) (*Response, error) { + url := fmt.Sprintf("orgs/%v/teams/%v/discussions/%v/comments/%v/reactions/%v", org, teamSlug, discussionNumber, commentNumber, reactionID) + + return s.deleteReaction(ctx, url) +} + +// DeleteTeamDiscussionCommentReactionByOrgIDAndTeamID deletes the reaction to a team discussion comment by organization ID and team ID. // -// GitHub API docs: https://developer.github.com/v3/reaction/reactions/#delete-a-reaction-archive -func (s *ReactionsService) DeleteReaction(ctx context.Context, id int64) (*Response, error) { - u := fmt.Sprintf("reactions/%v", id) +// GitHub API docs: https://developer.github.com/v3/reactions/#delete-team-discussion-comment-reaction +func (s *ReactionsService) DeleteTeamDiscussionCommentReactionByOrgIDAndTeamID(ctx context.Context, orgID, teamID, discussionNumber, commentNumber int, reactionID int64) (*Response, error) { + url := fmt.Sprintf("organizations/%v/team/%v/discussions/%v/comments/%v/reactions/%v", orgID, teamID, discussionNumber, commentNumber, reactionID) + + return s.deleteReaction(ctx, url) +} - req, err := s.client.NewRequest("DELETE", u, nil) +func (s ReactionsService) deleteReaction(ctx context.Context, url string) (*Response, error) { + req, err := s.client.NewRequest(http.MethodDelete, url, nil) if err != nil { return nil, err } - // TODO: remove custom Accept header when this API fully launches. + // TODO: remove custom Accept headers when APIs fully launch. req.Header.Set("Accept", mediaTypeReactionsPreview) return s.client.Do(ctx, req, nil) diff --git a/github/reactions_test.go b/github/reactions_test.go index 90b9eaafc28..ede3105e0df 100644 --- a/github/reactions_test.go +++ b/github/reactions_test.go @@ -325,50 +325,194 @@ func TestReactionService_CreateTeamDiscussionCommentReaction(t *testing.T) { } } -func TestReactionsService_DeleteReaction(t *testing.T) { +func TestReactionsService_DeleteCommitCommentReaction(t *testing.T) { client, mux, _, teardown := setup() defer teardown() - mux.HandleFunc("/reactions/1", func(w http.ResponseWriter, r *http.Request) { + mux.HandleFunc("/repos/o/r/comments/1/reactions/2", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "DELETE") testHeader(t, r, "Accept", mediaTypeReactionsPreview) w.WriteHeader(http.StatusNoContent) }) - if _, err := client.Reactions.DeleteReaction(context.Background(), 1); err != nil { - t.Errorf("DeleteReaction returned error: %v", err) + if _, err := client.Reactions.DeleteCommentReaction(context.Background(), "o", "r", 1, 2); err != nil { + t.Errorf("DeleteCommentReaction returned error: %v", err) } } -func TestReactionsService_DeleteCommitCommentReaction(t *testing.T) { +func TestReactionsService_DeleteCommitCommentReactionByRepoID(t *testing.T) { client, mux, _, teardown := setup() defer teardown() - mux.HandleFunc("/repos/o/r/comments/1/reactions/2", func(w http.ResponseWriter, r *http.Request) { + mux.HandleFunc("/repositories/1/comments/2/reactions/3", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "DELETE") testHeader(t, r, "Accept", mediaTypeReactionsPreview) w.WriteHeader(http.StatusNoContent) }) - if _, err := client.Reactions.DeleteCommentReaction(context.Background(), "o", "r", 1, 2); err != nil { - t.Errorf("DeleteCommentReaction returned error: %v", err) + if _, err := client.Reactions.DeleteCommentReactionByID(context.Background(), 1, 2, 3); err != nil { + t.Errorf("DeleteCommentReactionByRepoID returned error: %v", err) } } -func TestReactionsService_DeleteCommitCommentReactionByRepoID(t *testing.T) { +func TestReactionsService_DeleteIssueReaction(t *testing.T) { client, mux, _, teardown := setup() defer teardown() - mux.HandleFunc("/repositories/1/comments/2/reactions/3", func(w http.ResponseWriter, r *http.Request) { + mux.HandleFunc("/repos/o/r/issues/1/reactions/2", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "DELETE") testHeader(t, r, "Accept", mediaTypeReactionsPreview) w.WriteHeader(http.StatusNoContent) }) - if _, err := client.Reactions.DeleteCommentReactionByRepoID(context.Background(), 1, 2, 3); err != nil { - t.Errorf("DeleteCommentReactionByRepoID returned error: %v", err) + if _, err := client.Reactions.DeleteIssueReaction(context.Background(), "o", "r", 1, 2); err != nil { + t.Errorf("DeleteIssueReaction returned error: %v", err) + } +} + +func TestReactionsService_DeleteIssueReactionByRepoID(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/repositories/1/issues/2/reactions/3", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "DELETE") + testHeader(t, r, "Accept", mediaTypeReactionsPreview) + + w.WriteHeader(http.StatusNoContent) + }) + + if _, err := client.Reactions.DeleteIssueReactionByID(context.Background(), 1, 2, 3); err != nil { + t.Errorf("DeleteIssueReactionByRepoID returned error: %v", err) + } +} + +func TestReactionsService_DeleteIssueCommentReaction(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/repos/o/r/issues/comments/1/reactions/2", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "DELETE") + testHeader(t, r, "Accept", mediaTypeReactionsPreview) + + w.WriteHeader(http.StatusNoContent) + }) + + if _, err := client.Reactions.DeleteIssueCommentReaction(context.Background(), "o", "r", 1, 2); err != nil { + t.Errorf("DeleteIssueCommentReaction returned error: %v", err) + } +} + +func TestReactionsService_DeleteIssueCommentReactionByRepoID(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/repositories/1/issues/comments/2/reactions/3", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "DELETE") + testHeader(t, r, "Accept", mediaTypeReactionsPreview) + + w.WriteHeader(http.StatusNoContent) + }) + + if _, err := client.Reactions.DeleteIssueCommentReactionByID(context.Background(), 1, 2, 3); err != nil { + t.Errorf("DeleteIssueCommentReactionByRepoID returned error: %v", err) + } +} + +func TestReactionsService_DeletePullRequestCommentReaction(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/repos/o/r/pulls/comments/1/reactions/2", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "DELETE") + testHeader(t, r, "Accept", mediaTypeReactionsPreview) + + w.WriteHeader(http.StatusNoContent) + }) + + if _, err := client.Reactions.DeletePullRequestCommentReaction(context.Background(), "o", "r", 1, 2); err != nil { + t.Errorf("DeletePullRequestCommentReaction returned error: %v", err) + } +} + +func TestReactionsService_DeletePullRequestCommentReactionByRepoID(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/repositories/1/pulls/comments/2/reactions/3", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "DELETE") + testHeader(t, r, "Accept", mediaTypeReactionsPreview) + + w.WriteHeader(http.StatusNoContent) + }) + + if _, err := client.Reactions.DeletePullRequestCommentReactionByID(context.Background(), 1, 2, 3); err != nil { + t.Errorf("DeletePullRequestCommentReactionByRepoID returned error: %v", err) + } +} + +func TestReactionsService_DeleteTeamDiscussionReaction(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/orgs/o/teams/s/discussions/1/reactions/2", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "DELETE") + testHeader(t, r, "Accept", mediaTypeReactionsPreview) + + w.WriteHeader(http.StatusNoContent) + }) + + if _, err := client.Reactions.DeleteTeamDiscussionReaction(context.Background(), "o", "s", 1, 2); err != nil { + t.Errorf("DeleteTeamDiscussionReaction returned error: %v", err) + } +} + +func TestReactionsService_DeleteTeamDiscussionReactionByTeamIDAndOrgID(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/organizations/1/team/2/discussions/3/reactions/4", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "DELETE") + testHeader(t, r, "Accept", mediaTypeReactionsPreview) + + w.WriteHeader(http.StatusNoContent) + }) + + if _, err := client.Reactions.DeleteTeamDiscussionReactionByOrgIDAndTeamID(context.Background(), 1, 2, 3, 4); err != nil { + t.Errorf("DeleteTeamDiscussionReactionByTeamIDAndOrgID returned error: %v", err) + } +} + +func TestReactionsService_DeleteTeamDiscussionCommentReaction(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/orgs/o/teams/s/discussions/1/comments/2/reactions/3", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "DELETE") + testHeader(t, r, "Accept", mediaTypeReactionsPreview) + + w.WriteHeader(http.StatusNoContent) + }) + + if _, err := client.Reactions.DeleteTeamDiscussionCommentReaction(context.Background(), "o", "s", 1, 2, 3); err != nil { + t.Errorf("DeleteTeamDiscussionCommentReaction returned error: %v", err) + } +} + +func TestReactionsService_DeleteTeamDiscussionCommentReactionByTeamIDAndOrgID(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/organizations/1/team/2/discussions/3/comments/4/reactions/5", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "DELETE") + testHeader(t, r, "Accept", mediaTypeReactionsPreview) + + w.WriteHeader(http.StatusNoContent) + }) + + if _, err := client.Reactions.DeleteTeamDiscussionCommentReactionByOrgIDAndTeamID(context.Background(), 1, 2, 3, 4, 5); err != nil { + t.Errorf("DeleteTeamDiscussionCommentReactionByTeamIDAndOrgID returned error: %v", err) } } From f5442b7a9ba82833f3612dad5a03d1383f363949 Mon Sep 17 00:00:00 2001 From: Glenn Lewis <6598971+gmlewis@users.noreply.github.com> Date: Wed, 18 Mar 2020 09:31:30 -0400 Subject: [PATCH 0153/1468] Prepare for release v30.0.0 (#1456) --- README.md | 4 ++-- example/appengine/app.go | 2 +- example/basicauth/main.go | 2 +- example/commitpr/main.go | 2 +- example/migrations/main.go | 2 +- example/newrepo/main.go | 2 +- example/simple/main.go | 2 +- example/topics/main.go | 2 +- github/doc.go | 2 +- github/examples_test.go | 2 +- go.mod | 2 +- test/fields/fields.go | 2 +- test/integration/activity_test.go | 2 +- test/integration/authorizations_test.go | 2 +- test/integration/github_test.go | 2 +- test/integration/repos_test.go | 2 +- test/integration/users_test.go | 2 +- 17 files changed, 18 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 326cfe38190..deb37542272 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # go-github # -[![GoDoc](https://img.shields.io/static/v1?label=godoc&message=reference&color=blue)](https://pkg.go.dev/github.com/google/go-github/v29/github) +[![GoDoc](https://img.shields.io/static/v1?label=godoc&message=reference&color=blue)](https://pkg.go.dev/github.com/google/go-github/v30/github) [![Test Status](https://github.com/google/go-github/workflows/tests/badge.svg)](https://github.com/google/go-github/actions?query=workflow%3Atests) [![Test Coverage](https://codecov.io/gh/google/go-github/branch/master/graph/badge.svg)](https://codecov.io/gh/google/go-github) [![Discuss at go-github@googlegroups.com](https://img.shields.io/badge/discuss-go--github%40googlegroups.com-blue.svg)](https://groups.google.com/group/go-github) @@ -21,7 +21,7 @@ If you're interested in using the [GraphQL API v4][], the recommended library is ## Usage ## ```go -import "github.com/google/go-github/v29/github" // with go modules enabled (GO111MODULE=on or outside GOPATH) +import "github.com/google/go-github/v30/github" // with go modules enabled (GO111MODULE=on or outside GOPATH) import "github.com/google/go-github/github" // with go modules disabled ``` diff --git a/example/appengine/app.go b/example/appengine/app.go index ba2818423f6..bf6829d1402 100644 --- a/example/appengine/app.go +++ b/example/appengine/app.go @@ -12,7 +12,7 @@ import ( "net/http" "os" - "github.com/google/go-github/v29/github" + "github.com/google/go-github/v30/github" "golang.org/x/oauth2" "google.golang.org/appengine" "google.golang.org/appengine/log" diff --git a/example/basicauth/main.go b/example/basicauth/main.go index 4c31a30c427..53db11200c5 100644 --- a/example/basicauth/main.go +++ b/example/basicauth/main.go @@ -16,7 +16,7 @@ import ( "strings" "syscall" - "github.com/google/go-github/v29/github" + "github.com/google/go-github/v30/github" "golang.org/x/crypto/ssh/terminal" ) diff --git a/example/commitpr/main.go b/example/commitpr/main.go index e2ba12a4f55..0535ef1bcf9 100644 --- a/example/commitpr/main.go +++ b/example/commitpr/main.go @@ -31,7 +31,7 @@ import ( "strings" "time" - "github.com/google/go-github/v29/github" + "github.com/google/go-github/v30/github" "golang.org/x/oauth2" ) diff --git a/example/migrations/main.go b/example/migrations/main.go index d73380a7192..2869337da42 100644 --- a/example/migrations/main.go +++ b/example/migrations/main.go @@ -12,7 +12,7 @@ import ( "context" "fmt" - "github.com/google/go-github/v29/github" + "github.com/google/go-github/v30/github" "golang.org/x/oauth2" ) diff --git a/example/newrepo/main.go b/example/newrepo/main.go index 4b03a4407f9..77baac29e8b 100644 --- a/example/newrepo/main.go +++ b/example/newrepo/main.go @@ -16,7 +16,7 @@ import ( "log" "os" - "github.com/google/go-github/v29/github" + "github.com/google/go-github/v30/github" "golang.org/x/oauth2" ) diff --git a/example/simple/main.go b/example/simple/main.go index 33af5e5eaef..179c6423cae 100644 --- a/example/simple/main.go +++ b/example/simple/main.go @@ -12,7 +12,7 @@ import ( "context" "fmt" - "github.com/google/go-github/v29/github" + "github.com/google/go-github/v30/github" ) // Fetch all the public organizations' membership of a user. diff --git a/example/topics/main.go b/example/topics/main.go index da814a4abfb..b25e6be4d4a 100644 --- a/example/topics/main.go +++ b/example/topics/main.go @@ -12,7 +12,7 @@ import ( "context" "fmt" - "github.com/google/go-github/v29/github" + "github.com/google/go-github/v30/github" ) // Fetch all the public organizations' membership of a user. diff --git a/github/doc.go b/github/doc.go index 403a6ecc6fa..bad4821b2ad 100644 --- a/github/doc.go +++ b/github/doc.go @@ -8,7 +8,7 @@ Package github provides a client for using the GitHub API. Usage: - import "github.com/google/go-github/v29/github" // with go modules enabled (GO111MODULE=on or outside GOPATH) + import "github.com/google/go-github/v30/github" // with go modules enabled (GO111MODULE=on or outside GOPATH) import "github.com/google/go-github/github" // with go modules disabled Construct a new GitHub client, then use the various services on the client to diff --git a/github/examples_test.go b/github/examples_test.go index 3035f0ccf7f..f0b01905be6 100644 --- a/github/examples_test.go +++ b/github/examples_test.go @@ -12,7 +12,7 @@ import ( "fmt" "log" - "github.com/google/go-github/v29/github" + "github.com/google/go-github/v30/github" ) func ExampleClient_Markdown() { diff --git a/go.mod b/go.mod index bb82bb43edb..6cf63d146dc 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module github.com/google/go-github/v29 +module github.com/google/go-github/v30 require ( github.com/golang/protobuf v1.3.2 // indirect diff --git a/test/fields/fields.go b/test/fields/fields.go index 59a2c6476bd..ed14a451502 100644 --- a/test/fields/fields.go +++ b/test/fields/fields.go @@ -25,7 +25,7 @@ import ( "reflect" "strings" - "github.com/google/go-github/v29/github" + "github.com/google/go-github/v30/github" "golang.org/x/oauth2" ) diff --git a/test/integration/activity_test.go b/test/integration/activity_test.go index 15daf5d067b..5f7a1d305df 100644 --- a/test/integration/activity_test.go +++ b/test/integration/activity_test.go @@ -11,7 +11,7 @@ import ( "context" "testing" - "github.com/google/go-github/v29/github" + "github.com/google/go-github/v30/github" ) const ( diff --git a/test/integration/authorizations_test.go b/test/integration/authorizations_test.go index 90f09083051..3934a0de15d 100644 --- a/test/integration/authorizations_test.go +++ b/test/integration/authorizations_test.go @@ -16,7 +16,7 @@ import ( "testing" "time" - "github.com/google/go-github/v29/github" + "github.com/google/go-github/v30/github" ) const msgEnvMissing = "Skipping test because the required environment variable (%v) is not present." diff --git a/test/integration/github_test.go b/test/integration/github_test.go index a9aace3ff47..9b4fa942963 100644 --- a/test/integration/github_test.go +++ b/test/integration/github_test.go @@ -14,7 +14,7 @@ import ( "net/http" "os" - "github.com/google/go-github/v29/github" + "github.com/google/go-github/v30/github" "golang.org/x/oauth2" ) diff --git a/test/integration/repos_test.go b/test/integration/repos_test.go index 0cd2a87a572..9282fa0bbfc 100644 --- a/test/integration/repos_test.go +++ b/test/integration/repos_test.go @@ -15,7 +15,7 @@ import ( "reflect" "testing" - "github.com/google/go-github/v29/github" + "github.com/google/go-github/v30/github" ) func TestRepositories_CRUD(t *testing.T) { diff --git a/test/integration/users_test.go b/test/integration/users_test.go index bb8c5e23692..a038d45b6bd 100644 --- a/test/integration/users_test.go +++ b/test/integration/users_test.go @@ -13,7 +13,7 @@ import ( "math/rand" "testing" - "github.com/google/go-github/v29/github" + "github.com/google/go-github/v30/github" ) func TestUsers_Get(t *testing.T) { From 7726a3e3e3b67ab86c97198c8d682b09108a27b7 Mon Sep 17 00:00:00 2001 From: Suhaib Mujahid Date: Thu, 19 Mar 2020 19:53:35 -0400 Subject: [PATCH 0154/1468] Update github.go (#1464) --- github/github.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/github/github.go b/github/github.go index 644e230baec..15715cf0a92 100644 --- a/github/github.go +++ b/github/github.go @@ -296,7 +296,7 @@ func NewClient(httpClient *http.Client) *Client { // NewEnterpriseClient returns a new GitHub API client with provided // base URL and upload URL (often the same URL and is your GitHub Enterprise hostname). // If either URL does not have the suffix "/api/v3/", it will be added automatically. -// If a nil httpClient is provided, http.DefaultClient will be used. +// If a nil httpClient is provided, a new http.Client will be used. // // Note that NewEnterpriseClient is a convenience helper only; // its behavior is equivalent to using NewClient, followed by setting From 371b0007be89061b4cf899dc2083dd08e3912c14 Mon Sep 17 00:00:00 2001 From: Patrick Marabeas Date: Wed, 25 Mar 2020 23:37:04 +1100 Subject: [PATCH 0155/1468] Implement support for repository visibility parameter (#1471) Fixes #1470. --- github/github-accessors.go | 8 ++++++++ github/github-stringify_test.go | 3 ++- github/github.go | 3 +++ github/repos.go | 23 ++++++++++++++++------- github/repos_test.go | 9 ++++++--- 5 files changed, 35 insertions(+), 11 deletions(-) diff --git a/github/github-accessors.go b/github/github-accessors.go index 519123cdcf7..27e8b136caf 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -10708,6 +10708,14 @@ func (r *Repository) GetURL() string { return *r.URL } +// GetVisibility returns the Visibility field if it's non-nil, zero value otherwise. +func (r *Repository) GetVisibility() string { + if r == nil || r.Visibility == nil { + return "" + } + return *r.Visibility +} + // GetWatchersCount returns the WatchersCount field if it's non-nil, zero value otherwise. func (r *Repository) GetWatchersCount() int { if r == nil || r.WatchersCount == nil { diff --git a/github/github-stringify_test.go b/github/github-stringify_test.go index b85d3a62c30..df474203300 100644 --- a/github/github-stringify_test.go +++ b/github/github-stringify_test.go @@ -1301,8 +1301,9 @@ func TestRepository_String(t *testing.T) { TagsURL: String(""), TreesURL: String(""), TeamsURL: String(""), + Visibility: String(""), } - want := `github.Repository{ID:0, NodeID:"", Owner:github.User{}, Name:"", FullName:"", Description:"", Homepage:"", CodeOfConduct:github.CodeOfConduct{}, DefaultBranch:"", MasterBranch:"", CreatedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, PushedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, UpdatedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, HTMLURL:"", CloneURL:"", GitURL:"", MirrorURL:"", SSHURL:"", SVNURL:"", Language:"", Fork:false, ForksCount:0, NetworkCount:0, OpenIssuesCount:0, StargazersCount:0, SubscribersCount:0, WatchersCount:0, Size:0, AutoInit:false, Parent:github.Repository{}, Source:github.Repository{}, TemplateRepository:github.Repository{}, Organization:github.Organization{}, AllowRebaseMerge:false, AllowSquashMerge:false, AllowMergeCommit:false, DeleteBranchOnMerge:false, Archived:false, Disabled:false, License:github.License{}, Private:false, HasIssues:false, HasWiki:false, HasPages:false, HasProjects:false, HasDownloads:false, IsTemplate:false, LicenseTemplate:"", GitignoreTemplate:"", TeamID:0, URL:"", ArchiveURL:"", AssigneesURL:"", BlobsURL:"", BranchesURL:"", CollaboratorsURL:"", CommentsURL:"", CommitsURL:"", CompareURL:"", ContentsURL:"", ContributorsURL:"", DeploymentsURL:"", DownloadsURL:"", EventsURL:"", ForksURL:"", GitCommitsURL:"", GitRefsURL:"", GitTagsURL:"", HooksURL:"", IssueCommentURL:"", IssueEventsURL:"", IssuesURL:"", KeysURL:"", LabelsURL:"", LanguagesURL:"", MergesURL:"", MilestonesURL:"", NotificationsURL:"", PullsURL:"", ReleasesURL:"", StargazersURL:"", StatusesURL:"", SubscribersURL:"", SubscriptionURL:"", TagsURL:"", TreesURL:"", TeamsURL:""}` + want := `github.Repository{ID:0, NodeID:"", Owner:github.User{}, Name:"", FullName:"", Description:"", Homepage:"", CodeOfConduct:github.CodeOfConduct{}, DefaultBranch:"", MasterBranch:"", CreatedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, PushedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, UpdatedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, HTMLURL:"", CloneURL:"", GitURL:"", MirrorURL:"", SSHURL:"", SVNURL:"", Language:"", Fork:false, ForksCount:0, NetworkCount:0, OpenIssuesCount:0, StargazersCount:0, SubscribersCount:0, WatchersCount:0, Size:0, AutoInit:false, Parent:github.Repository{}, Source:github.Repository{}, TemplateRepository:github.Repository{}, Organization:github.Organization{}, AllowRebaseMerge:false, AllowSquashMerge:false, AllowMergeCommit:false, DeleteBranchOnMerge:false, Archived:false, Disabled:false, License:github.License{}, Private:false, HasIssues:false, HasWiki:false, HasPages:false, HasProjects:false, HasDownloads:false, IsTemplate:false, LicenseTemplate:"", GitignoreTemplate:"", TeamID:0, URL:"", ArchiveURL:"", AssigneesURL:"", BlobsURL:"", BranchesURL:"", CollaboratorsURL:"", CommentsURL:"", CommitsURL:"", CompareURL:"", ContentsURL:"", ContributorsURL:"", DeploymentsURL:"", DownloadsURL:"", EventsURL:"", ForksURL:"", GitCommitsURL:"", GitRefsURL:"", GitTagsURL:"", HooksURL:"", IssueCommentURL:"", IssueEventsURL:"", IssuesURL:"", KeysURL:"", LabelsURL:"", LanguagesURL:"", MergesURL:"", MilestonesURL:"", NotificationsURL:"", PullsURL:"", ReleasesURL:"", StargazersURL:"", StatusesURL:"", SubscribersURL:"", SubscriptionURL:"", TagsURL:"", TreesURL:"", TeamsURL:"", Visibility:""}` if got := v.String(); got != want { t.Errorf("Repository.String = %v, want %v", got, want) } diff --git a/github/github.go b/github/github.go index 15715cf0a92..c9bdff55f30 100644 --- a/github/github.go +++ b/github/github.go @@ -138,6 +138,9 @@ const ( // https://developer.github.com/changes/2019-11-05-deprecated-passwords-and-authorizations-api/ mediaTypeOAuthAppPreview = "application/vnd.github.doctor-strange-preview+json" + + // https://developer.github.com/changes/2019-12-03-internal-visibility-changes/ + mediaTypeRepositoryVisibilityPreview = "application/vnd.github.nebula-preview+json" ) // A Client manages communication with the GitHub API. diff --git a/github/repos.go b/github/repos.go index bce3c942743..41249226d1a 100644 --- a/github/repos.go +++ b/github/repos.go @@ -121,6 +121,11 @@ type Repository 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"` + + // Visibility is only used for Create and Edit endpoints. The visibility field + // overrides the field parameter when both are used. + // Can be one of public, private or internal. + Visibility *string `json:"visibility,omitempty"` } func (r Repository) String() string { @@ -295,11 +300,12 @@ type createRepoRequest struct { Description *string `json:"description,omitempty"` Homepage *string `json:"homepage,omitempty"` - Private *bool `json:"private,omitempty"` - HasIssues *bool `json:"has_issues,omitempty"` - HasProjects *bool `json:"has_projects,omitempty"` - HasWiki *bool `json:"has_wiki,omitempty"` - IsTemplate *bool `json:"is_template,omitempty"` + Private *bool `json:"private,omitempty"` + Visibility *string `json:"visibility,omitempty"` + HasIssues *bool `json:"has_issues,omitempty"` + HasProjects *bool `json:"has_projects,omitempty"` + HasWiki *bool `json:"has_wiki,omitempty"` + IsTemplate *bool `json:"is_template,omitempty"` // Creating an organization repository. Required for non-owners. TeamID *int64 `json:"team_id,omitempty"` @@ -334,6 +340,7 @@ func (s *RepositoriesService) Create(ctx context.Context, org string, repo *Repo Description: repo.Description, Homepage: repo.Homepage, Private: repo.Private, + Visibility: repo.Visibility, HasIssues: repo.HasIssues, HasProjects: repo.HasProjects, HasWiki: repo.HasWiki, @@ -353,7 +360,8 @@ func (s *RepositoriesService) Create(ctx context.Context, org string, repo *Repo return nil, nil, err } - req.Header.Set("Accept", mediaTypeRepositoryTemplatePreview) + acceptHeaders := []string{mediaTypeRepositoryTemplatePreview, mediaTypeRepositoryVisibilityPreview} + req.Header.Set("Accept", strings.Join(acceptHeaders, ", ")) r := new(Repository) resp, err := s.client.Do(ctx, req, r) if err != nil { @@ -469,7 +477,8 @@ func (s *RepositoriesService) Edit(ctx context.Context, owner, repo string, repo return nil, nil, err } - req.Header.Set("Accept", mediaTypeRepositoryTemplatePreview) + acceptHeaders := []string{mediaTypeRepositoryTemplatePreview, mediaTypeRepositoryVisibilityPreview} + req.Header.Set("Accept", strings.Join(acceptHeaders, ", ")) r := new(Repository) resp, err := s.client.Do(ctx, req, r) if err != nil { diff --git a/github/repos_test.go b/github/repos_test.go index d1c60cb010b..889a8fc8ddf 100644 --- a/github/repos_test.go +++ b/github/repos_test.go @@ -251,12 +251,13 @@ func TestRepositoriesService_Create_user(t *testing.T) { Archived: Bool(true), // not passed along. } + wantAcceptHeaders := []string{mediaTypeRepositoryTemplatePreview, mediaTypeRepositoryVisibilityPreview} mux.HandleFunc("/user/repos", func(w http.ResponseWriter, r *http.Request) { v := new(createRepoRequest) json.NewDecoder(r.Body).Decode(v) testMethod(t, r, "POST") - testHeader(t, r, "Accept", mediaTypeRepositoryTemplatePreview) + testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", ")) want := &createRepoRequest{Name: String("n")} if !reflect.DeepEqual(v, want) { t.Errorf("Request body = %+v, want %+v", v, want) @@ -313,12 +314,13 @@ func TestRepositoriesService_Create_org(t *testing.T) { Archived: Bool(true), // not passed along. } + wantAcceptHeaders := []string{mediaTypeRepositoryTemplatePreview, mediaTypeRepositoryVisibilityPreview} mux.HandleFunc("/orgs/o/repos", func(w http.ResponseWriter, r *http.Request) { v := new(createRepoRequest) json.NewDecoder(r.Body).Decode(v) testMethod(t, r, "POST") - testHeader(t, r, "Accept", mediaTypeRepositoryTemplatePreview) + testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", ")) want := &createRepoRequest{Name: String("n")} if !reflect.DeepEqual(v, want) { t.Errorf("Request body = %+v, want %+v", v, want) @@ -551,12 +553,13 @@ func TestRepositoriesService_Edit(t *testing.T) { i := true input := &Repository{HasIssues: &i} + wantAcceptHeaders := []string{mediaTypeRepositoryTemplatePreview, mediaTypeRepositoryVisibilityPreview} mux.HandleFunc("/repos/o/r", func(w http.ResponseWriter, r *http.Request) { v := new(Repository) json.NewDecoder(r.Body).Decode(v) testMethod(t, r, "PATCH") - testHeader(t, r, "Accept", mediaTypeRepositoryTemplatePreview) + testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", ")) if !reflect.DeepEqual(v, input) { t.Errorf("Request body = %+v, want %+v", v, input) } From e213c6de853e9c5ed9d53257b4fec0b5dac0b713 Mon Sep 17 00:00:00 2001 From: Glenn Lewis <6598971+gmlewis@users.noreply.github.com> Date: Wed, 25 Mar 2020 13:54:14 -0400 Subject: [PATCH 0156/1468] Update ListRunners with new response type - breaking change (#1473) --- github/actions_runners.go | 10 ++++++++-- github/actions_runners_test.go | 11 +++++++---- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/github/actions_runners.go b/github/actions_runners.go index bab3963136d..24f88f0f990 100644 --- a/github/actions_runners.go +++ b/github/actions_runners.go @@ -71,10 +71,16 @@ type Runner struct { Status *string `json:"status,omitempty"` } +// Runners represents a collection of self-hosted runners for a repository. +type Runners struct { + TotalCount int `json:"total_count"` + Runners []*Runner `json:"runners"` +} + // ListRunners lists all the self-hosted runners for a repository. // // GitHub API docs: https://developer.github.com/v3/actions/self_hosted_runners/#list-self-hosted-runners-for-a-repository -func (s *ActionsService) ListRunners(ctx context.Context, owner, repo string, opts *ListOptions) ([]*Runner, *Response, error) { +func (s *ActionsService) ListRunners(ctx context.Context, owner, repo string, opts *ListOptions) (*Runners, *Response, error) { u := fmt.Sprintf("repos/%v/%v/actions/runners", owner, repo) u, err := addOptions(u, opts) if err != nil { @@ -86,7 +92,7 @@ func (s *ActionsService) ListRunners(ctx context.Context, owner, repo string, op return nil, nil, err } - var runners []*Runner + runners := &Runners{} resp, err := s.client.Do(ctx, req, &runners) if err != nil { return nil, resp, err diff --git a/github/actions_runners_test.go b/github/actions_runners_test.go index 6739b28addd..13ceeea6a9d 100644 --- a/github/actions_runners_test.go +++ b/github/actions_runners_test.go @@ -69,7 +69,7 @@ func TestActionsService_ListRunners(t *testing.T) { mux.HandleFunc("/repos/o/r/actions/runners", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") testFormValues(t, r, values{"per_page": "2", "page": "2"}) - fmt.Fprint(w, `[{"id":23,"name":"MBP","os":"macos","status":"online"},{"id":24,"name":"iMac","os":"macos","status":"offline"}]`) + fmt.Fprint(w, `{"total_count":2,"runners":[{"id":23,"name":"MBP","os":"macos","status":"online"},{"id":24,"name":"iMac","os":"macos","status":"offline"}]}`) }) opts := &ListOptions{Page: 2, PerPage: 2} @@ -78,9 +78,12 @@ func TestActionsService_ListRunners(t *testing.T) { t.Errorf("Actions.ListRunners returned error: %v", err) } - want := []*Runner{ - {ID: Int64(23), Name: String("MBP"), OS: String("macos"), Status: String("online")}, - {ID: Int64(24), Name: String("iMac"), OS: String("macos"), Status: String("offline")}, + want := &Runners{ + TotalCount: 2, + Runners: []*Runner{ + {ID: Int64(23), Name: String("MBP"), OS: String("macos"), Status: String("online")}, + {ID: Int64(24), Name: String("iMac"), OS: String("macos"), Status: String("offline")}, + }, } if !reflect.DeepEqual(runners, want) { t.Errorf("Actions.ListRunners returned %+v, want %+v", runners, want) From 07c03e832bbdcc97d495d829c7d5fbc0452aa973 Mon Sep 17 00:00:00 2001 From: Alex Orr Date: Fri, 27 Mar 2020 05:10:30 -0700 Subject: [PATCH 0157/1468] Support for deprecating API authentication through query parameters (#1469) --- github/github.go | 54 ++++++++++++++++++------------------------- github/github_test.go | 38 +++++++++++++++++++++++------- 2 files changed, 52 insertions(+), 40 deletions(-) diff --git a/github/github.go b/github/github.go index c9bdff55f30..94f31a4c261 100644 --- a/github/github.go +++ b/github/github.go @@ -924,6 +924,24 @@ func (c *Client) RateLimits(ctx context.Context) (*RateLimits, *Response, error) return response.Resources, resp, nil } +func setCredentialsAsHeaders(req *http.Request, id, secret string) *http.Request { + // To set extra headers, we must make a copy of the Request so + // that we don't modify the Request we were given. This is required by the + // specification of http.RoundTripper. + // + // Since we are going to modify only req.Header here, we only need a deep copy + // of req.Header. + convertedRequest := new(http.Request) + *convertedRequest = *req + convertedRequest.Header = make(http.Header, len(req.Header)) + + for k, s := range req.Header { + convertedRequest.Header[k] = append([]string(nil), s...) + } + convertedRequest.SetBasicAuth(id, secret) + return convertedRequest +} + /* UnauthenticatedRateLimitedTransport allows you to make unauthenticated calls that need to use a higher rate limit associated with your OAuth application. @@ -934,8 +952,8 @@ that need to use a higher rate limit associated with your OAuth application. } client := github.NewClient(t.Client()) -This will append the querystring params client_id=xxx&client_secret=yyy to all -requests. +This will add the client id and secret as a base64-encoded string in the format +ClientID:ClientSecret and apply it as an "Authorization": "Basic" header. See https://developer.github.com/v3/#unauthenticated-rate-limited-requests for more information. @@ -964,22 +982,7 @@ func (t *UnauthenticatedRateLimitedTransport) RoundTrip(req *http.Request) (*htt return nil, errors.New("t.ClientSecret is empty") } - // To set extra querystring params, we must make a copy of the Request so - // that we don't modify the Request we were given. This is required by the - // specification of http.RoundTripper. - // - // Since we are going to modify only req.URL here, we only need a deep copy - // of req.URL. - req2 := new(http.Request) - *req2 = *req - req2.URL = new(url.URL) - *req2.URL = *req.URL - - q := req2.URL.Query() - q.Set("client_id", t.ClientID) - q.Set("client_secret", t.ClientSecret) - req2.URL.RawQuery = q.Encode() - + req2 := setCredentialsAsHeaders(req, t.ClientID, t.ClientSecret) // Make the HTTP request. return t.transport().RoundTrip(req2) } @@ -1013,20 +1016,7 @@ type BasicAuthTransport struct { // RoundTrip implements the RoundTripper interface. func (t *BasicAuthTransport) RoundTrip(req *http.Request) (*http.Response, error) { - // To set extra headers, we must make a copy of the Request so - // that we don't modify the Request we were given. This is required by the - // specification of http.RoundTripper. - // - // Since we are going to modify only req.Header here, we only need a deep copy - // of req.Header. - req2 := new(http.Request) - *req2 = *req - req2.Header = make(http.Header, len(req.Header)) - for k, s := range req.Header { - req2.Header[k] = append([]string(nil), s...) - } - - req2.SetBasicAuth(t.Username, t.Password) + req2 := setCredentialsAsHeaders(req, t.Username, t.Password) if t.OTP != "" { req2.Header.Set(headerOTP, t.OTP) } diff --git a/github/github_test.go b/github/github_test.go index 8381280b784..719741bc57b 100644 --- a/github/github_test.go +++ b/github/github_test.go @@ -1099,24 +1099,46 @@ func TestRateLimits(t *testing.T) { } } +func TestSetCredentialsAsHeaders(t *testing.T) { + req := new(http.Request) + id, secret := "id", "secret" + modifiedRequest := setCredentialsAsHeaders(req, id, secret) + + actualID, actualSecret, ok := modifiedRequest.BasicAuth() + if !ok { + t.Errorf("request does not contain basic credentials") + } + + if actualID != id { + t.Errorf("id is %s, want %s", actualID, id) + } + + if actualSecret != secret { + t.Errorf("secret is %s, want %s", actualSecret, secret) + } +} + func TestUnauthenticatedRateLimitedTransport(t *testing.T) { client, mux, _, teardown := setup() defer teardown() + clientID, clientSecret := "id", "secret" mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { - var v, want string - q := r.URL.Query() - if v, want = q.Get("client_id"), "id"; v != want { - t.Errorf("OAuth Client ID = %v, want %v", v, want) + id, secret, ok := r.BasicAuth() + if !ok { + t.Errorf("request does not contain basic auth credentials") } - if v, want = q.Get("client_secret"), "secret"; v != want { - t.Errorf("OAuth Client Secret = %v, want %v", v, want) + if id != clientID { + t.Errorf("request contained basic auth username %q, want %q", id, clientID) + } + if secret != clientSecret { + t.Errorf("request contained basic auth password %q, want %q", secret, clientSecret) } }) tp := &UnauthenticatedRateLimitedTransport{ - ClientID: "id", - ClientSecret: "secret", + ClientID: clientID, + ClientSecret: clientSecret, } unauthedClient := NewClient(tp.Client()) unauthedClient.BaseURL = client.BaseURL From 34cb1d623f03e277545da01608448d9fea80dc3b Mon Sep 17 00:00:00 2001 From: 2BFL Date: Sat, 28 Mar 2020 21:39:46 +0800 Subject: [PATCH 0158/1468] Fix doc URL (#1475) --- github/issues.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/github/issues.go b/github/issues.go index b53a2603e8b..bc3b83e732b 100644 --- a/github/issues.go +++ b/github/issues.go @@ -215,7 +215,7 @@ type IssueListByRepoOptions struct { // ListByRepo lists the issues for the specified repository. // -// GitHub API docs: https://developer.github.com/v3/issues/#list-issues-for-a-repository +// GitHub API docs: https://developer.github.com/v3/issues/#list-repository-issues func (s *IssuesService) ListByRepo(ctx context.Context, owner string, repo string, opts *IssueListByRepoOptions) ([]*Issue, *Response, error) { u := fmt.Sprintf("repos/%v/%v/issues", owner, repo) u, err := addOptions(u, opts) From 4a7cf4a76843a3e11ce2bfd96a9b5067a07a2429 Mon Sep 17 00:00:00 2001 From: Ryan Mast Date: Wed, 8 Apr 2020 05:54:14 -0700 Subject: [PATCH 0159/1468] Add RenameOrg endpoint for Org Admin API (#1480) Fixes #1479. --- github/admin_orgs.go | 48 +++++++++++++++++++++++++++++- github/admin_orgs_test.go | 60 ++++++++++++++++++++++++++++++++++++++ github/github-accessors.go | 16 ++++++++++ 3 files changed, 123 insertions(+), 1 deletion(-) diff --git a/github/admin_orgs.go b/github/admin_orgs.go index f063831085b..448e51f631e 100644 --- a/github/admin_orgs.go +++ b/github/admin_orgs.go @@ -5,7 +5,10 @@ package github -import "context" +import ( + "context" + "fmt" +) // createOrgRequest is a subset of Organization and is used internally // by CreateOrg to pass only the known fields for the endpoint. @@ -41,3 +44,46 @@ func (s *AdminService) CreateOrg(ctx context.Context, org *Organization, admin s return o, resp, nil } + +// renameOrgRequest is a subset of Organization and is used internally +// by RenameOrg and RenameOrgByName to pass only the known fields for the endpoint. +type renameOrgRequest struct { + Login *string `json:"login,omitempty"` +} + +// RenameOrgResponse is the response given when renaming an Organization. +type RenameOrgResponse struct { + Message *string `json:"message,omitempty"` + URL *string `json:"url,omitempty"` +} + +// RenameOrg renames an organization in GitHub Enterprise. +// +// GitHub Enterprise API docs: https://developer.github.com/enterprise/v3/enterprise-admin/orgs/#rename-an-organization +func (s *AdminService) RenameOrg(ctx context.Context, org *Organization, newName string) (*RenameOrgResponse, *Response, error) { + return s.RenameOrgByName(ctx, *org.Login, newName) +} + +// RenameOrgByName renames an organization in GitHub Enterprise using its current name. +// +// GitHub Enterprise API docs: https://developer.github.com/enterprise/v3/enterprise-admin/orgs/#rename-an-organization +func (s *AdminService) RenameOrgByName(ctx context.Context, org, newName string) (*RenameOrgResponse, *Response, error) { + u := fmt.Sprintf("admin/organizations/%v", org) + + orgReq := &renameOrgRequest{ + Login: &newName, + } + + req, err := s.client.NewRequest("PATCH", u, orgReq) + if err != nil { + return nil, nil, err + } + + o := new(RenameOrgResponse) + resp, err := s.client.Do(ctx, req, o) + if err != nil { + return nil, resp, err + } + + return o, resp, nil +} diff --git a/github/admin_orgs_test.go b/github/admin_orgs_test.go index 6966a179c05..4e0d6e0fea5 100644 --- a/github/admin_orgs_test.go +++ b/github/admin_orgs_test.go @@ -45,3 +45,63 @@ func TestAdminOrgs_Create(t *testing.T) { t.Errorf("Admin.CreateOrg returned %+v, want %+v", org, want) } } + +func TestAdminOrgs_Rename(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + input := &Organization{ + Login: String("o"), + } + + mux.HandleFunc("/admin/organizations/o", func(w http.ResponseWriter, r *http.Request) { + v := new(renameOrgRequest) + json.NewDecoder(r.Body).Decode(v) + + testMethod(t, r, "PATCH") + want := &renameOrgRequest{Login: String("the-new-octocats")} + if !reflect.DeepEqual(v, want) { + t.Errorf("Request body = %+v, want %+v", v, want) + } + + fmt.Fprint(w, `{"message":"Job queued to rename organization. It may take a few minutes to complete.","url":"https:///api/v3/organizations/1"}`) + }) + + resp, _, err := client.Admin.RenameOrg(context.Background(), input, "the-new-octocats") + if err != nil { + t.Errorf("Admin.RenameOrg returned error: %v", err) + } + + want := &RenameOrgResponse{Message: String("Job queued to rename organization. It may take a few minutes to complete."), URL: String("https:///api/v3/organizations/1")} + if !reflect.DeepEqual(resp, want) { + t.Errorf("Admin.RenameOrg returned %+v, want %+v", resp, want) + } +} + +func TestAdminOrgs_RenameByName(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/admin/organizations/o", func(w http.ResponseWriter, r *http.Request) { + v := new(renameOrgRequest) + json.NewDecoder(r.Body).Decode(v) + + testMethod(t, r, "PATCH") + want := &renameOrgRequest{Login: String("the-new-octocats")} + if !reflect.DeepEqual(v, want) { + t.Errorf("Request body = %+v, want %+v", v, want) + } + + fmt.Fprint(w, `{"message":"Job queued to rename organization. It may take a few minutes to complete.","url":"https:///api/v3/organizations/1"}`) + }) + + resp, _, err := client.Admin.RenameOrgByName(context.Background(), "o", "the-new-octocats") + if err != nil { + t.Errorf("Admin.RenameOrg returned error: %v", err) + } + + want := &RenameOrgResponse{Message: String("Job queued to rename organization. It may take a few minutes to complete."), URL: String("https:///api/v3/organizations/1")} + if !reflect.DeepEqual(resp, want) { + t.Errorf("Admin.RenameOrg returned %+v, want %+v", resp, want) + } +} diff --git a/github/github-accessors.go b/github/github-accessors.go index 27e8b136caf..4141b9cd602 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -9996,6 +9996,22 @@ func (r *Rename) GetTo() string { return *r.To } +// GetMessage returns the Message field if it's non-nil, zero value otherwise. +func (r *RenameOrgResponse) GetMessage() string { + if r == nil || r.Message == nil { + return "" + } + return *r.Message +} + +// GetURL returns the URL field if it's non-nil, zero value otherwise. +func (r *RenameOrgResponse) GetURL() string { + if r == nil || r.URL == nil { + return "" + } + return *r.URL +} + // GetIncompleteResults returns the IncompleteResults field if it's non-nil, zero value otherwise. func (r *RepositoriesSearchResult) GetIncompleteResults() bool { if r == nil || r.IncompleteResults == nil { From 1513a77e0105e39218f28f8cfcb0ef1a73f38bdd Mon Sep 17 00:00:00 2001 From: angie pinilla Date: Thu, 9 Apr 2020 14:34:56 -0400 Subject: [PATCH 0160/1468] Update IdP team-sync list and create/update endpoints with ByID and BySlug (#1484) Fixes #1483. --- github/teams.go | 56 +++++++++++++++++--- github/teams_test.go | 121 +++++++++++++++++++++++++++++++++++++------ 2 files changed, 155 insertions(+), 22 deletions(-) diff --git a/github/teams.go b/github/teams.go index cfb814e7dbd..9ca449cdba1 100644 --- a/github/teams.go +++ b/github/teams.go @@ -765,11 +765,12 @@ func (s *TeamsService) ListIDPGroupsInOrganization(ctx context.Context, org stri return groups, resp, nil } -// ListIDPGroupsForTeam lists IDP groups connected to a team on GitHub. +// ListIDPGroupsForTeamByID lists IDP groups connected to a team on GitHub +// given organization and team IDs. // // GitHub API docs: https://developer.github.com/v3/teams/team_sync/#list-idp-groups-for-a-team -func (s *TeamsService) ListIDPGroupsForTeam(ctx context.Context, teamID string) (*IDPGroupList, *Response, error) { - u := fmt.Sprintf("teams/%v/team-sync/group-mappings", teamID) +func (s *TeamsService) ListIDPGroupsForTeamByID(ctx context.Context, orgID, teamID int64) (*IDPGroupList, *Response, error) { + u := fmt.Sprintf("organizations/%v/team/%v/team-sync/group-mappings", orgID, teamID) req, err := s.client.NewRequest("GET", u, nil) if err != nil { @@ -784,12 +785,53 @@ func (s *TeamsService) ListIDPGroupsForTeam(ctx context.Context, teamID string) return groups, resp, err } -// CreateOrUpdateIDPGroupConnections creates, updates, or removes a connection between a team -// and an IDP group. +// ListIDPGroupsForTeamBySlug lists IDP groups connected to a team on GitHub +// given organization name and team slug. +// +// GitHub API docs: https://developer.github.com/v3/teams/team_sync/#list-idp-groups-for-a-team +func (s *TeamsService) ListIDPGroupsForTeamBySlug(ctx context.Context, org, slug string) (*IDPGroupList, *Response, error) { + u := fmt.Sprintf("orgs/%v/teams/%v/team-sync/group-mappings", org, slug) + + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + + groups := new(IDPGroupList) + resp, err := s.client.Do(ctx, req, groups) + if err != nil { + return nil, resp, err + } + return groups, resp, err +} + +// CreateOrUpdateIDPGroupConnectionsByID creates, updates, or removes a connection +// between a team and an IDP group given organization and team IDs. +// +// GitHub API docs: https://developer.github.com/v3/teams/team_sync/#create-or-update-idp-group-connections +func (s *TeamsService) CreateOrUpdateIDPGroupConnectionsByID(ctx context.Context, orgID, teamID int64, opts IDPGroupList) (*IDPGroupList, *Response, error) { + u := fmt.Sprintf("organizations/%v/team/%v/team-sync/group-mappings", orgID, teamID) + + req, err := s.client.NewRequest("PATCH", u, opts) + if err != nil { + return nil, nil, err + } + + groups := new(IDPGroupList) + resp, err := s.client.Do(ctx, req, groups) + if err != nil { + return nil, resp, err + } + + return groups, resp, nil +} + +// CreateOrUpdateIDPGroupConnectionsBySlug creates, updates, or removes a connection +// between a team and an IDP group given organization name and team slug. // // GitHub API docs: https://developer.github.com/v3/teams/team_sync/#create-or-update-idp-group-connections -func (s *TeamsService) CreateOrUpdateIDPGroupConnections(ctx context.Context, teamID string, opts IDPGroupList) (*IDPGroupList, *Response, error) { - u := fmt.Sprintf("teams/%v/team-sync/group-mappings", teamID) +func (s *TeamsService) CreateOrUpdateIDPGroupConnectionsBySlug(ctx context.Context, org, slug string, opts IDPGroupList) (*IDPGroupList, *Response, error) { + u := fmt.Sprintf("orgs/%v/teams/%v/team-sync/group-mappings", org, slug) req, err := s.client.NewRequest("PATCH", u, opts) if err != nil { diff --git a/github/teams_test.go b/github/teams_test.go index 414ad78e7fc..304f93c3373 100644 --- a/github/teams_test.go +++ b/github/teams_test.go @@ -946,18 +946,18 @@ func TestTeamsService_ListIDPGroupsInOrganization(t *testing.T) { } } -func TestTeamsService_ListIDPGroupsForTeam(t *testing.T) { +func TestTeamsService_ListIDPGroupsForTeamByID(t *testing.T) { client, mux, _, teardown := setup() defer teardown() - mux.HandleFunc("/teams/1/team-sync/group-mappings", func(w http.ResponseWriter, r *http.Request) { + mux.HandleFunc("/organizations/1/team/1/team-sync/group-mappings", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") fmt.Fprint(w, `{"groups": [{"group_id": "1", "group_name": "n", "group_description": "d"}]}`) }) - groups, _, err := client.Teams.ListIDPGroupsForTeam(context.Background(), "1") + groups, _, err := client.Teams.ListIDPGroupsForTeamByID(context.Background(), 1, 1) if err != nil { - t.Errorf("Teams.ListIDPGroupsForTeam returned error: %v", err) + t.Errorf("Teams.ListIDPGroupsForTeamByID returned error: %v", err) } want := &IDPGroupList{ @@ -970,15 +970,81 @@ func TestTeamsService_ListIDPGroupsForTeam(t *testing.T) { }, } if !reflect.DeepEqual(groups, want) { - t.Errorf("Teams.ListIDPGroupsForTeam returned %+v. want %+v", groups, want) + t.Errorf("Teams.ListIDPGroupsForTeamByID returned %+v. want %+v", groups, want) } } -func TestTeamsService_CreateOrUpdateIDPGroupConnections(t *testing.T) { +func TestTeamsService_ListIDPGroupsForTeamBySlug(t *testing.T) { client, mux, _, teardown := setup() defer teardown() - mux.HandleFunc("/teams/1/team-sync/group-mappings", func(w http.ResponseWriter, r *http.Request) { + mux.HandleFunc("/orgs/o/teams/slug/team-sync/group-mappings", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + fmt.Fprint(w, `{"groups": [{"group_id": "1", "group_name": "n", "group_description": "d"}]}`) + }) + + groups, _, err := client.Teams.ListIDPGroupsForTeamBySlug(context.Background(), "o", "slug") + if err != nil { + t.Errorf("Teams.ListIDPGroupsForTeamBySlug returned error: %v", err) + } + + want := &IDPGroupList{ + Groups: []*IDPGroup{ + { + GroupID: String("1"), + GroupName: String("n"), + GroupDescription: String("d"), + }, + }, + } + if !reflect.DeepEqual(groups, want) { + t.Errorf("Teams.ListIDPGroupsForTeamBySlug returned %+v. want %+v", groups, want) + } +} + +func TestTeamsService_CreateOrUpdateIDPGroupConnectionsByID(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/organizations/1/team/1/team-sync/group-mappings", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "PATCH") + fmt.Fprint(w, `{"groups": [{"group_id": "1", "group_name": "n", "group_description": "d"}]}`) + }) + + input := IDPGroupList{ + Groups: []*IDPGroup{ + { + GroupID: String("1"), + GroupName: String("n"), + GroupDescription: String("d"), + }, + }, + } + + groups, _, err := client.Teams.CreateOrUpdateIDPGroupConnectionsByID(context.Background(), 1, 1, input) + if err != nil { + t.Errorf("Teams.CreateOrUpdateIDPGroupConnectionsByID returned error: %v", err) + } + + want := &IDPGroupList{ + Groups: []*IDPGroup{ + { + GroupID: String("1"), + GroupName: String("n"), + GroupDescription: String("d"), + }, + }, + } + if !reflect.DeepEqual(groups, want) { + t.Errorf("Teams.CreateOrUpdateIDPGroupConnectionsByID returned %+v. want %+v", groups, want) + } +} + +func TestTeamsService_CreateOrUpdateIDPGroupConnectionsBySlug(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/orgs/o/teams/slug/team-sync/group-mappings", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "PATCH") fmt.Fprint(w, `{"groups": [{"group_id": "1", "group_name": "n", "group_description": "d"}]}`) }) @@ -993,9 +1059,9 @@ func TestTeamsService_CreateOrUpdateIDPGroupConnections(t *testing.T) { }, } - groups, _, err := client.Teams.CreateOrUpdateIDPGroupConnections(context.Background(), "1", input) + groups, _, err := client.Teams.CreateOrUpdateIDPGroupConnectionsBySlug(context.Background(), "o", "slug", input) if err != nil { - t.Errorf("Teams.CreateOrUpdateIDPGroupConnections returned error: %v", err) + t.Errorf("Teams.CreateOrUpdateIDPGroupConnectionsBySlug returned error: %v", err) } want := &IDPGroupList{ @@ -1008,15 +1074,40 @@ func TestTeamsService_CreateOrUpdateIDPGroupConnections(t *testing.T) { }, } if !reflect.DeepEqual(groups, want) { - t.Errorf("Teams.CreateOrUpdateIDPGroupConnections returned %+v. want %+v", groups, want) + t.Errorf("Teams.CreateOrUpdateIDPGroupConnectionsBySlug returned %+v. want %+v", groups, want) + } +} +func TestTeamsService_CreateOrUpdateIDPGroupConnectionsByID_empty(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/organizations/1/team/1/team-sync/group-mappings", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "PATCH") + fmt.Fprint(w, `{"groups": []}`) + }) + + input := IDPGroupList{ + Groups: []*IDPGroup{}, + } + + groups, _, err := client.Teams.CreateOrUpdateIDPGroupConnectionsByID(context.Background(), 1, 1, input) + if err != nil { + t.Errorf("Teams.CreateOrUpdateIDPGroupConnectionsByID returned error: %v", err) + } + + want := &IDPGroupList{ + Groups: []*IDPGroup{}, + } + if !reflect.DeepEqual(groups, want) { + t.Errorf("Teams.CreateOrUpdateIDPGroupConnectionsByID returned %+v. want %+v", groups, want) } } -func TestTeamsService_CreateOrUpdateIDPGroupConnections_empty(t *testing.T) { +func TestTeamsService_CreateOrUpdateIDPGroupConnectionsBySlug_empty(t *testing.T) { client, mux, _, teardown := setup() defer teardown() - mux.HandleFunc("/teams/1/team-sync/group-mappings", func(w http.ResponseWriter, r *http.Request) { + mux.HandleFunc("/orgs/o/teams/slug/team-sync/group-mappings", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "PATCH") fmt.Fprint(w, `{"groups": []}`) }) @@ -1025,15 +1116,15 @@ func TestTeamsService_CreateOrUpdateIDPGroupConnections_empty(t *testing.T) { Groups: []*IDPGroup{}, } - groups, _, err := client.Teams.CreateOrUpdateIDPGroupConnections(context.Background(), "1", input) + groups, _, err := client.Teams.CreateOrUpdateIDPGroupConnectionsBySlug(context.Background(), "o", "slug", input) if err != nil { - t.Errorf("Teams.CreateOrUpdateIDPGroupConnections returned error: %v", err) + t.Errorf("Teams.CreateOrUpdateIDPGroupConnectionsBySlug returned error: %v", err) } want := &IDPGroupList{ Groups: []*IDPGroup{}, } if !reflect.DeepEqual(groups, want) { - t.Errorf("Teams.CreateOrUpdateIDPGroupConnections returned %+v. want %+v", groups, want) + t.Errorf("Teams.CreateOrUpdateIDPGroupConnectionsBySlug returned %+v. want %+v", groups, want) } } From 5c620050e324b9d019481fca72b5ec85030954e5 Mon Sep 17 00:00:00 2001 From: Weslei Juan Moser Pereira Date: Thu, 9 Apr 2020 11:39:36 -0700 Subject: [PATCH 0161/1468] Set mediaTypeRepositoryVisibilityPreview in Repository.Get (#1486) Fixes #1481. --- github/repos.go | 7 ++++++- github/repos_test.go | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/github/repos.go b/github/repos.go index 41249226d1a..c30d5955ee3 100644 --- a/github/repos.go +++ b/github/repos.go @@ -414,7 +414,12 @@ func (s *RepositoriesService) Get(ctx context.Context, owner, repo string) (*Rep // TODO: remove custom Accept header when the license support fully launches // https://developer.github.com/v3/licenses/#get-a-repositorys-license - acceptHeaders := []string{mediaTypeCodesOfConductPreview, mediaTypeTopicsPreview, mediaTypeRepositoryTemplatePreview} + acceptHeaders := []string{ + mediaTypeCodesOfConductPreview, + mediaTypeTopicsPreview, + mediaTypeRepositoryTemplatePreview, + mediaTypeRepositoryVisibilityPreview, + } req.Header.Set("Accept", strings.Join(acceptHeaders, ", ")) repository := new(Repository) diff --git a/github/repos_test.go b/github/repos_test.go index 889a8fc8ddf..56a56b6331f 100644 --- a/github/repos_test.go +++ b/github/repos_test.go @@ -405,7 +405,7 @@ func TestRepositoriesService_Get(t *testing.T) { client, mux, _, teardown := setup() defer teardown() - wantAcceptHeaders := []string{mediaTypeCodesOfConductPreview, mediaTypeTopicsPreview, mediaTypeRepositoryTemplatePreview} + wantAcceptHeaders := []string{mediaTypeCodesOfConductPreview, mediaTypeTopicsPreview, mediaTypeRepositoryTemplatePreview, mediaTypeRepositoryVisibilityPreview} mux.HandleFunc("/repos/o/r", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", ")) From 8256b7258d24f77a857f9fe525f9b815995c4b6e Mon Sep 17 00:00:00 2001 From: Glenn Lewis <6598971+gmlewis@users.noreply.github.com> Date: Thu, 9 Apr 2020 21:21:44 -0400 Subject: [PATCH 0162/1468] Fix receivers and other breaking changes (#1487) --- github/gitignore.go | 4 ++-- github/reactions.go | 10 +++++----- github/repos_keys.go | 20 ------------------- github/repos_keys_test.go | 37 ----------------------------------- github/users_projects.go | 2 +- github/users_projects_test.go | 2 +- 6 files changed, 9 insertions(+), 66 deletions(-) diff --git a/github/gitignore.go b/github/gitignore.go index 2f691bc323e..dc2eab757ae 100644 --- a/github/gitignore.go +++ b/github/gitignore.go @@ -29,7 +29,7 @@ func (g Gitignore) String() string { // List all available Gitignore templates. // // GitHub API docs: https://developer.github.com/v3/gitignore/#listing-available-templates -func (s GitignoresService) List(ctx context.Context) ([]string, *Response, error) { +func (s *GitignoresService) List(ctx context.Context) ([]string, *Response, error) { req, err := s.client.NewRequest("GET", "gitignore/templates", nil) if err != nil { return nil, nil, err @@ -47,7 +47,7 @@ func (s GitignoresService) List(ctx context.Context) ([]string, *Response, error // Get a Gitignore by name. // // GitHub API docs: https://developer.github.com/v3/gitignore/#get-a-single-template -func (s GitignoresService) Get(ctx context.Context, name string) (*Gitignore, *Response, error) { +func (s *GitignoresService) Get(ctx context.Context, name string) (*Gitignore, *Response, error) { u := fmt.Sprintf("gitignore/templates/%v", name) req, err := s.client.NewRequest("GET", u, nil) if err != nil { diff --git a/github/reactions.go b/github/reactions.go index 1602032e221..7dd8b7c9db3 100644 --- a/github/reactions.go +++ b/github/reactions.go @@ -89,7 +89,7 @@ func (s *ReactionsService) ListCommentReactions(ctx context.Context, owner, repo // The content should have one of the following values: "+1", "-1", "laugh", "confused", "heart", "hooray". // // GitHub API docs: https://developer.github.com/v3/reactions/#create-reaction-for-a-commit-comment -func (s ReactionsService) CreateCommentReaction(ctx context.Context, owner, repo string, id int64, content string) (*Reaction, *Response, error) { +func (s *ReactionsService) CreateCommentReaction(ctx context.Context, owner, repo string, id int64, content string) (*Reaction, *Response, error) { u := fmt.Sprintf("repos/%v/%v/comments/%v/reactions", owner, repo, id) body := &Reaction{Content: String(content)} @@ -161,7 +161,7 @@ func (s *ReactionsService) ListIssueReactions(ctx context.Context, owner, repo s // The content should have one of the following values: "+1", "-1", "laugh", "confused", "heart", "hooray". // // GitHub API docs: https://developer.github.com/v3/reactions/#create-reaction-for-an-issue -func (s ReactionsService) CreateIssueReaction(ctx context.Context, owner, repo string, number int, content string) (*Reaction, *Response, error) { +func (s *ReactionsService) CreateIssueReaction(ctx context.Context, owner, repo string, number int, content string) (*Reaction, *Response, error) { u := fmt.Sprintf("repos/%v/%v/issues/%v/reactions", owner, repo, number) body := &Reaction{Content: String(content)} @@ -233,7 +233,7 @@ func (s *ReactionsService) ListIssueCommentReactions(ctx context.Context, owner, // The content should have one of the following values: "+1", "-1", "laugh", "confused", "heart", "hooray". // // GitHub API docs: https://developer.github.com/v3/reactions/#create-reaction-for-an-issue-comment -func (s ReactionsService) CreateIssueCommentReaction(ctx context.Context, owner, repo string, id int64, content string) (*Reaction, *Response, error) { +func (s *ReactionsService) CreateIssueCommentReaction(ctx context.Context, owner, repo string, id int64, content string) (*Reaction, *Response, error) { u := fmt.Sprintf("repos/%v/%v/issues/comments/%v/reactions", owner, repo, id) body := &Reaction{Content: String(content)} @@ -305,7 +305,7 @@ func (s *ReactionsService) ListPullRequestCommentReactions(ctx context.Context, // The content should have one of the following values: "+1", "-1", "laugh", "confused", "heart", "hooray". // // GitHub API docs: https://developer.github.com/v3/reactions/#create-reaction-for-an-issue-comment -func (s ReactionsService) CreatePullRequestCommentReaction(ctx context.Context, owner, repo string, id int64, content string) (*Reaction, *Response, error) { +func (s *ReactionsService) CreatePullRequestCommentReaction(ctx context.Context, owner, repo string, id int64, content string) (*Reaction, *Response, error) { u := fmt.Sprintf("repos/%v/%v/pulls/comments/%v/reactions", owner, repo, id) body := &Reaction{Content: String(content)} @@ -479,7 +479,7 @@ func (s *ReactionsService) DeleteTeamDiscussionCommentReactionByOrgIDAndTeamID(c return s.deleteReaction(ctx, url) } -func (s ReactionsService) deleteReaction(ctx context.Context, url string) (*Response, error) { +func (s *ReactionsService) deleteReaction(ctx context.Context, url string) (*Response, error) { req, err := s.client.NewRequest(http.MethodDelete, url, nil) if err != nil { return nil, err diff --git a/github/repos_keys.go b/github/repos_keys.go index 64ee7422a07..11b3b6f6840 100644 --- a/github/repos_keys.go +++ b/github/repos_keys.go @@ -76,26 +76,6 @@ func (s *RepositoriesService) CreateKey(ctx context.Context, owner string, repo return k, resp, nil } -// EditKey edits a deploy key. -// -// GitHub API docs: https://developer.github.com/v3/repos/keys/#edit -func (s *RepositoriesService) EditKey(ctx context.Context, owner string, repo string, id int64, key *Key) (*Key, *Response, error) { - u := fmt.Sprintf("repos/%v/%v/keys/%v", owner, repo, id) - - req, err := s.client.NewRequest("PATCH", u, key) - if err != nil { - return nil, nil, err - } - - k := new(Key) - resp, err := s.client.Do(ctx, req, k) - if err != nil { - return nil, resp, err - } - - return k, resp, nil -} - // DeleteKey deletes a deploy key. // // GitHub API docs: https://developer.github.com/v3/repos/keys/#delete diff --git a/github/repos_keys_test.go b/github/repos_keys_test.go index 75a17356edd..7a9a4b09f7b 100644 --- a/github/repos_keys_test.go +++ b/github/repos_keys_test.go @@ -109,43 +109,6 @@ func TestRepositoriesService_CreateKey_invalidOwner(t *testing.T) { testURLParseError(t, err) } -func TestRepositoriesService_EditKey(t *testing.T) { - client, mux, _, teardown := setup() - defer teardown() - - input := &Key{Key: String("k"), Title: String("t")} - - mux.HandleFunc("/repos/o/r/keys/1", func(w http.ResponseWriter, r *http.Request) { - v := new(Key) - json.NewDecoder(r.Body).Decode(v) - - testMethod(t, r, "PATCH") - if !reflect.DeepEqual(v, input) { - t.Errorf("Request body = %+v, want %+v", v, input) - } - - fmt.Fprint(w, `{"id":1}`) - }) - - key, _, err := client.Repositories.EditKey(context.Background(), "o", "r", 1, input) - if err != nil { - t.Errorf("Repositories.EditKey returned error: %v", err) - } - - want := &Key{ID: Int64(1)} - if !reflect.DeepEqual(key, want) { - t.Errorf("Repositories.EditKey returned %+v, want %+v", key, want) - } -} - -func TestRepositoriesService_EditKey_invalidOwner(t *testing.T) { - client, _, _, teardown := setup() - defer teardown() - - _, _, err := client.Repositories.EditKey(context.Background(), "%", "%", 1, nil) - testURLParseError(t, err) -} - func TestRepositoriesService_DeleteKey(t *testing.T) { client, mux, _, teardown := setup() defer teardown() diff --git a/github/users_projects.go b/github/users_projects.go index 64e85a03226..1357055040c 100644 --- a/github/users_projects.go +++ b/github/users_projects.go @@ -49,7 +49,7 @@ type CreateUserProjectOptions struct { // // GitHub API docs: https://developer.github.com/v3/projects/#create-a-user-project func (s *UsersService) CreateProject(ctx context.Context, opts *CreateUserProjectOptions) (*Project, *Response, error) { - u := "users/projects" + u := "user/projects" req, err := s.client.NewRequest("POST", u, opts) if err != nil { return nil, nil, err diff --git a/github/users_projects_test.go b/github/users_projects_test.go index b186fbf07f7..7e3e5cbef8b 100644 --- a/github/users_projects_test.go +++ b/github/users_projects_test.go @@ -43,7 +43,7 @@ func TestUsersService_CreateProject(t *testing.T) { input := &CreateUserProjectOptions{Name: "Project Name", Body: String("Project body.")} - mux.HandleFunc("/users/projects", func(w http.ResponseWriter, r *http.Request) { + mux.HandleFunc("/user/projects", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "POST") testHeader(t, r, "Accept", mediaTypeProjectsPreview) From 259aa56b9e3f43b924520fb5b5bc0784a901f90d Mon Sep 17 00:00:00 2001 From: Glenn Lewis <6598971+gmlewis@users.noreply.github.com> Date: Thu, 9 Apr 2020 21:28:23 -0400 Subject: [PATCH 0163/1468] Create tool to update and validate GitHub v3 API URLs (#1477) Fixes #1476. --- .gitignore | 1 + github/actions_workflow_jobs.go | 2 +- github/activity_events.go | 12 +- github/activity_notifications.go | 10 +- github/activity_star.go | 9 +- github/activity_watching.go | 3 +- github/apps.go | 7 +- github/apps_installation.go | 4 +- github/apps_manifest.go | 2 +- github/apps_marketplace.go | 3 +- github/checks.go | 14 +- github/gists.go | 11 +- github/issues.go | 9 +- github/issues_comments.go | 1 + github/migrations.go | 12 +- github/migrations_source_import.go | 16 +- github/migrations_user.go | 2 +- github/orgs.go | 3 +- github/orgs_members.go | 8 +- github/pulls.go | 4 +- github/pulls_comments.go | 3 +- github/reactions.go | 12 +- github/repos.go | 22 +- github/repos_collaborators.go | 4 +- github/repos_commits.go | 6 +- github/repos_community_health.go | 2 +- github/repos_contents.go | 4 +- github/repos_hooks.go | 2 +- github/repos_keys.go | 8 +- github/repos_pages.go | 4 +- github/repos_stats.go | 10 +- github/repos_traffic.go | 2 +- github/search.go | 2 +- github/teams.go | 8 +- github/users.go | 2 +- github/users_followers.go | 3 + github/users_gpg_keys.go | 1 + github/users_keys.go | 1 + update-urls/activity-events_test.go | 1441 ++++++++++ update-urls/go.mod | 5 + update-urls/go.sum | 2 + update-urls/main.go | 1165 ++++++++ update-urls/main_test.go | 563 ++++ update-urls/reactions_test.go | 4143 +++++++++++++++++++++++++++ 44 files changed, 7445 insertions(+), 103 deletions(-) create mode 100644 update-urls/activity-events_test.go create mode 100644 update-urls/go.mod create mode 100644 update-urls/go.sum create mode 100644 update-urls/main.go create mode 100644 update-urls/main_test.go create mode 100644 update-urls/reactions_test.go diff --git a/.gitignore b/.gitignore index 3515c4b9740..d99e2ea721c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ +*.sh *.test coverage.out diff --git a/github/actions_workflow_jobs.go b/github/actions_workflow_jobs.go index 8cb7c6aa876..0838ce48d74 100644 --- a/github/actions_workflow_jobs.go +++ b/github/actions_workflow_jobs.go @@ -84,7 +84,7 @@ func (s *ActionsService) ListWorkflowJobs(ctx context.Context, owner, repo strin // GetWorkflowJobByID gets a specific job in a workflow run by ID. // -// GitHub API docs: https://developer.github.com/v3/actions/workflow_jobs/#list-jobs-for-a-workflow-run +// GitHub API docs: https://developer.github.com/v3/actions/workflow_jobs/#get-a-workflow-job func (s *ActionsService) GetWorkflowJobByID(ctx context.Context, owner, repo string, jobID int64) (*WorkflowJob, *Response, error) { u := fmt.Sprintf("repos/%v/%v/actions/jobs/%v", owner, repo, jobID) diff --git a/github/activity_events.go b/github/activity_events.go index 115bcc97d3a..d45b26ddcd8 100644 --- a/github/activity_events.go +++ b/github/activity_events.go @@ -59,7 +59,7 @@ func (s *ActivityService) ListRepositoryEvents(ctx context.Context, owner, repo // ListIssueEventsForRepository lists issue events for a repository. // -// GitHub API docs: https://developer.github.com/v3/activity/events/#list-issue-events-for-a-repository +// GitHub API docs: https://developer.github.com/v3/issues/events/#list-events-for-a-repository func (s *ActivityService) ListIssueEventsForRepository(ctx context.Context, owner, repo string, opts *ListOptions) ([]*IssueEvent, *Response, error) { u := fmt.Sprintf("repos/%v/%v/issues/events", owner, repo) u, err := addOptions(u, opts) @@ -107,7 +107,7 @@ func (s *ActivityService) ListEventsForRepoNetwork(ctx context.Context, owner, r // ListEventsForOrganization lists public events for an organization. // -// GitHub API docs: https://developer.github.com/v3/activity/events/#list-public-events-for-an-organization +// GitHub API docs: https://developer.github.com/v3/activity/events/#list-public-organization-events func (s *ActivityService) ListEventsForOrganization(ctx context.Context, org string, opts *ListOptions) ([]*Event, *Response, error) { u := fmt.Sprintf("orgs/%v/events", org) u, err := addOptions(u, opts) @@ -132,7 +132,8 @@ func (s *ActivityService) ListEventsForOrganization(ctx context.Context, org str // ListEventsPerformedByUser lists the events performed by a user. If publicOnly is // true, only public events will be returned. // -// GitHub API docs: https://developer.github.com/v3/activity/events/#list-events-performed-by-a-user +// GitHub API docs: https://developer.github.com/v3/activity/events/#list-events-for-the-authenticated-user +// GitHub API docs: https://developer.github.com/v3/activity/events/#list-public-events-for-a-user func (s *ActivityService) ListEventsPerformedByUser(ctx context.Context, user string, publicOnly bool, opts *ListOptions) ([]*Event, *Response, error) { var u string if publicOnly { @@ -162,7 +163,8 @@ func (s *ActivityService) ListEventsPerformedByUser(ctx context.Context, user st // ListEventsReceivedByUser lists the events received by a user. If publicOnly is // true, only public events will be returned. // -// GitHub API docs: https://developer.github.com/v3/activity/events/#list-events-that-a-user-has-received +// GitHub API docs: https://developer.github.com/v3/activity/events/#list-events-received-by-the-authenticated-user +// GitHub API docs: https://developer.github.com/v3/activity/events/#list-public-events-received-by-a-user func (s *ActivityService) ListEventsReceivedByUser(ctx context.Context, user string, publicOnly bool, opts *ListOptions) ([]*Event, *Response, error) { var u string if publicOnly { @@ -192,7 +194,7 @@ func (s *ActivityService) ListEventsReceivedByUser(ctx context.Context, user str // ListUserEventsForOrganization provides the user’s organization dashboard. You // must be authenticated as the user to view this. // -// GitHub API docs: https://developer.github.com/v3/activity/events/#list-events-for-an-organization +// GitHub API docs: https://developer.github.com/v3/activity/events/#list-organization-events-for-the-authenticated-user func (s *ActivityService) ListUserEventsForOrganization(ctx context.Context, org, user string, opts *ListOptions) ([]*Event, *Response, error) { u := fmt.Sprintf("users/%v/events/orgs/%v", user, org) u, err := addOptions(u, opts) diff --git a/github/activity_notifications.go b/github/activity_notifications.go index 983da6f82f1..9c19922bb30 100644 --- a/github/activity_notifications.go +++ b/github/activity_notifications.go @@ -49,7 +49,7 @@ type NotificationListOptions struct { // ListNotifications lists all notifications for the authenticated user. // -// GitHub API docs: https://developer.github.com/v3/activity/notifications/#list-your-notifications +// GitHub API docs: https://developer.github.com/v3/activity/notifications/#list-notifications-for-the-authenticated-user func (s *ActivityService) ListNotifications(ctx context.Context, opts *NotificationListOptions) ([]*Notification, *Response, error) { u := fmt.Sprintf("notifications") u, err := addOptions(u, opts) @@ -74,7 +74,7 @@ func (s *ActivityService) ListNotifications(ctx context.Context, opts *Notificat // ListRepositoryNotifications lists all notifications in a given repository // for the authenticated user. // -// GitHub API docs: https://developer.github.com/v3/activity/notifications/#list-your-notifications-in-a-repository +// GitHub API docs: https://developer.github.com/v3/activity/notifications/#list-repository-notifications-for-the-authenticated-user func (s *ActivityService) ListRepositoryNotifications(ctx context.Context, owner, repo string, opts *NotificationListOptions) ([]*Notification, *Response, error) { u := fmt.Sprintf("repos/%v/%v/notifications", owner, repo) u, err := addOptions(u, opts) @@ -118,7 +118,7 @@ func (s *ActivityService) MarkNotificationsRead(ctx context.Context, lastRead ti // MarkRepositoryNotificationsRead marks all notifications up to lastRead in // the specified repository as read. // -// GitHub API docs: https://developer.github.com/v3/activity/notifications/#mark-notifications-as-read-in-a-repository +// GitHub API docs: https://developer.github.com/v3/activity/notifications/#mark-repository-notifications-as-read func (s *ActivityService) MarkRepositoryNotificationsRead(ctx context.Context, owner, repo string, lastRead time.Time) (*Response, error) { opts := &markReadOptions{ LastReadAt: lastRead, @@ -134,7 +134,7 @@ func (s *ActivityService) MarkRepositoryNotificationsRead(ctx context.Context, o // GetThread gets the specified notification thread. // -// GitHub API docs: https://developer.github.com/v3/activity/notifications/#view-a-single-thread +// GitHub API docs: https://developer.github.com/v3/activity/notifications/#get-a-thread func (s *ActivityService) GetThread(ctx context.Context, id string) (*Notification, *Response, error) { u := fmt.Sprintf("notifications/threads/%v", id) @@ -169,7 +169,7 @@ func (s *ActivityService) MarkThreadRead(ctx context.Context, id string) (*Respo // GetThreadSubscription checks to see if the authenticated user is subscribed // to a thread. // -// GitHub API docs: https://developer.github.com/v3/activity/notifications/#get-a-thread-subscription +// GitHub API docs: https://developer.github.com/v3/activity/notifications/#get-a-thread-subscription-for-the-authenticated-user func (s *ActivityService) GetThreadSubscription(ctx context.Context, id string) (*Subscription, *Response, error) { u := fmt.Sprintf("notifications/threads/%v/subscription", id) diff --git a/github/activity_star.go b/github/activity_star.go index 1e9850f9e13..158f395210a 100644 --- a/github/activity_star.go +++ b/github/activity_star.go @@ -67,7 +67,8 @@ type ActivityListStarredOptions struct { // ListStarred lists all the repos starred by a user. Passing the empty string // will list the starred repositories for the authenticated user. // -// GitHub API docs: https://developer.github.com/v3/activity/starring/#list-repositories-being-starred +// GitHub API docs: https://developer.github.com/v3/activity/starring/#list-repositories-starred-by-a-user +// GitHub API docs: https://developer.github.com/v3/activity/starring/#list-repositories-starred-by-the-authenticated-user func (s *ActivityService) ListStarred(ctx context.Context, user string, opts *ActivityListStarredOptions) ([]*StarredRepository, *Response, error) { var u string if user != "" { @@ -100,7 +101,7 @@ func (s *ActivityService) ListStarred(ctx context.Context, user string, opts *Ac // IsStarred checks if a repository is starred by authenticated user. // -// GitHub API docs: https://developer.github.com/v3/activity/starring/#check-if-you-are-starring-a-repository +// GitHub API docs: https://developer.github.com/v3/activity/starring/#check-if-a-repository-is-starred-by-the-authenticated-user func (s *ActivityService) IsStarred(ctx context.Context, owner, repo string) (bool, *Response, error) { u := fmt.Sprintf("user/starred/%v/%v", owner, repo) req, err := s.client.NewRequest("GET", u, nil) @@ -114,7 +115,7 @@ func (s *ActivityService) IsStarred(ctx context.Context, owner, repo string) (bo // Star a repository as the authenticated user. // -// GitHub API docs: https://developer.github.com/v3/activity/starring/#star-a-repository +// GitHub API docs: https://developer.github.com/v3/activity/starring/#star-a-repository-for-the-authenticated-user func (s *ActivityService) Star(ctx context.Context, owner, repo string) (*Response, error) { u := fmt.Sprintf("user/starred/%v/%v", owner, repo) req, err := s.client.NewRequest("PUT", u, nil) @@ -126,7 +127,7 @@ func (s *ActivityService) Star(ctx context.Context, owner, repo string) (*Respon // Unstar a repository as the authenticated user. // -// GitHub API docs: https://developer.github.com/v3/activity/starring/#unstar-a-repository +// GitHub API docs: https://developer.github.com/v3/activity/starring/#unstar-a-repository-for-the-authenticated-user func (s *ActivityService) Unstar(ctx context.Context, owner, repo string) (*Response, error) { u := fmt.Sprintf("user/starred/%v/%v", owner, repo) req, err := s.client.NewRequest("DELETE", u, nil) diff --git a/github/activity_watching.go b/github/activity_watching.go index 608647a6ce5..0265a08d0d9 100644 --- a/github/activity_watching.go +++ b/github/activity_watching.go @@ -52,7 +52,8 @@ func (s *ActivityService) ListWatchers(ctx context.Context, owner, repo string, // ListWatched lists the repositories the specified user is watching. Passing // the empty string will fetch watched repos for the authenticated user. // -// GitHub API docs: https://developer.github.com/v3/activity/watching/#list-repositories-being-watched +// GitHub API docs: https://developer.github.com/v3/activity/watching/#list-repositories-watched-by-a-user +// GitHub API docs: https://developer.github.com/v3/activity/watching/#list-repositories-watched-by-the-authenticated-user func (s *ActivityService) ListWatched(ctx context.Context, user string, opts *ListOptions) ([]*Repository, *Response, error) { var u string if user != "" { diff --git a/github/apps.go b/github/apps.go index 75d9177fa9a..c0e8c9a0bfe 100644 --- a/github/apps.go +++ b/github/apps.go @@ -124,6 +124,7 @@ func (i Installation) String() string { // (e.g., https://github.com/settings/apps/:app_slug). // // GitHub API docs: https://developer.github.com/v3/apps/#get-a-single-github-app +// GitHub API docs: https://developer.github.com/v3/apps/#get-the-authenticated-github-app func (s *AppsService) Get(ctx context.Context, appSlug string) (*App, *Response, error) { var u string if appSlug != "" { @@ -177,14 +178,14 @@ func (s *AppsService) ListInstallations(ctx context.Context, opts *ListOptions) // GetInstallation returns the specified installation. // -// GitHub API docs: https://developer.github.com/v3/apps/#get-a-single-installation +// GitHub API docs: https://developer.github.com/v3/apps/#get-an-installation func (s *AppsService) GetInstallation(ctx context.Context, id int64) (*Installation, *Response, error) { return s.getInstallation(ctx, fmt.Sprintf("app/installations/%v", id)) } // ListUserInstallations lists installations that are accessible to the authenticated user. // -// GitHub API docs: https://developer.github.com/v3/apps/#list-installations-for-user +// GitHub API docs: https://developer.github.com/v3/apps/installations/#list-installations-for-a-user func (s *AppsService) ListUserInstallations(ctx context.Context, opts *ListOptions) ([]*Installation, *Response, error) { u, err := addOptions("user/installations", opts) if err != nil { @@ -235,7 +236,7 @@ func (s *AppsService) CreateInstallationToken(ctx context.Context, id int64, opt // CreateAttachment creates a new attachment on user comment containing a url. // -// GitHub API docs: https://developer.github.com/v3/apps/#create-a-content-attachment +// GitHub API docs: https://developer.github.com/v3/apps/installations/#create-a-content-attachment func (s *AppsService) CreateAttachment(ctx context.Context, contentReferenceID int64, title, body string) (*Attachment, *Response, error) { u := fmt.Sprintf("content_references/%v/attachments", contentReferenceID) payload := &Attachment{Title: String(title), Body: String(body)} diff --git a/github/apps_installation.go b/github/apps_installation.go index 59a90c15a99..2f7664cfbac 100644 --- a/github/apps_installation.go +++ b/github/apps_installation.go @@ -90,7 +90,7 @@ func (s *AppsService) AddRepository(ctx context.Context, instID, repoID int64) ( // RemoveRepository removes a single repository from an installation. // -// GitHub docs: https://developer.github.com/v3/apps/installations/#remove-repository-from-installation +// GitHub API docs: https://developer.github.com/v3/apps/installations/#remove-repository-from-installation func (s *AppsService) RemoveRepository(ctx context.Context, instID, repoID int64) (*Response, error) { u := fmt.Sprintf("user/installations/%v/repositories/%v", instID, repoID) req, err := s.client.NewRequest("DELETE", u, nil) @@ -104,7 +104,7 @@ func (s *AppsService) RemoveRepository(ctx context.Context, instID, repoID int64 // RevokeInstallationToken revokes an installation token. // -// GitHub docs: https://developer.github.com/v3/apps/installations/#revoke-an-installation-token +// GitHub API docs: https://developer.github.com/v3/apps/installations/#revoke-an-installation-token func (s *AppsService) RevokeInstallationToken(ctx context.Context) (*Response, error) { u := "installation/token" req, err := s.client.NewRequest("DELETE", u, nil) diff --git a/github/apps_manifest.go b/github/apps_manifest.go index 8d6ab3c8c45..9db76a30457 100644 --- a/github/apps_manifest.go +++ b/github/apps_manifest.go @@ -34,7 +34,7 @@ type AppConfig struct { // CompleteAppManifest completes the App manifest handshake flow for the given // code. // -// GitHub API docs: https://developer.github.com/apps/building-github-apps/creating-github-apps-from-a-manifest/#3-you-exchange-the-temporary-code-to-retrieve-the-app-configuration +// GitHub API docs: https://developer.github.com/v3/apps/#create-a-github-app-from-a-manifest func (s *AppsService) CompleteAppManifest(ctx context.Context, code string) (*AppConfig, *Response, error) { u := fmt.Sprintf("app-manifests/%s/conversions", code) req, err := s.client.NewRequest("POST", u, nil) diff --git a/github/apps_marketplace.go b/github/apps_marketplace.go index 053d451dc60..9026633e7aa 100644 --- a/github/apps_marketplace.go +++ b/github/apps_marketplace.go @@ -150,7 +150,8 @@ func (s *MarketplaceService) ListPlanAccountsForAccount(ctx context.Context, acc // ListMarketplacePurchasesForUser lists all GitHub marketplace purchases made by a user. // -// GitHub API docs: https://developer.github.com/v3/apps/marketplace/#get-a-users-marketplace-purchases +// GitHub API docs: https://developer.github.com/v3/apps/marketplace/#list-subscriptions-for-the-authenticated-user +// GitHub API docs: https://developer.github.com/v3/apps/marketplace/#list-subscriptions-for-the-authenticated-user-stubbed func (s *MarketplaceService) ListMarketplacePurchasesForUser(ctx context.Context, opts *ListOptions) ([]*MarketplacePurchase, *Response, error) { uri := "user/marketplace_purchases" if s.Stubbed { diff --git a/github/checks.go b/github/checks.go index 67b7e770217..8d08cb39fbc 100644 --- a/github/checks.go +++ b/github/checks.go @@ -96,7 +96,7 @@ func (c CheckSuite) String() string { // GetCheckRun gets a check-run for a repository. // -// GitHub API docs: https://developer.github.com/v3/checks/runs/#get-a-single-check-run +// GitHub API docs: https://developer.github.com/v3/checks/runs/#get-a-check-run func (s *ChecksService) GetCheckRun(ctx context.Context, owner, repo string, checkRunID int64) (*CheckRun, *Response, error) { u := fmt.Sprintf("repos/%v/%v/check-runs/%v", owner, repo, checkRunID) req, err := s.client.NewRequest("GET", u, nil) @@ -117,7 +117,7 @@ func (s *ChecksService) GetCheckRun(ctx context.Context, owner, repo string, che // GetCheckSuite gets a single check suite. // -// GitHub API docs: https://developer.github.com/v3/checks/suites/#get-a-single-check-suite +// GitHub API docs: https://developer.github.com/v3/checks/suites/#get-a-check-suite func (s *ChecksService) GetCheckSuite(ctx context.Context, owner, repo string, checkSuiteID int64) (*CheckSuite, *Response, error) { u := fmt.Sprintf("repos/%v/%v/check-suites/%v", owner, repo, checkSuiteID) req, err := s.client.NewRequest("GET", u, nil) @@ -214,7 +214,7 @@ func (s *ChecksService) UpdateCheckRun(ctx context.Context, owner, repo string, // ListCheckRunAnnotations lists the annotations for a check run. // -// GitHub API docs: https://developer.github.com/v3/checks/runs/#list-annotations-for-a-check-run +// GitHub API docs: https://developer.github.com/v3/checks/runs/#list-check-run-annotations func (s *ChecksService) ListCheckRunAnnotations(ctx context.Context, owner, repo string, checkRunID int64, opts *ListOptions) ([]*CheckRunAnnotation, *Response, error) { u := fmt.Sprintf("repos/%v/%v/check-runs/%v/annotations", owner, repo, checkRunID) u, err := addOptions(u, opts) @@ -255,7 +255,7 @@ type ListCheckRunsResults struct { // ListCheckRunsForRef lists check runs for a specific ref. // -// GitHub API docs: https://developer.github.com/v3/checks/runs/#list-check-runs-for-a-specific-ref +// GitHub API docs: https://developer.github.com/v3/checks/runs/#list-check-runs-for-a-git-reference func (s *ChecksService) ListCheckRunsForRef(ctx context.Context, owner, repo, ref string, opts *ListCheckRunsOptions) (*ListCheckRunsResults, *Response, error) { u := fmt.Sprintf("repos/%v/%v/commits/%v/check-runs", owner, repo, refURLEscape(ref)) u, err := addOptions(u, opts) @@ -321,7 +321,7 @@ type ListCheckSuiteResults struct { // ListCheckSuitesForRef lists check suite for a specific ref. // -// GitHub API docs: https://developer.github.com/v3/checks/suites/#list-check-suites-for-a-specific-ref +// GitHub API docs: https://developer.github.com/v3/checks/suites/#list-check-suites-for-a-git-reference func (s *ChecksService) ListCheckSuitesForRef(ctx context.Context, owner, repo, ref string, opts *ListCheckSuiteOptions) (*ListCheckSuiteResults, *Response, error) { u := fmt.Sprintf("repos/%v/%v/commits/%v/check-suites", owner, repo, refURLEscape(ref)) u, err := addOptions(u, opts) @@ -369,7 +369,7 @@ type PreferenceList struct { // SetCheckSuitePreferences changes the default automatic flow when creating check suites. // -// GitHub API docs: https://developer.github.com/v3/checks/suites/#set-preferences-for-check-suites-on-a-repository +// GitHub API docs: https://developer.github.com/v3/checks/suites/#update-repository-preferences-for-check-suites func (s *ChecksService) SetCheckSuitePreferences(ctx context.Context, owner, repo string, opts CheckSuitePreferenceOptions) (*CheckSuitePreferenceResults, *Response, error) { u := fmt.Sprintf("repos/%v/%v/check-suites/preferences", owner, repo) req, err := s.client.NewRequest("PATCH", u, opts) @@ -417,7 +417,7 @@ func (s *ChecksService) CreateCheckSuite(ctx context.Context, owner, repo string // ReRequestCheckSuite triggers GitHub to rerequest an existing check suite, without pushing new code to a repository. // -// GitHub API docs: https://developer.github.com/v3/checks/suites/#rerequest-check-suite +// GitHub API docs: https://developer.github.com/v3/checks/suites/#rerequest-a-check-suite func (s *ChecksService) ReRequestCheckSuite(ctx context.Context, owner, repo string, checkSuiteID int64) (*Response, error) { u := fmt.Sprintf("repos/%v/%v/check-suites/%v/rerequest", owner, repo, checkSuiteID) diff --git a/github/gists.go b/github/gists.go index 0f326055421..026b5d15ee1 100644 --- a/github/gists.go +++ b/github/gists.go @@ -96,7 +96,8 @@ type GistListOptions struct { // is authenticated, it will returns all gists for the authenticated // user. // -// GitHub API docs: https://developer.github.com/v3/gists/#list-gists +// GitHub API docs: https://developer.github.com/v3/gists/#list-gists-for-a-user +// GitHub API docs: https://developer.github.com/v3/gists/#list-gists-for-the-authenticated-user func (s *GistsService) List(ctx context.Context, user string, opts *GistListOptions) ([]*Gist, *Response, error) { var u string if user != "" { @@ -125,7 +126,7 @@ func (s *GistsService) List(ctx context.Context, user string, opts *GistListOpti // ListAll lists all public gists. // -// GitHub API docs: https://developer.github.com/v3/gists/#list-gists +// GitHub API docs: https://developer.github.com/v3/gists/#list-public-gists func (s *GistsService) ListAll(ctx context.Context, opts *GistListOptions) ([]*Gist, *Response, error) { u, err := addOptions("gists/public", opts) if err != nil { @@ -148,7 +149,7 @@ func (s *GistsService) ListAll(ctx context.Context, opts *GistListOptions) ([]*G // ListStarred lists starred gists of authenticated user. // -// GitHub API docs: https://developer.github.com/v3/gists/#list-gists +// GitHub API docs: https://developer.github.com/v3/gists/#list-starred-gists func (s *GistsService) ListStarred(ctx context.Context, opts *GistListOptions) ([]*Gist, *Response, error) { u, err := addOptions("gists/starred", opts) if err != nil { @@ -171,7 +172,7 @@ func (s *GistsService) ListStarred(ctx context.Context, opts *GistListOptions) ( // Get a single gist. // -// GitHub API docs: https://developer.github.com/v3/gists/#get-a-single-gist +// GitHub API docs: https://developer.github.com/v3/gists/#get-a-gist func (s *GistsService) Get(ctx context.Context, id string) (*Gist, *Response, error) { u := fmt.Sprintf("gists/%v", id) req, err := s.client.NewRequest("GET", u, nil) @@ -228,7 +229,7 @@ func (s *GistsService) Create(ctx context.Context, gist *Gist) (*Gist, *Response // Edit a gist. // -// GitHub API docs: https://developer.github.com/v3/gists/#edit-a-gist +// GitHub API docs: https://developer.github.com/v3/gists/#update-a-gist func (s *GistsService) Edit(ctx context.Context, id string, gist *Gist) (*Gist, *Response, error) { u := fmt.Sprintf("gists/%v", id) req, err := s.client.NewRequest("PATCH", u, gist) diff --git a/github/issues.go b/github/issues.go index bc3b83e732b..ccce80abc79 100644 --- a/github/issues.go +++ b/github/issues.go @@ -129,7 +129,8 @@ type PullRequestLinks struct { // organization repositories; if false, list only owned and member // repositories. // -// GitHub API docs: https://developer.github.com/v3/issues/#list-issues +// GitHub API docs: https://developer.github.com/v3/issues/#list-issues-assigned-to-the-authenticated-user +// GitHub API docs: https://developer.github.com/v3/issues/#list-user-account-issues-assigned-to-the-authenticated-user func (s *IssuesService) List(ctx context.Context, all bool, opts *IssueListOptions) ([]*Issue, *Response, error) { var u string if all { @@ -143,7 +144,7 @@ func (s *IssuesService) List(ctx context.Context, all bool, opts *IssueListOptio // ListByOrg fetches the issues in the specified organization for the // authenticated user. // -// GitHub API docs: https://developer.github.com/v3/issues/#list-issues +// GitHub API docs: https://developer.github.com/v3/issues/#list-organization-issues-assigned-to-the-authenticated-user func (s *IssuesService) ListByOrg(ctx context.Context, org string, opts *IssueListOptions) ([]*Issue, *Response, error) { u := fmt.Sprintf("orgs/%v/issues", org) return s.listIssues(ctx, u, opts) @@ -243,7 +244,7 @@ func (s *IssuesService) ListByRepo(ctx context.Context, owner string, repo strin // Get a single issue. // -// GitHub API docs: https://developer.github.com/v3/issues/#get-a-single-issue +// GitHub API docs: https://developer.github.com/v3/issues/#get-an-issue func (s *IssuesService) Get(ctx context.Context, owner string, repo string, number int) (*Issue, *Response, error) { u := fmt.Sprintf("repos/%v/%v/issues/%d", owner, repo, number) req, err := s.client.NewRequest("GET", u, nil) @@ -285,7 +286,7 @@ func (s *IssuesService) Create(ctx context.Context, owner string, repo string, i // Edit an issue. // -// GitHub API docs: https://developer.github.com/v3/issues/#edit-an-issue +// GitHub API docs: https://developer.github.com/v3/issues/#update-an-issue func (s *IssuesService) Edit(ctx context.Context, owner string, repo string, number int, issue *IssueRequest) (*Issue, *Response, error) { u := fmt.Sprintf("repos/%v/%v/issues/%d", owner, repo, number) req, err := s.client.NewRequest("PATCH", u, issue) diff --git a/github/issues_comments.go b/github/issues_comments.go index 56b24c19179..5e5a754744e 100644 --- a/github/issues_comments.go +++ b/github/issues_comments.go @@ -50,6 +50,7 @@ type IssueListCommentsOptions struct { // ListComments lists all comments on the specified issue. Specifying an issue // number of 0 will return all comments on all issues for the repository. // +// GitHub API docs: https://developer.github.com/v3/issues/comments/#list-comments-in-a-repository // GitHub API docs: https://developer.github.com/v3/issues/comments/#list-comments-on-an-issue func (s *IssuesService) ListComments(ctx context.Context, owner string, repo string, number int, opts *IssueListCommentsOptions) ([]*IssueComment, *Response, error) { var u string diff --git a/github/migrations.go b/github/migrations.go index f4260bb77cc..86b7c2789e0 100644 --- a/github/migrations.go +++ b/github/migrations.go @@ -74,7 +74,7 @@ type startMigration struct { // StartMigration starts the generation of a migration archive. // repos is a slice of repository names to migrate. // -// GitHub API docs: https://developer.github.com/v3/migration/migrations/#start-a-migration +// GitHub API docs: https://developer.github.com/v3/migrations/orgs/#start-an-organization-migration func (s *MigrationService) StartMigration(ctx context.Context, org string, repos []string, opts *MigrationOptions) (*Migration, *Response, error) { u := fmt.Sprintf("orgs/%v/migrations", org) @@ -103,7 +103,7 @@ func (s *MigrationService) StartMigration(ctx context.Context, org string, repos // ListMigrations lists the most recent migrations. // -// GitHub API docs: https://developer.github.com/v3/migrations/orgs/#get-a-list-of-organization-migrations +// GitHub API docs: https://developer.github.com/v3/migrations/orgs/#list-organization-migrations func (s *MigrationService) ListMigrations(ctx context.Context, org string, opts *ListOptions) ([]*Migration, *Response, error) { u := fmt.Sprintf("orgs/%v/migrations", org) u, err := addOptions(u, opts) @@ -131,7 +131,7 @@ func (s *MigrationService) ListMigrations(ctx context.Context, org string, opts // MigrationStatus gets the status of a specific migration archive. // id is the migration ID. // -// GitHub API docs: https://developer.github.com/v3/migration/migrations/#get-the-status-of-a-migration +// GitHub API docs: https://developer.github.com/v3/migrations/orgs/#get-the-status-of-an-organization-migration func (s *MigrationService) MigrationStatus(ctx context.Context, org string, id int64) (*Migration, *Response, error) { u := fmt.Sprintf("orgs/%v/migrations/%v", org, id) @@ -155,7 +155,7 @@ func (s *MigrationService) MigrationStatus(ctx context.Context, org string, id i // MigrationArchiveURL fetches a migration archive URL. // id is the migration ID. // -// GitHub API docs: https://developer.github.com/v3/migration/migrations/#download-a-migration-archive +// GitHub API docs: https://developer.github.com/v3/migrations/orgs/#download-an-organization-migration-archive func (s *MigrationService) MigrationArchiveURL(ctx context.Context, org string, id int64) (url string, err error) { u := fmt.Sprintf("orgs/%v/migrations/%v/archive", org, id) @@ -192,7 +192,7 @@ func (s *MigrationService) MigrationArchiveURL(ctx context.Context, org string, // DeleteMigration deletes a previous migration archive. // id is the migration ID. // -// GitHub API docs: https://developer.github.com/v3/migration/migrations/#delete-a-migration-archive +// GitHub API docs: https://developer.github.com/v3/migrations/orgs/#delete-an-organization-migration-archive func (s *MigrationService) DeleteMigration(ctx context.Context, org string, id int64) (*Response, error) { u := fmt.Sprintf("orgs/%v/migrations/%v/archive", org, id) @@ -212,7 +212,7 @@ func (s *MigrationService) DeleteMigration(ctx context.Context, org string, id i // You should unlock each migrated repository and delete them when the migration // is complete and you no longer need the source data. // -// GitHub API docs: https://developer.github.com/v3/migration/migrations/#unlock-a-repository +// GitHub API docs: https://developer.github.com/v3/migrations/orgs/#unlock-an-organization-repository func (s *MigrationService) UnlockRepo(ctx context.Context, org string, id int64, repo string) (*Response, error) { u := fmt.Sprintf("orgs/%v/migrations/%v/repos/%v/lock", org, id, repo) diff --git a/github/migrations_source_import.go b/github/migrations_source_import.go index cbdf1ea8a13..3980dc902c1 100644 --- a/github/migrations_source_import.go +++ b/github/migrations_source_import.go @@ -146,7 +146,7 @@ func (f LargeFile) String() string { // StartImport initiates a repository import. // -// GitHub API docs: https://developer.github.com/v3/migration/source_imports/#start-an-import +// GitHub API docs: https://developer.github.com/v3/migrations/source_imports/#start-an-import func (s *MigrationService) StartImport(ctx context.Context, owner, repo string, in *Import) (*Import, *Response, error) { u := fmt.Sprintf("repos/%v/%v/import", owner, repo) req, err := s.client.NewRequest("PUT", u, in) @@ -165,7 +165,7 @@ func (s *MigrationService) StartImport(ctx context.Context, owner, repo string, // ImportProgress queries for the status and progress of an ongoing repository import. // -// GitHub API docs: https://developer.github.com/v3/migration/source_imports/#get-import-progress +// GitHub API docs: https://developer.github.com/v3/migrations/source_imports/#get-import-progress func (s *MigrationService) ImportProgress(ctx context.Context, owner, repo string) (*Import, *Response, error) { u := fmt.Sprintf("repos/%v/%v/import", owner, repo) req, err := s.client.NewRequest("GET", u, nil) @@ -184,7 +184,7 @@ func (s *MigrationService) ImportProgress(ctx context.Context, owner, repo strin // UpdateImport initiates a repository import. // -// GitHub API docs: https://developer.github.com/v3/migration/source_imports/#update-existing-import +// GitHub API docs: https://developer.github.com/v3/migrations/source_imports/#update-existing-import func (s *MigrationService) UpdateImport(ctx context.Context, owner, repo string, in *Import) (*Import, *Response, error) { u := fmt.Sprintf("repos/%v/%v/import", owner, repo) req, err := s.client.NewRequest("PATCH", u, in) @@ -213,7 +213,7 @@ func (s *MigrationService) UpdateImport(ctx context.Context, owner, repo string, // This method and MapCommitAuthor allow you to provide correct Git author // information. // -// GitHub API docs: https://developer.github.com/v3/migration/source_imports/#get-commit-authors +// GitHub API docs: https://developer.github.com/v3/migrations/source_imports/#get-commit-authors func (s *MigrationService) CommitAuthors(ctx context.Context, owner, repo string) ([]*SourceImportAuthor, *Response, error) { u := fmt.Sprintf("repos/%v/%v/import/authors", owner, repo) req, err := s.client.NewRequest("GET", u, nil) @@ -234,7 +234,7 @@ func (s *MigrationService) CommitAuthors(ctx context.Context, owner, repo string // application can continue updating authors any time before you push new // commits to the repository. // -// GitHub API docs: https://developer.github.com/v3/migration/source_imports/#map-a-commit-author +// GitHub API docs: https://developer.github.com/v3/migrations/source_imports/#map-a-commit-author func (s *MigrationService) MapCommitAuthor(ctx context.Context, owner, repo string, id int64, author *SourceImportAuthor) (*SourceImportAuthor, *Response, error) { u := fmt.Sprintf("repos/%v/%v/import/authors/%v", owner, repo, id) req, err := s.client.NewRequest("PATCH", u, author) @@ -255,7 +255,7 @@ func (s *MigrationService) MapCommitAuthor(ctx context.Context, owner, repo stri // files larger than 100MB. Only the UseLFS field on the provided Import is // used. // -// GitHub API docs: https://developer.github.com/v3/migration/source_imports/#set-git-lfs-preference +// GitHub API docs: https://developer.github.com/v3/migrations/source_imports/#set-git-lfs-preference func (s *MigrationService) SetLFSPreference(ctx context.Context, owner, repo string, in *Import) (*Import, *Response, error) { u := fmt.Sprintf("repos/%v/%v/import/lfs", owner, repo) req, err := s.client.NewRequest("PATCH", u, in) @@ -274,7 +274,7 @@ func (s *MigrationService) SetLFSPreference(ctx context.Context, owner, repo str // LargeFiles lists files larger than 100MB found during the import. // -// GitHub API docs: https://developer.github.com/v3/migration/source_imports/#get-large-files +// GitHub API docs: https://developer.github.com/v3/migrations/source_imports/#get-large-files func (s *MigrationService) LargeFiles(ctx context.Context, owner, repo string) ([]*LargeFile, *Response, error) { u := fmt.Sprintf("repos/%v/%v/import/large_files", owner, repo) req, err := s.client.NewRequest("GET", u, nil) @@ -293,7 +293,7 @@ func (s *MigrationService) LargeFiles(ctx context.Context, owner, repo string) ( // CancelImport stops an import for a repository. // -// GitHub API docs: https://developer.github.com/v3/migration/source_imports/#cancel-an-import +// GitHub API docs: https://developer.github.com/v3/migrations/source_imports/#cancel-an-import func (s *MigrationService) CancelImport(ctx context.Context, owner, repo string) (*Response, error) { u := fmt.Sprintf("repos/%v/%v/import", owner, repo) req, err := s.client.NewRequest("DELETE", u, nil) diff --git a/github/migrations_user.go b/github/migrations_user.go index 5b58d293544..5224d7b844c 100644 --- a/github/migrations_user.go +++ b/github/migrations_user.go @@ -96,7 +96,7 @@ func (s *MigrationService) StartUserMigration(ctx context.Context, repos []strin // ListUserMigrations lists the most recent migrations. // -// GitHub API docs: https://developer.github.com/v3/migrations/users/#get-a-list-of-user-migrations +// GitHub API docs: https://developer.github.com/v3/migrations/users/#list-user-migrations func (s *MigrationService) ListUserMigrations(ctx context.Context) ([]*UserMigration, *Response, error) { u := "user/migrations" diff --git a/github/orgs.go b/github/orgs.go index 3c87ec84d4f..564231bc418 100644 --- a/github/orgs.go +++ b/github/orgs.go @@ -145,6 +145,7 @@ func (s *OrganizationsService) ListAll(ctx context.Context, opts *OrganizationsL // organizations for the authenticated user. // // GitHub API docs: https://developer.github.com/v3/orgs/#list-user-organizations +// GitHub API docs: https://developer.github.com/v3/orgs/#oauth-scope-requirements func (s *OrganizationsService) List(ctx context.Context, user string, opts *ListOptions) ([]*Organization, *Response, error) { var u string if user != "" { @@ -214,7 +215,7 @@ func (s *OrganizationsService) GetByID(ctx context.Context, id int64) (*Organiza // Edit an organization. // -// GitHub API docs: https://developer.github.com/v3/orgs/#edit-an-organization +// GitHub API docs: https://developer.github.com/v3/orgs/#members_can_create_repositories func (s *OrganizationsService) Edit(ctx context.Context, name string, org *Organization) (*Organization, *Response, error) { u := fmt.Sprintf("orgs/%v", name) req, err := s.client.NewRequest("PATCH", u, org) diff --git a/github/orgs_members.go b/github/orgs_members.go index 6b96d05f67c..0dfa92070d5 100644 --- a/github/orgs_members.go +++ b/github/orgs_members.go @@ -72,6 +72,7 @@ type ListMembersOptions struct { // public members, otherwise it will only return public members. // // GitHub API docs: https://developer.github.com/v3/orgs/members/#members-list +// GitHub API docs: https://developer.github.com/v3/orgs/members/#public-members-list func (s *OrganizationsService) ListMembers(ctx context.Context, org string, opts *ListMembersOptions) ([]*User, *Response, error) { var u string if opts != nil && opts.PublicOnly { @@ -206,9 +207,8 @@ func (s *OrganizationsService) ListOrgMemberships(ctx context.Context, opts *Lis // Passing an empty string for user will get the membership for the // authenticated user. // -// GitHub API docs: -// https://developer.github.com/v3/orgs/members/#get-organization-membership -// https://developer.github.com/v3/orgs/members/#get-your-organization-membership +// GitHub API docs: https://developer.github.com/v3/orgs/members/#get-organization-membership +// GitHub API docs: https://developer.github.com/v3/orgs/members/#get-your-organization-membership func (s *OrganizationsService) GetOrgMembership(ctx context.Context, user, org string) (*Membership, *Response, error) { var u string if user != "" { @@ -322,7 +322,7 @@ type CreateOrgInvitationOptions struct { // In order to create invitations in an organization, // the authenticated user must be an organization owner. // -// https://developer.github.com/v3/orgs/members/#create-organization-invitation +// GitHub API docs: https://developer.github.com/v3/orgs/members/#create-organization-invitation func (s *OrganizationsService) CreateOrgInvitation(ctx context.Context, org string, opts *CreateOrgInvitationOptions) (*Invitation, *Response, error) { u := fmt.Sprintf("orgs/%v/invitations", org) diff --git a/github/pulls.go b/github/pulls.go index 00692088647..019432659a2 100644 --- a/github/pulls.go +++ b/github/pulls.go @@ -214,6 +214,8 @@ func (s *PullRequestsService) Get(ctx context.Context, owner string, repo string } // GetRaw gets a single pull request in raw (diff or patch) format. +// +// GitHub API docs: https://developer.github.com/v3/pulls/#get-a-single-pull-request func (s *PullRequestsService) GetRaw(ctx context.Context, owner string, repo string, number int, opts RawOptions) (string, *Response, error) { u := fmt.Sprintf("repos/%v/%v/pulls/%d", owner, repo, number) req, err := s.client.NewRequest("GET", u, nil) @@ -458,7 +460,7 @@ type pullRequestMergeRequest struct { // Merge a pull request (Merge Button™). // commitMessage is the title for the automatic commit message. // -// GitHub API docs: https://developer.github.com/v3/pulls/#merge-a-pull-request-merge-buttontrade +// GitHub API docs: https://developer.github.com/v3/pulls/#merge-a-pull-request-merge-button func (s *PullRequestsService) Merge(ctx context.Context, owner string, repo string, number int, commitMessage string, options *PullRequestOptions) (*PullRequestMergeResult, *Response, error) { u := fmt.Sprintf("repos/%v/%v/pulls/%d/merge", owner, repo, number) diff --git a/github/pulls_comments.go b/github/pulls_comments.go index 88fb209b6fa..741454aeefb 100644 --- a/github/pulls_comments.go +++ b/github/pulls_comments.go @@ -66,6 +66,7 @@ type PullRequestListCommentsOptions struct { // pull request number of 0 will return all comments on all pull requests for // the repository. // +// GitHub API docs: https://developer.github.com/v3/pulls/comments/#list-comments-in-a-repository // GitHub API docs: https://developer.github.com/v3/pulls/comments/#list-comments-on-a-pull-request func (s *PullRequestsService) ListComments(ctx context.Context, owner string, repo string, number int, opts *PullRequestListCommentsOptions) ([]*PullRequestComment, *Response, error) { var u string @@ -144,7 +145,7 @@ func (s *PullRequestsService) CreateComment(ctx context.Context, owner string, r // CreateCommentInReplyTo creates a new comment as a reply to an existing pull request comment. // -// GitHub API docs: https://developer.github.com/v3/pulls/comments/#alternative-input +// GitHub API docs: https://developer.github.com/v3/pulls/comments/#create-a-comment func (s *PullRequestsService) CreateCommentInReplyTo(ctx context.Context, owner string, repo string, number int, body string, commentID int64) (*PullRequestComment, *Response, error) { comment := &struct { Body string `json:"body,omitempty"` diff --git a/github/reactions.go b/github/reactions.go index 7dd8b7c9db3..ce0a7518295 100644 --- a/github/reactions.go +++ b/github/reactions.go @@ -274,7 +274,7 @@ func (s *ReactionsService) DeleteIssueCommentReactionByID(ctx context.Context, r // ListPullRequestCommentReactions lists the reactions for a pull request review comment. // -// GitHub API docs: https://developer.github.com/v3/reactions/#list-reactions-for-an-issue-comment +// GitHub API docs: https://developer.github.com/v3/reactions/#list-reactions-for-a-pull-request-review-comment func (s *ReactionsService) ListPullRequestCommentReactions(ctx context.Context, owner, repo string, id int64, opts *ListOptions) ([]*Reaction, *Response, error) { u := fmt.Sprintf("repos/%v/%v/pulls/comments/%v/reactions", owner, repo, id) u, err := addOptions(u, opts) @@ -304,7 +304,7 @@ func (s *ReactionsService) ListPullRequestCommentReactions(ctx context.Context, // previously created reaction will be returned with Status: 200 OK. // The content should have one of the following values: "+1", "-1", "laugh", "confused", "heart", "hooray". // -// GitHub API docs: https://developer.github.com/v3/reactions/#create-reaction-for-an-issue-comment +// GitHub API docs: https://developer.github.com/v3/reactions/#create-reaction-for-a-pull-request-review-comment func (s *ReactionsService) CreatePullRequestCommentReaction(ctx context.Context, owner, repo string, id int64, content string) (*Reaction, *Response, error) { u := fmt.Sprintf("repos/%v/%v/pulls/comments/%v/reactions", owner, repo, id) @@ -346,7 +346,7 @@ func (s *ReactionsService) DeletePullRequestCommentReactionByID(ctx context.Cont // ListTeamDiscussionReactions lists the reactions for a team discussion. // -// GitHub API docs: https://developer.github.com/v3/reactions/#list-reactions-for-a-team-discussion +// GitHub API docs: https://developer.github.com/v3/reactions/#list-reactions-for-a-team-discussion-legacy func (s *ReactionsService) ListTeamDiscussionReactions(ctx context.Context, teamID int64, discussionNumber int, opts *ListOptions) ([]*Reaction, *Response, error) { u := fmt.Sprintf("teams/%v/discussions/%v/reactions", teamID, discussionNumber) u, err := addOptions(u, opts) @@ -373,7 +373,7 @@ func (s *ReactionsService) ListTeamDiscussionReactions(ctx context.Context, team // CreateTeamDiscussionReaction creates a reaction for a team discussion. // The content should have one of the following values: "+1", "-1", "laugh", "confused", "heart", "hooray". // -// GitHub API docs: https://developer.github.com/v3/reactions/#create-reaction-for-a-team-discussion +// GitHub API docs: https://developer.github.com/v3/reactions/#create-reaction-for-a-team-discussion-legacy func (s *ReactionsService) CreateTeamDiscussionReaction(ctx context.Context, teamID int64, discussionNumber int, content string) (*Reaction, *Response, error) { u := fmt.Sprintf("teams/%v/discussions/%v/reactions", teamID, discussionNumber) @@ -414,7 +414,7 @@ func (s *ReactionsService) DeleteTeamDiscussionReactionByOrgIDAndTeamID(ctx cont // ListTeamDiscussionCommentReactions lists the reactions for a team discussion comment. // -// GitHub API docs: https://developer.github.com/v3/reactions/#list-reactions-for-a-team-discussion-comment +// GitHub API docs: https://developer.github.com/v3/reactions/#list-reactions-for-a-team-discussion-comment-legacy func (s *ReactionsService) ListTeamDiscussionCommentReactions(ctx context.Context, teamID int64, discussionNumber, commentNumber int, opts *ListOptions) ([]*Reaction, *Response, error) { u := fmt.Sprintf("teams/%v/discussions/%v/comments/%v/reactions", teamID, discussionNumber, commentNumber) u, err := addOptions(u, opts) @@ -440,7 +440,7 @@ func (s *ReactionsService) ListTeamDiscussionCommentReactions(ctx context.Contex // CreateTeamDiscussionCommentReaction creates a reaction for a team discussion comment. // The content should have one of the following values: "+1", "-1", "laugh", "confused", "heart", "hooray". // -// GitHub API docs: https://developer.github.com/v3/reactions/#create-reaction-for-a-team-discussion-comment +// GitHub API docs: https://developer.github.com/v3/reactions/#create-reaction-for-a-team-discussion-comment-legacy func (s *ReactionsService) CreateTeamDiscussionCommentReaction(ctx context.Context, teamID int64, discussionNumber, commentNumber int, content string) (*Reaction, *Response, error) { u := fmt.Sprintf("teams/%v/discussions/%v/comments/%v/reactions", teamID, discussionNumber, commentNumber) diff --git a/github/repos.go b/github/repos.go index c30d5955ee3..1014d91f44b 100644 --- a/github/repos.go +++ b/github/repos.go @@ -182,7 +182,8 @@ type RepositoryListOptions struct { // List the repositories for a user. Passing the empty string will list // repositories for the authenticated user. // -// GitHub API docs: https://developer.github.com/v3/repos/#list-user-repositories +// GitHub API docs: https://developer.github.com/v3/repos/#list-repositories-for-a-user +// GitHub API docs: https://developer.github.com/v3/repos/#list-repositories-for-the-authenticated-user func (s *RepositoriesService) List(ctx context.Context, user string, opts *RepositoryListOptions) ([]*Repository, *Response, error) { var u string if user != "" { @@ -268,7 +269,7 @@ type RepositoryListAllOptions struct { // ListAll lists all GitHub repositories in the order that they were created. // -// GitHub API docs: https://developer.github.com/v3/repos/#list-all-public-repositories +// GitHub API docs: https://developer.github.com/v3/repos/#list-public-repositories func (s *RepositoriesService) ListAll(ctx context.Context, opts *RepositoryListAllOptions) ([]*Repository, *Response, error) { u, err := addOptions("repositories", opts) if err != nil { @@ -326,7 +327,8 @@ type createRepoRequest struct { // Note that only a subset of the repo fields are used and repo must // not be nil. // -// GitHub API docs: https://developer.github.com/v3/repos/#create +// GitHub API docs: https://developer.github.com/v3/repos/#create-a-repository-for-the-authenticated-user +// GitHub API docs: https://developer.github.com/v3/repos/#create-an-organization-repository func (s *RepositoriesService) Create(ctx context.Context, org string, repo *Repository) (*Repository, *Response, error) { var u string if org != "" { @@ -383,7 +385,7 @@ type TemplateRepoRequest struct { // CreateFromTemplate generates a repository from a template. // -// GitHub API docs: https://developer.github.com/v3/repos/#create-repository-using-a-repository-template +// GitHub API docs: https://developer.github.com/v3/repos/#create-a-repository-using-a-template func (s *RepositoriesService) CreateFromTemplate(ctx context.Context, templateOwner, templateRepo string, templateRepoReq *TemplateRepoRequest) (*Repository, *Response, error) { u := fmt.Sprintf("repos/%v/%v/generate", templateOwner, templateRepo) @@ -404,7 +406,7 @@ func (s *RepositoriesService) CreateFromTemplate(ctx context.Context, templateOw // Get fetches a repository. // -// GitHub API docs: https://developer.github.com/v3/repos/#get +// GitHub API docs: https://developer.github.com/v3/repos/#get-a-repository func (s *RepositoriesService) Get(ctx context.Context, owner, repo string) (*Repository, *Response, error) { u := fmt.Sprintf("repos/%v/%v", owner, repo) req, err := s.client.NewRequest("GET", u, nil) @@ -474,7 +476,7 @@ func (s *RepositoriesService) GetByID(ctx context.Context, id int64) (*Repositor // Edit updates a repository. // -// GitHub API docs: https://developer.github.com/v3/repos/#edit +// GitHub API docs: https://developer.github.com/v3/repos/#update-a-repository func (s *RepositoriesService) Edit(ctx context.Context, owner, repo string, repository *Repository) (*Repository, *Response, error) { u := fmt.Sprintf("repos/%v/%v", owner, repo) req, err := s.client.NewRequest("PATCH", u, repository) @@ -898,7 +900,7 @@ type SignaturesProtectedBranch struct { // ListBranches lists branches for the specified repository. // -// GitHub API docs: https://developer.github.com/v3/repos/#list-branches +// GitHub API docs: https://developer.github.com/v3/repos/branches/#list-branches func (s *RepositoriesService) ListBranches(ctx context.Context, owner string, repo string, opts *BranchListOptions) ([]*Branch, *Response, error) { u := fmt.Sprintf("repos/%v/%v/branches", owner, repo) u, err := addOptions(u, opts) @@ -925,7 +927,7 @@ func (s *RepositoriesService) ListBranches(ctx context.Context, owner string, re // GetBranch gets the specified branch for a repository. // -// GitHub API docs: https://developer.github.com/v3/repos/#get-branch +// GitHub API docs: https://developer.github.com/v3/repos/branches/#get-branch func (s *RepositoriesService) GetBranch(ctx context.Context, owner, repo, branch string) (*Branch, *Response, error) { u := fmt.Sprintf("repos/%v/%v/branches/%v", owner, repo, branch) req, err := s.client.NewRequest("GET", u, nil) @@ -1304,7 +1306,7 @@ type repositoryTopics struct { // ListAllTopics lists topics for a repository. // -// GitHub API docs: https://developer.github.com/v3/repos/#list-all-topics-for-a-repository +// GitHub API docs: https://developer.github.com/v3/repos/#get-all-repository-topics func (s *RepositoriesService) ListAllTopics(ctx context.Context, owner, repo string) ([]string, *Response, error) { u := fmt.Sprintf("repos/%v/%v/topics", owner, repo) req, err := s.client.NewRequest("GET", u, nil) @@ -1326,7 +1328,7 @@ func (s *RepositoriesService) ListAllTopics(ctx context.Context, owner, repo str // ReplaceAllTopics replaces topics for a repository. // -// GitHub API docs: https://developer.github.com/v3/repos/#replace-all-topics-for-a-repository +// GitHub API docs: https://developer.github.com/v3/repos/#replace-all-repository-topics func (s *RepositoriesService) ReplaceAllTopics(ctx context.Context, owner, repo string, topics []string) ([]string, *Response, error) { u := fmt.Sprintf("repos/%v/%v/topics", owner, repo) t := &repositoryTopics{ diff --git a/github/repos_collaborators.go b/github/repos_collaborators.go index bdfe04f13f3..e461516cae0 100644 --- a/github/repos_collaborators.go +++ b/github/repos_collaborators.go @@ -68,7 +68,7 @@ func (s *RepositoriesService) ListCollaborators(ctx context.Context, owner, repo // Note: This will return false if the user is not a collaborator OR the user // is not a GitHub user. // -// GitHub API docs: https://developer.github.com/v3/repos/collaborators/#get +// GitHub API docs: https://developer.github.com/v3/repos/collaborators/#check-if-a-user-is-a-collaborator func (s *RepositoriesService) IsCollaborator(ctx context.Context, owner, repo, user string) (bool, *Response, error) { u := fmt.Sprintf("repos/%v/%v/collaborators/%v", owner, repo, user) req, err := s.client.NewRequest("GET", u, nil) @@ -141,7 +141,7 @@ func (s *RepositoriesService) AddCollaborator(ctx context.Context, owner, repo, // RemoveCollaborator removes the specified GitHub user as collaborator from the given repo. // Note: Does not return error if a valid user that is not a collaborator is removed. // -// GitHub API docs: https://developer.github.com/v3/repos/collaborators/#remove-collaborator +// GitHub API docs: https://developer.github.com/v3/repos/collaborators/#remove-user-as-a-collaborator func (s *RepositoriesService) RemoveCollaborator(ctx context.Context, owner, repo, user string) (*Response, error) { u := fmt.Sprintf("repos/%v/%v/collaborators/%v", owner, repo, user) req, err := s.client.NewRequest("DELETE", u, nil) diff --git a/github/repos_commits.go b/github/repos_commits.go index 77bd748187f..4db577085ad 100644 --- a/github/repos_commits.go +++ b/github/repos_commits.go @@ -123,7 +123,7 @@ type BranchCommit struct { // ListCommits lists the commits of a repository. // -// GitHub API docs: https://developer.github.com/v3/repos/commits/#list +// GitHub API docs: https://developer.github.com/v3/repos/commits/#list-commits-on-a-repository func (s *RepositoriesService) ListCommits(ctx context.Context, owner, repo string, opts *CommitsListOptions) ([]*RepositoryCommit, *Response, error) { u := fmt.Sprintf("repos/%v/%v/commits", owner, repo) u, err := addOptions(u, opts) @@ -167,6 +167,8 @@ func (s *RepositoriesService) GetCommit(ctx context.Context, owner, repo, sha st } // GetCommitRaw fetches the specified commit in raw (diff or patch) format. +// +// GitHub API docs: https://developer.github.com/v3/repos/commits/#get-a-single-commit func (s *RepositoriesService) GetCommitRaw(ctx context.Context, owner string, repo string, sha string, opts RawOptions) (string, *Response, error) { u := fmt.Sprintf("repos/%v/%v/commits/%v", owner, repo, sha) req, err := s.client.NewRequest("GET", u, nil) @@ -195,7 +197,7 @@ func (s *RepositoriesService) GetCommitRaw(ctx context.Context, owner string, re // GetCommitSHA1 gets the SHA-1 of a commit reference. If a last-known SHA1 is // supplied and no new commits have occurred, a 304 Unmodified response is returned. // -// GitHub API docs: https://developer.github.com/v3/repos/commits/#get-the-sha-1-of-a-commit-reference +// GitHub API docs: https://developer.github.com/v3/repos/commits/#get-a-single-commit func (s *RepositoriesService) GetCommitSHA1(ctx context.Context, owner, repo, ref, lastSHA string) (string, *Response, error) { u := fmt.Sprintf("repos/%v/%v/commits/%v", owner, repo, refURLEscape(ref)) diff --git a/github/repos_community_health.go b/github/repos_community_health.go index 73d1d573bff..e8775a6c15e 100644 --- a/github/repos_community_health.go +++ b/github/repos_community_health.go @@ -38,7 +38,7 @@ type CommunityHealthMetrics struct { // GetCommunityHealthMetrics retrieves all the community health metrics for a repository. // -// GitHub API docs: https://developer.github.com/v3/repos/community/#retrieve-community-health-metrics +// GitHub API docs: https://developer.github.com/v3/repos/community/#retrieve-community-profile-metrics func (s *RepositoriesService) GetCommunityHealthMetrics(ctx context.Context, owner, repo string) (*CommunityHealthMetrics, *Response, error) { u := fmt.Sprintf("repos/%v/%v/community/profile", owner, repo) req, err := s.client.NewRequest("GET", u, nil) diff --git a/github/repos_contents.go b/github/repos_contents.go index ede93e4f4b5..015d9471a5e 100644 --- a/github/repos_contents.go +++ b/github/repos_contents.go @@ -177,7 +177,7 @@ func (s *RepositoriesService) GetContents(ctx context.Context, owner, repo, path // CreateFile creates a new file in a repository at the given path and returns // the commit and file metadata. // -// GitHub API docs: https://developer.github.com/v3/repos/contents/#create-a-file +// GitHub API docs: https://developer.github.com/v3/repos/contents/#create-or-update-a-file func (s *RepositoriesService) CreateFile(ctx context.Context, owner, repo, path string, opts *RepositoryContentFileOptions) (*RepositoryContentResponse, *Response, error) { u := fmt.Sprintf("repos/%s/%s/contents/%s", owner, repo, path) req, err := s.client.NewRequest("PUT", u, opts) @@ -195,7 +195,7 @@ func (s *RepositoriesService) CreateFile(ctx context.Context, owner, repo, path // UpdateFile updates a file in a repository at the given path and returns the // commit and file metadata. Requires the blob SHA of the file being updated. // -// GitHub API docs: https://developer.github.com/v3/repos/contents/#update-a-file +// GitHub API docs: https://developer.github.com/v3/repos/contents/#create-or-update-a-file func (s *RepositoriesService) UpdateFile(ctx context.Context, owner, repo, path string, opts *RepositoryContentFileOptions) (*RepositoryContentResponse, *Response, error) { u := fmt.Sprintf("repos/%s/%s/contents/%s", owner, repo, path) req, err := s.client.NewRequest("PUT", u, opts) diff --git a/github/repos_hooks.go b/github/repos_hooks.go index 5af71dfd11f..d81e74c9cf9 100644 --- a/github/repos_hooks.go +++ b/github/repos_hooks.go @@ -131,7 +131,7 @@ func (s *RepositoriesService) CreateHook(ctx context.Context, owner, repo string // ListHooks lists all Hooks for the specified repository. // -// GitHub API docs: https://developer.github.com/v3/repos/hooks/#list +// GitHub API docs: https://developer.github.com/v3/repos/hooks/#list-hooks func (s *RepositoriesService) ListHooks(ctx context.Context, owner, repo string, opts *ListOptions) ([]*Hook, *Response, error) { u := fmt.Sprintf("repos/%v/%v/hooks", owner, repo) u, err := addOptions(u, opts) diff --git a/github/repos_keys.go b/github/repos_keys.go index 11b3b6f6840..0eefd3dd96f 100644 --- a/github/repos_keys.go +++ b/github/repos_keys.go @@ -14,7 +14,7 @@ import ( // ListKeys lists the deploy keys for a repository. // -// GitHub API docs: https://developer.github.com/v3/repos/keys/#list +// GitHub API docs: https://developer.github.com/v3/repos/keys/#list-deploy-keys func (s *RepositoriesService) ListKeys(ctx context.Context, owner string, repo string, opts *ListOptions) ([]*Key, *Response, error) { u := fmt.Sprintf("repos/%v/%v/keys", owner, repo) u, err := addOptions(u, opts) @@ -38,7 +38,7 @@ func (s *RepositoriesService) ListKeys(ctx context.Context, owner string, repo s // GetKey fetches a single deploy key. // -// GitHub API docs: https://developer.github.com/v3/repos/keys/#get +// GitHub API docs: https://developer.github.com/v3/repos/keys/#get-a-deploy-key func (s *RepositoriesService) GetKey(ctx context.Context, owner string, repo string, id int64) (*Key, *Response, error) { u := fmt.Sprintf("repos/%v/%v/keys/%v", owner, repo, id) @@ -58,7 +58,7 @@ func (s *RepositoriesService) GetKey(ctx context.Context, owner string, repo str // CreateKey adds a deploy key for a repository. // -// GitHub API docs: https://developer.github.com/v3/repos/keys/#create +// GitHub API docs: https://developer.github.com/v3/repos/keys/#add-a-new-deploy-key func (s *RepositoriesService) CreateKey(ctx context.Context, owner string, repo string, key *Key) (*Key, *Response, error) { u := fmt.Sprintf("repos/%v/%v/keys", owner, repo) @@ -78,7 +78,7 @@ func (s *RepositoriesService) CreateKey(ctx context.Context, owner string, repo // DeleteKey deletes a deploy key. // -// GitHub API docs: https://developer.github.com/v3/repos/keys/#delete +// GitHub API docs: https://developer.github.com/v3/repos/keys/#remove-a-deploy-key func (s *RepositoriesService) DeleteKey(ctx context.Context, owner string, repo string, id int64) (*Response, error) { u := fmt.Sprintf("repos/%v/%v/keys/%v", owner, repo, id) diff --git a/github/repos_pages.go b/github/repos_pages.go index 58826527d9d..bdbd84b6c04 100644 --- a/github/repos_pages.go +++ b/github/repos_pages.go @@ -165,7 +165,7 @@ func (s *RepositoriesService) ListPagesBuilds(ctx context.Context, owner, repo s // GetLatestPagesBuild fetches the latest build information for a GitHub pages site. // -// GitHub API docs: https://developer.github.com/v3/repos/pages/#list-latest-pages-build +// GitHub API docs: https://developer.github.com/v3/repos/pages/#get-latest-pages-build func (s *RepositoriesService) GetLatestPagesBuild(ctx context.Context, owner, repo string) (*PagesBuild, *Response, error) { u := fmt.Sprintf("repos/%v/%v/pages/builds/latest", owner, repo) req, err := s.client.NewRequest("GET", u, nil) @@ -184,7 +184,7 @@ func (s *RepositoriesService) GetLatestPagesBuild(ctx context.Context, owner, re // GetPageBuild fetches the specific build information for a GitHub pages site. // -// GitHub API docs: https://developer.github.com/v3/repos/pages/#list-a-specific-pages-build +// GitHub API docs: https://developer.github.com/v3/repos/pages/#get-a-specific-pages-build func (s *RepositoriesService) GetPageBuild(ctx context.Context, owner, repo string, id int64) (*PagesBuild, *Response, error) { u := fmt.Sprintf("repos/%v/%v/pages/builds/%v", owner, repo, id) req, err := s.client.NewRequest("GET", u, nil) diff --git a/github/repos_stats.go b/github/repos_stats.go index e9c6d3fff4d..0e257bad39d 100644 --- a/github/repos_stats.go +++ b/github/repos_stats.go @@ -45,7 +45,7 @@ func (w WeeklyStats) String() string { // it is now computing the requested statistics. A follow up request, after a // delay of a second or so, should result in a successful request. // -// GitHub API docs: https://developer.github.com/v3/repos/statistics/#contributors +// GitHub API docs: https://developer.github.com/v3/repos/statistics/#get-contributors-list-with-additions-deletions-and-commit-counts func (s *RepositoriesService) ListContributorsStats(ctx context.Context, owner, repo string) ([]*ContributorStats, *Response, error) { u := fmt.Sprintf("repos/%v/%v/stats/contributors", owner, repo) req, err := s.client.NewRequest("GET", u, nil) @@ -84,7 +84,7 @@ func (w WeeklyCommitActivity) String() string { // it is now computing the requested statistics. A follow up request, after a // delay of a second or so, should result in a successful request. // -// GitHub API docs: https://developer.github.com/v3/repos/statistics/#commit-activity +// GitHub API docs: https://developer.github.com/v3/repos/statistics/#get-the-last-year-of-commit-activity-data func (s *RepositoriesService) ListCommitActivity(ctx context.Context, owner, repo string) ([]*WeeklyCommitActivity, *Response, error) { u := fmt.Sprintf("repos/%v/%v/stats/commit_activity", owner, repo) req, err := s.client.NewRequest("GET", u, nil) @@ -111,7 +111,7 @@ func (s *RepositoriesService) ListCommitActivity(ctx context.Context, owner, rep // it is now computing the requested statistics. A follow up request, after a // delay of a second or so, should result in a successful request. // -// GitHub API docs: https://developer.github.com/v3/repos/statistics/#code-frequency +// GitHub API docs: https://developer.github.com/v3/repos/statistics/#get-the-number-of-additions-and-deletions-per-week func (s *RepositoriesService) ListCodeFrequency(ctx context.Context, owner, repo string) ([]*WeeklyStats, *Response, error) { u := fmt.Sprintf("repos/%v/%v/stats/code_frequency", owner, repo) req, err := s.client.NewRequest("GET", u, nil) @@ -164,7 +164,7 @@ func (r RepositoryParticipation) String() string { // it is now computing the requested statistics. A follow up request, after a // delay of a second or so, should result in a successful request. // -// GitHub API docs: https://developer.github.com/v3/repos/statistics/#participation +// GitHub API docs: https://developer.github.com/v3/repos/statistics/#get-the-weekly-commit-count-for-the-repository-owner-and-everyone-else func (s *RepositoriesService) ListParticipation(ctx context.Context, owner, repo string) (*RepositoryParticipation, *Response, error) { u := fmt.Sprintf("repos/%v/%v/stats/participation", owner, repo) req, err := s.client.NewRequest("GET", u, nil) @@ -197,7 +197,7 @@ type PunchCard struct { // it is now computing the requested statistics. A follow up request, after a // delay of a second or so, should result in a successful request. // -// GitHub API docs: https://developer.github.com/v3/repos/statistics/#punch-card +// GitHub API docs: https://developer.github.com/v3/repos/statistics/#get-the-number-of-commits-per-hour-in-each-day func (s *RepositoriesService) ListPunchCard(ctx context.Context, owner, repo string) ([]*PunchCard, *Response, error) { u := fmt.Sprintf("repos/%v/%v/stats/punch_card", owner, repo) req, err := s.client.NewRequest("GET", u, nil) diff --git a/github/repos_traffic.go b/github/repos_traffic.go index e7ee18849a5..91d85706286 100644 --- a/github/repos_traffic.go +++ b/github/repos_traffic.go @@ -118,7 +118,7 @@ func (s *RepositoriesService) ListTrafficViews(ctx context.Context, owner, repo // ListTrafficClones get total number of clones for the last 14 days and breaks it down either per day or week for the last 14 days. // -// GitHub API docs: https://developer.github.com/v3/repos/traffic/#views +// GitHub API docs: https://developer.github.com/v3/repos/traffic/#clones func (s *RepositoriesService) ListTrafficClones(ctx context.Context, owner, repo string, opts *TrafficBreakdownOptions) (*TrafficClones, *Response, error) { u := fmt.Sprintf("repos/%v/%v/traffic/clones", owner, repo) u, err := addOptions(u, opts) diff --git a/github/search.go b/github/search.go index f08b3eb080a..c15c1f2b272 100644 --- a/github/search.go +++ b/github/search.go @@ -147,7 +147,7 @@ type IssuesSearchResult struct { // Issues searches issues via various criteria. // -// GitHub API docs: https://developer.github.com/v3/search/#search-issues +// GitHub API docs: https://developer.github.com/v3/search/#search-issues-and-pull-requests func (s *SearchService) Issues(ctx context.Context, query string, opts *SearchOptions) (*IssuesSearchResult, *Response, error) { result := new(IssuesSearchResult) resp, err := s.search(ctx, "issues", &searchParameters{Query: query}, opts, result) diff --git a/github/teams.go b/github/teams.go index 9ca449cdba1..6eab37fd545 100644 --- a/github/teams.go +++ b/github/teams.go @@ -461,7 +461,7 @@ type TeamAddTeamRepoOptions struct { // The specified repository must be owned by the organization to which the team // belongs, or a direct fork of a repository owned by the organization. // -// GitHub API docs: https://developer.github.com/v3/teams/#add-team-repo +// GitHub API docs: https://developer.github.com/v3/teams/#add-or-update-team-repository func (s *TeamsService) AddTeamRepoByID(ctx context.Context, orgID, teamID int64, owner, repo string, opts *TeamAddTeamRepoOptions) (*Response, error) { u := fmt.Sprintf("organizations/%v/team/%v/repos/%v/%v", orgID, teamID, owner, repo) req, err := s.client.NewRequest("PUT", u, opts) @@ -476,7 +476,7 @@ func (s *TeamsService) AddTeamRepoByID(ctx context.Context, orgID, teamID int64, // The specified repository must be owned by the organization to which the team // belongs, or a direct fork of a repository owned by the organization. // -// GitHub API docs: https://developer.github.com/v3/teams/#add-team-repo +// GitHub API docs: https://developer.github.com/v3/teams/#add-or-update-team-repository func (s *TeamsService) AddTeamRepoBySlug(ctx context.Context, org, slug, owner, repo string, opts *TeamAddTeamRepoOptions) (*Response, error) { u := fmt.Sprintf("orgs/%v/teams/%v/repos/%v/%v", org, slug, owner, repo) req, err := s.client.NewRequest("PUT", u, opts) @@ -491,7 +491,7 @@ func (s *TeamsService) AddTeamRepoBySlug(ctx context.Context, org, slug, owner, // team given the team ID. Note that this does not delete the repository, it // just removes it from the team. // -// GitHub API docs: https://developer.github.com/v3/teams/#remove-team-repo +// GitHub API docs: https://developer.github.com/v3/teams/#remove-team-repository func (s *TeamsService) RemoveTeamRepoByID(ctx context.Context, orgID, teamID int64, owner, repo string) (*Response, error) { u := fmt.Sprintf("organizations/%v/team/%v/repos/%v/%v", orgID, teamID, owner, repo) req, err := s.client.NewRequest("DELETE", u, nil) @@ -506,7 +506,7 @@ func (s *TeamsService) RemoveTeamRepoByID(ctx context.Context, orgID, teamID int // team given the team slug. Note that this does not delete the repository, it // just removes it from the team. // -// GitHub API docs: https://developer.github.com/v3/teams/#remove-team-repo +// GitHub API docs: https://developer.github.com/v3/teams/#remove-team-repository func (s *TeamsService) RemoveTeamRepoBySlug(ctx context.Context, org, slug, owner, repo string) (*Response, error) { u := fmt.Sprintf("orgs/%v/teams/%v/repos/%v/%v", org, slug, owner, repo) req, err := s.client.NewRequest("DELETE", u, nil) diff --git a/github/users.go b/github/users.go index 8b6ce5d87b9..97747f713c6 100644 --- a/github/users.go +++ b/github/users.go @@ -78,7 +78,7 @@ func (u User) String() string { // user. // // GitHub API docs: https://developer.github.com/v3/users/#get-a-single-user -// and: https://developer.github.com/v3/users/#get-the-authenticated-user +// GitHub API docs: https://developer.github.com/v3/users/#get-the-authenticated-user func (s *UsersService) Get(ctx context.Context, user string) (*User, *Response, error) { var u string if user != "" { diff --git a/github/users_followers.go b/github/users_followers.go index afa7d4b6b71..fa841c6c5de 100644 --- a/github/users_followers.go +++ b/github/users_followers.go @@ -14,6 +14,7 @@ import ( // fetch followers for the authenticated user. // // GitHub API docs: https://developer.github.com/v3/users/followers/#list-followers-of-a-user +// GitHub API docs: https://developer.github.com/v3/users/followers/#list-followers-of-the-authenticated-user func (s *UsersService) ListFollowers(ctx context.Context, user string, opts *ListOptions) ([]*User, *Response, error) { var u string if user != "" { @@ -44,6 +45,7 @@ func (s *UsersService) ListFollowers(ctx context.Context, user string, opts *Lis // string will list people the authenticated user is following. // // GitHub API docs: https://developer.github.com/v3/users/followers/#list-users-followed-by-another-user +// GitHub API docs: https://developer.github.com/v3/users/followers/#list-users-followed-by-the-authenticated-user func (s *UsersService) ListFollowing(ctx context.Context, user string, opts *ListOptions) ([]*User, *Response, error) { var u string if user != "" { @@ -73,6 +75,7 @@ func (s *UsersService) ListFollowing(ctx context.Context, user string, opts *Lis // IsFollowing checks if "user" is following "target". Passing the empty // string for "user" will check if the authenticated user is following "target". // +// GitHub API docs: https://developer.github.com/v3/users/followers/#check-if-one-user-follows-another // GitHub API docs: https://developer.github.com/v3/users/followers/#check-if-you-are-following-a-user func (s *UsersService) IsFollowing(ctx context.Context, user, target string) (bool, *Response, error) { var u string diff --git a/github/users_gpg_keys.go b/github/users_gpg_keys.go index 1d4dab045af..20b6edfd5b2 100644 --- a/github/users_gpg_keys.go +++ b/github/users_gpg_keys.go @@ -45,6 +45,7 @@ type GPGEmail struct { // via Basic Auth or via OAuth with at least read:gpg_key scope. // // GitHub API docs: https://developer.github.com/v3/users/gpg_keys/#list-gpg-keys-for-a-user +// GitHub API docs: https://developer.github.com/v3/users/gpg_keys/#list-your-gpg-keys func (s *UsersService) ListGPGKeys(ctx context.Context, user string, opts *ListOptions) ([]*GPGKey, *Response, error) { var u string if user != "" { diff --git a/github/users_keys.go b/github/users_keys.go index f12c01b9b07..1091606a9f2 100644 --- a/github/users_keys.go +++ b/github/users_keys.go @@ -28,6 +28,7 @@ func (k Key) String() string { // string will fetch keys for the authenticated user. // // GitHub API docs: https://developer.github.com/v3/users/keys/#list-public-keys-for-a-user +// GitHub API docs: https://developer.github.com/v3/users/keys/#list-your-public-keys func (s *UsersService) ListKeys(ctx context.Context, user string, opts *ListOptions) ([]*Key, *Response, error) { var u string if user != "" { diff --git a/update-urls/activity-events_test.go b/update-urls/activity-events_test.go new file mode 100644 index 00000000000..6f4dbeb4b13 --- /dev/null +++ b/update-urls/activity-events_test.go @@ -0,0 +1,1441 @@ +// Copyright 2020 The go-github AUTHORS. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +import ( + "testing" +) + +func newActivitiesEventsPipeline() *pipelineSetup { + return &pipelineSetup{ + baseURL: "https://developer.github.com/v3/activity/events/", + endpointsFromWebsite: activityEventsWant, + filename: "activity_events.go", + serviceName: "ActivityService", + originalGoSource: activityEventsGoFileOriginal, + wantGoSource: activityEventsGoFileWant, + wantNumEndpoints: 7, + } +} + +func TestPipeline_ActivityEvents(t *testing.T) { + ps := newActivitiesEventsPipeline() + ps.setup(t, false, false) + ps.validate(t) +} + +func TestPipeline_ActivityEvents_FirstStripAllURLs(t *testing.T) { + ps := newActivitiesEventsPipeline() + ps.setup(t, true, false) + ps.validate(t) +} + +func TestPipeline_ActivityEvents_FirstDestroyReceivers(t *testing.T) { + ps := newActivitiesEventsPipeline() + ps.setup(t, false, true) + ps.validate(t) +} + +func TestPipeline_ActivityEvents_FirstStripAllURLsAndDestroyReceivers(t *testing.T) { + ps := newActivitiesEventsPipeline() + ps.setup(t, true, true) + ps.validate(t) +} + +func TestParseWebPageEndpoints_ActivityEvents(t *testing.T) { + got, want := parseWebPageEndpoints(activityEventsTestWebPage), activityEventsWant + testWebPageHelper(t, got, want) +} + +var activityEventsWant = endpointsByFragmentID{ + "list-public-events": []*Endpoint{ + {urlFormats: []string{"events"}, httpMethod: "GET"}, + }, + + "list-repository-events": []*Endpoint{ + {urlFormats: []string{"repos/%v/%v/events"}, httpMethod: "GET"}, + }, + + "list-public-events-for-a-network-of-repositories": []*Endpoint{ + {urlFormats: []string{"networks/%v/%v/events"}, httpMethod: "GET"}, + }, + + "list-events-received-by-the-authenticated-user": []*Endpoint{ + {urlFormats: []string{"users/%v/received_events"}, httpMethod: "GET"}, + }, + + "list-events-for-the-authenticated-user": []*Endpoint{ + {urlFormats: []string{"users/%v/events"}, httpMethod: "GET"}, + }, + + "list-public-events-for-a-user": []*Endpoint{ + {urlFormats: []string{"users/%v/events/public"}, httpMethod: "GET"}, + }, + + "list-organization-events-for-the-authenticated-user": []*Endpoint{ + {urlFormats: []string{"users/%v/events/orgs/%v"}, httpMethod: "GET"}, + }, + + "list-public-organization-events": []*Endpoint{ + {urlFormats: []string{"orgs/%v/events"}, httpMethod: "GET"}, + }, + + "list-public-events-received-by-a-user": []*Endpoint{ + {urlFormats: []string{"users/%v/received_events/public"}, httpMethod: "GET"}, + }, +} + +var activityEventsTestWebPage = ` + + + + + + + + Events | GitHub Developer Guide + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + +
+
+

+Events

+ +

This is a read-only API to the GitHub events. These events power the various activity streams on the site. An events API for repository issues is also available. For more information, see the "Issue Events API."

+ + + +

Events are optimized for polling with the "ETag" header. If no new events have been triggered, you will see a "304 Not Modified" response, and your current rate limit will be untouched. There is also an "X-Poll-Interval" header that specifies how often (in seconds) you are allowed to poll. In times of high +server load, the time may increase. Please obey the header.

+ +
+curl -I https://api.github.com/users/tater/events
+HTTP/1.1 200 OK
+X-Poll-Interval: 60
+ETag: "a18c3bded88eb5dbb5c849a489412bf3"
+# The quotes around the ETag value are important
+curl -I https://api.github.com/users/tater/events \
+   -H 'If-None-Match: "a18c3bded88eb5dbb5c849a489412bf3"'
+HTTP/1.1 304 Not Modified
+X-Poll-Interval: 60
+
+ +

Events support pagination, however the per_page option is unsupported. The fixed page size is 30 items. Fetching up to ten pages is supported, for a total of 300 events.

+ +

Only events created within the past 90 days will be included in timelines. Events older than 90 days will not be included (even if the total number of events in the timeline is less than 300).

+ +

All Events have the same response format:

+ +
Status: 200 OK
+Link: <https://api.github.com/resource?page=2>; rel="next",
+      <https://api.github.com/resource?page=5>; rel="last"
+
+ + +
[
+  {
+    "type": "Event",
+    "public": true,
+    "payload": {
+    },
+    "repo": {
+      "id": 3,
+      "name": "octocat/Hello-World",
+      "url": "https://api.github.com/repos/octocat/Hello-World"
+    },
+    "actor": {
+      "id": 1,
+      "login": "octocat",
+      "gravatar_id": "",
+      "avatar_url": "https://github.com/images/error/octocat_happy.gif",
+      "url": "https://api.github.com/users/octocat"
+    },
+    "org": {
+      "id": 1,
+      "login": "github",
+      "gravatar_id": "",
+      "url": "https://api.github.com/orgs/github",
+      "avatar_url": "https://github.com/images/error/octocat_happy.gif"
+    },
+    "created_at": "2011-09-06T17:26:27Z",
+    "id": "12345"
+  }
+]
+
+ + +

+List public events +

+ +

We delay the public events feed by five minutes, which means the most recent event returned by the public events API actually occurred at least five minutes ago.

+ +
GET /events
+
+ +

+List repository events +

+ +
GET /repos/:owner/:repo/events
+
+ +

+List public events for a network of repositories +

+ +
GET /networks/:owner/:repo/events
+
+ +

+List public organization events +

+ +
GET /orgs/:org/events
+
+ +

+List events received by the authenticated user +

+ +

These are events that you've received by watching repos and following users. If you are authenticated as the given user, you will see private events. Otherwise, you'll only see public events.

+ +
GET /users/:username/received_events
+
+ +

+List public events received by a user +

+ +
GET /users/:username/received_events/public
+
+ +

+List events for the authenticated user +

+ +

If you are authenticated as the given user, you will see your private events. Otherwise, you'll only see public events.

+ +
GET /users/:username/events
+
+ +

+List public events for a user +

+ +
GET /users/:username/events/public
+
+ +

+List organization events for the authenticated user

+ +

This is the user's organization dashboard. You must be authenticated as the user to view this.

+ +
GET /users/:username/events/orgs/:org
+
+
+ + + + + +
+
+ + + + + + + +` + +var activityEventsGoFileOriginal = `// Copyright 2013 The go-github AUTHORS. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package github + +import ( + "context" + "fmt" +) + +// ListEvents drinks from the firehose of all public events across GitHub. +// +// GitHub API docs: https://developer.github.com/v3/activity/events/#list-public-events +func (s *ActivityService) ListEvents(ctx context.Context, opts *ListOptions) ([]*Event, *Response, error) { + u, err := addOptions("events", opts) + if err != nil { + return nil, nil, err + } + + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + + var events []*Event + resp, err := s.client.Do(ctx, req, &events) + if err != nil { + return nil, resp, err + } + + return events, resp, nil +} + +// ListRepositoryEvents lists events for a repository. +// +// GitHub API docs: https://developer.github.com/v3/activity/events/#list-repository-events +func (s *ActivityService) ListRepositoryEvents(ctx context.Context, owner, repo string, opts *ListOptions) ([]*Event, *Response, error) { + u := fmt.Sprintf("repos/%v/%v/events", owner, repo) + u, err := addOptions(u, opts) + if err != nil { + return nil, nil, err + } + + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + + var events []*Event + resp, err := s.client.Do(ctx, req, &events) + if err != nil { + return nil, resp, err + } + + return events, resp, nil +} + +// Note that ActivityService.ListIssueEventsForRepository was moved to: +// IssuesService.ListRepositoryEvents. + +// ListEventsForRepoNetwork lists public events for a network of repositories. +// +// GitHub API docs: https://developer.github.com/v3/activity/events/#list-public-events-for-a-network-of-repositories +func (s *ActivityService) ListEventsForRepoNetwork(ctx context.Context, owner, repo string, opts *ListOptions) ([]*Event, *Response, error) { + u := fmt.Sprintf("networks/%v/%v/events", owner, repo) + u, err := addOptions(u, opts) + if err != nil { + return nil, nil, err + } + + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + + var events []*Event + resp, err := s.client.Do(ctx, req, &events) + if err != nil { + return nil, resp, err + } + + return events, resp, nil +} + +// ListEventsForOrganization lists public events for an organization. +// +// GitHub API docs: https://developer.github.com/v3/activity/events/#list-public-events-for-an-organization +func (s *ActivityService) ListEventsForOrganization(ctx context.Context, org string, opts *ListOptions) ([]*Event, *Response, error) { + u := fmt.Sprintf("orgs/%v/events", org) + u, err := addOptions(u, opts) + if err != nil { + return nil, nil, err + } + + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + + var events []*Event + resp, err := s.client.Do(ctx, req, &events) + if err != nil { + return nil, resp, err + } + + return events, resp, nil +} + +// ListEventsPerformedByUser lists the events performed by a user. If publicOnly is +// true, only public events will be returned. +// +// GitHub API docs: https://developer.github.com/v3/activity/events/#list-events-for-the-authenticated-user +// GitHub API docs: https://developer.github.com/v3/activity/events/#list-public-events-for-a-user +func (s *ActivityService) ListEventsPerformedByUser(ctx context.Context, user string, publicOnly bool, opts *ListOptions) ([]*Event, *Response, error) { + var u string + if publicOnly { + u = fmt.Sprintf("users/%v/events/public", user) + } else { + u = fmt.Sprintf("users/%v/events", user) + } + u, err := addOptions(u, opts) + if err != nil { + return nil, nil, err + } + + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + + var events []*Event + resp, err := s.client.Do(ctx, req, &events) + if err != nil { + return nil, resp, err + } + + return events, resp, nil +} + +// ListEventsReceivedByUser lists the events received by a user. If publicOnly is +// true, only public events will be returned. +// +// GitHub API docs: https://developer.github.com/v3/activity/events/#list-events-received-by-the-authenticated-user +// GitHub API docs: https://developer.github.com/v3/activity/events/#list-public-events-received-by-a-user +func (s *ActivityService) ListEventsReceivedByUser(ctx context.Context, user string, publicOnly bool, opts *ListOptions) ([]*Event, *Response, error) { + var u string + if publicOnly { + u = fmt.Sprintf("users/%v/received_events/public", user) + } else { + u = fmt.Sprintf("users/%v/received_events", user) + } + u, err := addOptions(u, opts) + if err != nil { + return nil, nil, err + } + + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + + var events []*Event + resp, err := s.client.Do(ctx, req, &events) + if err != nil { + return nil, resp, err + } + + return events, resp, nil +} + +// ListUserEventsForOrganization provides the user’s organization dashboard. You +// must be authenticated as the user to view this. +// +// GitHub API docs: https://developer.github.com/v3/activity/events/#list-events-for-an-organization +func (s *ActivityService) ListUserEventsForOrganization(ctx context.Context, org, user string, opts *ListOptions) ([]*Event, *Response, error) { + u := fmt.Sprintf("users/%v/events/orgs/%v", user, org) + u, err := addOptions(u, opts) + if err != nil { + return nil, nil, err + } + + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + + var events []*Event + resp, err := s.client.Do(ctx, req, &events) + if err != nil { + return nil, resp, err + } + + return events, resp, nil +} +` + +var activityEventsGoFileWant = `// Copyright 2013 The go-github AUTHORS. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package github + +import ( + "context" + "fmt" +) + +// ListEvents drinks from the firehose of all public events across GitHub. +// +// GitHub API docs: https://developer.github.com/v3/activity/events/#list-public-events +func (s *ActivityService) ListEvents(ctx context.Context, opts *ListOptions) ([]*Event, *Response, error) { + u, err := addOptions("events", opts) + if err != nil { + return nil, nil, err + } + + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + + var events []*Event + resp, err := s.client.Do(ctx, req, &events) + if err != nil { + return nil, resp, err + } + + return events, resp, nil +} + +// ListRepositoryEvents lists events for a repository. +// +// GitHub API docs: https://developer.github.com/v3/activity/events/#list-repository-events +func (s *ActivityService) ListRepositoryEvents(ctx context.Context, owner, repo string, opts *ListOptions) ([]*Event, *Response, error) { + u := fmt.Sprintf("repos/%v/%v/events", owner, repo) + u, err := addOptions(u, opts) + if err != nil { + return nil, nil, err + } + + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + + var events []*Event + resp, err := s.client.Do(ctx, req, &events) + if err != nil { + return nil, resp, err + } + + return events, resp, nil +} + +// Note that ActivityService.ListIssueEventsForRepository was moved to: +// IssuesService.ListRepositoryEvents. + +// ListEventsForRepoNetwork lists public events for a network of repositories. +// +// GitHub API docs: https://developer.github.com/v3/activity/events/#list-public-events-for-a-network-of-repositories +func (s *ActivityService) ListEventsForRepoNetwork(ctx context.Context, owner, repo string, opts *ListOptions) ([]*Event, *Response, error) { + u := fmt.Sprintf("networks/%v/%v/events", owner, repo) + u, err := addOptions(u, opts) + if err != nil { + return nil, nil, err + } + + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + + var events []*Event + resp, err := s.client.Do(ctx, req, &events) + if err != nil { + return nil, resp, err + } + + return events, resp, nil +} + +// ListEventsForOrganization lists public events for an organization. +// +// GitHub API docs: https://developer.github.com/v3/activity/events/#list-public-organization-events +func (s *ActivityService) ListEventsForOrganization(ctx context.Context, org string, opts *ListOptions) ([]*Event, *Response, error) { + u := fmt.Sprintf("orgs/%v/events", org) + u, err := addOptions(u, opts) + if err != nil { + return nil, nil, err + } + + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + + var events []*Event + resp, err := s.client.Do(ctx, req, &events) + if err != nil { + return nil, resp, err + } + + return events, resp, nil +} + +// ListEventsPerformedByUser lists the events performed by a user. If publicOnly is +// true, only public events will be returned. +// +// GitHub API docs: https://developer.github.com/v3/activity/events/#list-events-for-the-authenticated-user +// GitHub API docs: https://developer.github.com/v3/activity/events/#list-public-events-for-a-user +func (s *ActivityService) ListEventsPerformedByUser(ctx context.Context, user string, publicOnly bool, opts *ListOptions) ([]*Event, *Response, error) { + var u string + if publicOnly { + u = fmt.Sprintf("users/%v/events/public", user) + } else { + u = fmt.Sprintf("users/%v/events", user) + } + u, err := addOptions(u, opts) + if err != nil { + return nil, nil, err + } + + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + + var events []*Event + resp, err := s.client.Do(ctx, req, &events) + if err != nil { + return nil, resp, err + } + + return events, resp, nil +} + +// ListEventsReceivedByUser lists the events received by a user. If publicOnly is +// true, only public events will be returned. +// +// GitHub API docs: https://developer.github.com/v3/activity/events/#list-events-received-by-the-authenticated-user +// GitHub API docs: https://developer.github.com/v3/activity/events/#list-public-events-received-by-a-user +func (s *ActivityService) ListEventsReceivedByUser(ctx context.Context, user string, publicOnly bool, opts *ListOptions) ([]*Event, *Response, error) { + var u string + if publicOnly { + u = fmt.Sprintf("users/%v/received_events/public", user) + } else { + u = fmt.Sprintf("users/%v/received_events", user) + } + u, err := addOptions(u, opts) + if err != nil { + return nil, nil, err + } + + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + + var events []*Event + resp, err := s.client.Do(ctx, req, &events) + if err != nil { + return nil, resp, err + } + + return events, resp, nil +} + +// ListUserEventsForOrganization provides the user’s organization dashboard. You +// must be authenticated as the user to view this. +// +// GitHub API docs: https://developer.github.com/v3/activity/events/#list-organization-events-for-the-authenticated-user +func (s *ActivityService) ListUserEventsForOrganization(ctx context.Context, org, user string, opts *ListOptions) ([]*Event, *Response, error) { + u := fmt.Sprintf("users/%v/events/orgs/%v", user, org) + u, err := addOptions(u, opts) + if err != nil { + return nil, nil, err + } + + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + + var events []*Event + resp, err := s.client.Do(ctx, req, &events) + if err != nil { + return nil, resp, err + } + + return events, resp, nil +} +` diff --git a/update-urls/go.mod b/update-urls/go.mod new file mode 100644 index 00000000000..3e168745cfc --- /dev/null +++ b/update-urls/go.mod @@ -0,0 +1,5 @@ +module github.com/google/go-github/update-urls + +go 1.14 + +require github.com/pmezard/go-difflib v1.0.0 diff --git a/update-urls/go.sum b/update-urls/go.sum new file mode 100644 index 00000000000..5d60ca74bbf --- /dev/null +++ b/update-urls/go.sum @@ -0,0 +1,2 @@ +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= diff --git a/update-urls/main.go b/update-urls/main.go new file mode 100644 index 00000000000..73c2e9ca3aa --- /dev/null +++ b/update-urls/main.go @@ -0,0 +1,1165 @@ +// Copyright 2020 The go-github AUTHORS. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// update-urls updates GitHub URL docs for each service endpoint. +// +// It is meant to be used periodically by go-github repo maintainers +// to update stale GitHub Developer v3 API documenation URLs. +// +// Usage (from go-github directory): +// go run ./update-urls/main.go +// go generate ./... +// go test ./... +// go vet ./... +package main + +import ( + "errors" + "flag" + "fmt" + "go/ast" + "go/parser" + "go/token" + "io/ioutil" + "log" + "net/http" + "os" + "regexp" + "sort" + "strings" +) + +const ( + skipPrefix = "gen-" + + enterpriseURL = "developer.github.com/enterprise" + stdURL = "developer.github.com" + + enterpriseRefFmt = "// GitHub Enterprise API docs: %v" + stdRefFmt = "// GitHub API docs: %v" +) + +var ( + verbose = flag.Bool("v", false, "Print verbose log messages") + debugFile = flag.String("d", "", "Debug named file only") + + // methodBlacklist holds methods that do not have GitHub v3 API URLs + // or are otherwise problematic in parsing, discovering, and/or fixing. + methodBlacklist = map[string]bool{ + "ActionsService.DownloadArtifact": true, + "AdminService.CreateOrg": true, + "AdminService.CreateUser": true, + "AdminService.CreateUserImpersonation": true, + "AdminService.DeleteUserImpersonation": true, + "AdminService.GetAdminStats": true, + "AdminService.RenameOrg": true, + "AdminService.RenameOrgByName": true, + "AdminService.UpdateTeamLDAPMapping": true, + "AdminService.UpdateUserLDAPMapping": true, + "AppsService.FindRepositoryInstallationByID": true, + "AuthorizationsService.CreateImpersonation": true, + "AuthorizationsService.DeleteImpersonation": true, + "GitService.GetRef": true, + "GitService.GetRefs": true, + "GitService.ListRefs": true, + "MarketplaceService.marketplaceURI": true, + "OrganizationsService.GetByID": true, + "RepositoriesService.DeletePreReceiveHook": true, + "RepositoriesService.DownloadContents": true, + "RepositoriesService.GetArchiveLink": true, + "RepositoriesService.GetByID": true, + "RepositoriesService.GetPreReceiveHook": true, + "RepositoriesService.ListPreReceiveHooks": true, + "RepositoriesService.UpdatePreReceiveHook": true, + "SearchService.search": true, + "UsersService.DemoteSiteAdmin": true, + "UsersService.GetByID": true, + "UsersService.PromoteSiteAdmin": true, + "UsersService.Suspend": true, + "UsersService.Unsuspend": true, + } + + helperOverrides = map[string]overrideFunc{ + "s.search": func(arg string) (httpMethod, url string) { + return "GET", fmt.Sprintf("search/%v", arg) + }, + } + + // methodOverrides contains overrides for troublesome endpoints. + methodOverrides = map[string]string{ + "OrganizationsService.EditOrgMembership: method orgs/%v/memberships/%v": "PUT", + "OrganizationsService.EditOrgMembership: PUT user/memberships/orgs/%v": "PATCH", + } + + paramRE = regexp.MustCompile(`:[a-z_]+`) +) + +type overrideFunc func(arg string) (httpMethod, url string) + +func logf(fmt string, args ...interface{}) { + if *verbose { + log.Printf(fmt, args...) + } +} + +type servicesMap map[string]*Service +type endpointsMap map[string]*Endpoint + +func main() { + flag.Parse() + fset := token.NewFileSet() + + sourceFilter := func(fi os.FileInfo) bool { + return !strings.HasSuffix(fi.Name(), "_test.go") && !strings.HasPrefix(fi.Name(), skipPrefix) + } + + if err := os.Chdir("./github"); err != nil { + log.Fatalf("Please run this from the go-github directory.") + } + + pkgs, err := parser.ParseDir(fset, ".", sourceFilter, parser.ParseComments) + if err != nil { + log.Fatal(err) + } + + // Step 1 - get a map of all services. + services := findAllServices(pkgs) + + // Step 2 - find all the API service endpoints. + iter := &realAstFileIterator{fset: fset, pkgs: pkgs} + endpoints, err := findAllServiceEndpoints(iter, services) + if err != nil { + log.Fatalf("\n%v", err) + } + + // Step 3 - resolve all missing httpMethods from helperMethods. + // Additionally, use existing URLs as hints to pre-cache all apiDocs. + docCache := &documentCache{} + usedHelpers, endpointsByFilename := resolveHelpersAndCacheDocs(endpoints, docCache) + + // Step 4 - validate and rewrite all URLs, skipping used helper methods. + frw := &liveFileRewriter{fset: fset} + validateRewriteURLs(usedHelpers, endpointsByFilename, docCache, frw) + + logf("Done.") +} + +type usedHelpersMap map[string]bool +type endpointsByFilenameMap map[string][]*Endpoint + +// FileRewriter read/writes files and converts AST token positions. +type FileRewriter interface { + Position(token.Pos) token.Position + ReadFile(filename string) ([]byte, error) + WriteFile(filename string, buf []byte, mode os.FileMode) error +} + +// liveFileRewriter implements FileRewriter. +type liveFileRewriter struct { + fset *token.FileSet +} + +func (lfr *liveFileRewriter) Position(pos token.Pos) token.Position { return lfr.fset.Position(pos) } +func (lfr *liveFileRewriter) ReadFile(filename string) ([]byte, error) { + return ioutil.ReadFile(filename) +} +func (lfr *liveFileRewriter) WriteFile(filename string, buf []byte, mode os.FileMode) error { + return ioutil.WriteFile(filename, buf, mode) +} + +func validateRewriteURLs(usedHelpers usedHelpersMap, endpointsByFilename endpointsByFilenameMap, docCache documentCacheReader, fileRewriter FileRewriter) { + for filename, slc := range endpointsByFilename { + logf("Step 4 - Processing %v methods in %v ...", len(slc), filename) + + var fileEdits []*FileEdit + for _, endpoint := range slc { + fullName := fmt.Sprintf("%v.%v", endpoint.serviceName, endpoint.endpointName) + if usedHelpers[fullName] { + logf("Step 4 - skipping used helper method %q", fullName) + continue + } + + // First, find the correct GitHub v3 API URL by httpMethod and urlFormat. + for _, path := range endpoint.urlFormats { + path = strings.ReplaceAll(path, "%d", "%v") + path = strings.ReplaceAll(path, "%s", "%v") + + // Check the overrides. + endpoint.checkHttpMethodOverride(path) + + methodAndPath := fmt.Sprintf("%v %v", endpoint.httpMethod, path) + url, ok := docCache.UrlByMethodAndPath(methodAndPath) + if !ok { + if i := len(endpoint.endpointComments); i > 0 { + pos := fileRewriter.Position(endpoint.endpointComments[i-1].Pos()) + fmt.Printf("%v:%v:%v: WARNING: unable to find online docs for %q: (%v)\nPLEASE CHECK MANUALLY AND FIX.\n", pos.Filename, pos.Line, pos.Column, fullName, methodAndPath) + } else { + fmt.Printf("%v: WARNING: unable to find online docs for %q: (%v)\nPLEASE CHECK MANUALLY AND FIX.\n", filename, fullName, methodAndPath) + } + continue + } + logf("found %q for: %q (%v)", url, fullName, methodAndPath) + + // Make sure URL is up-to-date. + switch { + case len(endpoint.enterpriseRefLines) > 1: + log.Printf("WARNING: multiple Enterprise GitHub URLs found - skipping: %#v", endpoint.enterpriseRefLines) + case len(endpoint.enterpriseRefLines) > 0: + line := fmt.Sprintf(enterpriseRefFmt, url) + cmt := endpoint.enterpriseRefLines[0] + if cmt.Text != line { + pos := fileRewriter.Position(cmt.Pos()) + logf("At byte offset %v:\nFOUND %q\nWANT: %q", pos.Offset, cmt.Text, line) + fileEdits = append(fileEdits, &FileEdit{ + pos: pos, + fromText: cmt.Text, + toText: line, + }) + } + case len(endpoint.stdRefLines) > 1: + var foundMatch bool + line := fmt.Sprintf(stdRefFmt, url) + for i, stdRefLine := range endpoint.stdRefLines { + if stdRefLine.Text == line { + foundMatch = true + logf("found match with %v, not editing and removing from list", line) + // Remove matching line + endpoint.stdRefLines = append(endpoint.stdRefLines[:i], endpoint.stdRefLines[i+1:]...) + break + } + } + if !foundMatch { // Edit last stdRefLine, then remove it. + cmt := endpoint.stdRefLines[len(endpoint.stdRefLines)-1] + pos := fileRewriter.Position(cmt.Pos()) + logf("stdRefLines=%v: At byte offset %v:\nFOUND %q\nWANT: %q", len(endpoint.stdRefLines), pos.Offset, cmt.Text, line) + fileEdits = append(fileEdits, &FileEdit{ + pos: pos, + fromText: cmt.Text, + toText: line, + }) + endpoint.stdRefLines = endpoint.stdRefLines[:len(endpoint.stdRefLines)-1] + } + case len(endpoint.stdRefLines) > 0: + line := fmt.Sprintf(stdRefFmt, url) + cmt := endpoint.stdRefLines[0] + if cmt.Text != line { + pos := fileRewriter.Position(cmt.Pos()) + logf("stdRefLines=1: At byte offset %v:\nFOUND %q\nWANT: %q", pos.Offset, cmt.Text, line) + fileEdits = append(fileEdits, &FileEdit{ + pos: pos, + fromText: cmt.Text, + toText: line, + }) + } + endpoint.stdRefLines = nil + case len(endpoint.endpointComments) > 0: + lastCmt := endpoint.endpointComments[len(endpoint.endpointComments)-1] + // logf("lastCmt.Text=%q (len=%v)", lastCmt.Text, len(lastCmt.Text)) + pos := fileRewriter.Position(lastCmt.Pos()) + pos.Offset += len(lastCmt.Text) + line := "\n" + fmt.Sprintf(stdRefFmt, url) + if lastCmt.Text != "//" { + line = "\n//" + line // Add blank comment line before URL. + } + // logf("line=%q (len=%v)", line, len(line)) + // logf("At byte offset %v: adding missing documentation:\n%q", pos.Offset, line) + fileEdits = append(fileEdits, &FileEdit{ + pos: pos, + fromText: "", + toText: line, + }) + default: // Missing documentation - add it. + log.Printf("WARNING: file %v has no godoc comment string for method %v", fullName, methodAndPath) + } + } + } + + if len(fileEdits) > 0 { + b, err := fileRewriter.ReadFile(filename) + if err != nil { + log.Fatalf("ReadFile: %v", err) + } + + log.Printf("Performing %v edits on file %v", len(fileEdits), filename) + b = performBufferEdits(b, fileEdits) + + if err := fileRewriter.WriteFile(filename, b, 0644); err != nil { + log.Fatalf("WriteFile: %v", err) + } + } + } +} + +func performBufferEdits(b []byte, fileEdits []*FileEdit) []byte { + fileEdits = sortAndMergeFileEdits(fileEdits) + + for _, edit := range fileEdits { + prelude := b[0:edit.pos.Offset] + postlude := b[edit.pos.Offset+len(edit.fromText):] + logf("At byte offset %v, replacing %v bytes with %v bytes\nBEFORE: %v\nAFTER : %v", edit.pos.Offset, len(edit.fromText), len(edit.toText), edit.fromText, edit.toText) + b = []byte(fmt.Sprintf("%s%v%s", prelude, edit.toText, postlude)) + } + + return b +} + +func sortAndMergeFileEdits(fileEdits []*FileEdit) []*FileEdit { + // Sort edits from last to first in the file. + // If the offsets are identical, sort the comment "toText" strings, ascending. + var foundDups bool + sort.Slice(fileEdits, func(a, b int) bool { + if fileEdits[a].pos.Offset == fileEdits[b].pos.Offset { + foundDups = true + return fileEdits[a].toText < fileEdits[b].toText + } + return fileEdits[a].pos.Offset > fileEdits[b].pos.Offset + }) + + if !foundDups { + return fileEdits + } + + // Merge the duplicate edits. + var mergedEdits []*FileEdit + var dupOffsets []*FileEdit + + mergeFunc := func() { + if len(dupOffsets) > 1 { + isInsert := dupOffsets[0].fromText == "" + var hasBlankCommentLine bool + + // Merge dups + var lines []string + for _, dup := range dupOffsets { + if isInsert && strings.HasPrefix(dup.toText, "\n//\n//") { + lines = append(lines, strings.TrimPrefix(dup.toText, "\n//")) + hasBlankCommentLine = true + } else { + lines = append(lines, dup.toText) + } + } + sort.Strings(lines) + + var joinStr string + // if insert, no extra newlines + if !isInsert { // if replacement - add newlines + joinStr = "\n" + } + toText := strings.Join(lines, joinStr) + if hasBlankCommentLine { // Add back in + toText = "\n//" + toText + } + mergedEdits = append(mergedEdits, &FileEdit{ + pos: dupOffsets[0].pos, + fromText: dupOffsets[0].fromText, + toText: toText, + }) + } else if len(dupOffsets) > 0 { + // Move non-dup to final output + mergedEdits = append(mergedEdits, dupOffsets[0]) + } + dupOffsets = nil + } + + lastOffset := -1 + for _, fileEdit := range fileEdits { + if fileEdit.pos.Offset != lastOffset { + mergeFunc() + } + dupOffsets = append(dupOffsets, fileEdit) + lastOffset = fileEdit.pos.Offset + } + mergeFunc() + return mergedEdits +} + +// astFileIterator iterates over all files in an ast.Package. +type astFileIterator interface { + // Finds the position of a token. + Position(token.Pos) token.Position + // Reset resets the iterator. + Reset() + // Next returns the next filenameAstFilePair pair or nil if done. + Next() *filenameAstFilePair +} + +type filenameAstFilePair struct { + filename string + astFile *ast.File +} + +// realAstFileIterator implements astFileIterator. +type realAstFileIterator struct { + fset *token.FileSet + pkgs map[string]*ast.Package + ch chan *filenameAstFilePair + closed bool +} + +func (rafi *realAstFileIterator) Position(pos token.Pos) token.Position { + return rafi.fset.Position(pos) +} + +func (rafi *realAstFileIterator) Reset() { + if !rafi.closed && rafi.ch != nil { + logf("Closing old channel on Reset") + close(rafi.ch) + } + rafi.ch = make(chan *filenameAstFilePair, 10) + rafi.closed = false + + go func() { + var count int + for _, pkg := range rafi.pkgs { + for filename, f := range pkg.Files { + logf("Sending file #%v: %v to channel", count, filename) + rafi.ch <- &filenameAstFilePair{filename: filename, astFile: f} + count++ + } + } + rafi.closed = true + close(rafi.ch) + logf("Closed channel after sending %v files", count) + if count == 0 { + log.Fatalf("Processed no files. Did you run this from the go-github directory?") + } + }() +} + +func (rafi *realAstFileIterator) Next() *filenameAstFilePair { + for pair := range rafi.ch { + logf("Next: returning file %v", pair.filename) + return pair + } + return nil +} + +func findAllServices(pkgs map[string]*ast.Package) servicesMap { + services := servicesMap{} + for _, pkg := range pkgs { + for filename, f := range pkg.Files { + if filename != "github.go" { + continue + } + + logf("Step 1 - Processing %v ...", filename) + if err := findClientServices(filename, f, services); err != nil { + log.Fatal(err) + } + } + } + return services +} + +func findAllServiceEndpoints(iter astFileIterator, services servicesMap) (endpointsMap, error) { + endpoints := endpointsMap{} + iter.Reset() + var errs []string // Collect all the errors and return in a big batch. + for next := iter.Next(); next != nil; next = iter.Next() { + filename, f := next.filename, next.astFile + if filename == "github.go" { + continue + } + + if *debugFile != "" && !strings.Contains(filename, *debugFile) { + continue + } + + logf("Step 2 - Processing %v ...", filename) + if err := processAST(filename, f, services, endpoints, iter); err != nil { + errs = append(errs, err.Error()) + } + } + + if len(errs) > 0 { + return nil, errors.New(strings.Join(errs, "\n")) + } + + return endpoints, nil +} + +func resolveHelpersAndCacheDocs(endpoints endpointsMap, docCache documentCacheWriter) (usedHelpers usedHelpersMap, endpointsByFilename endpointsByFilenameMap) { + usedHelpers = usedHelpersMap{} + endpointsByFilename = endpointsByFilenameMap{} + for k, v := range endpoints { + if _, ok := endpointsByFilename[v.filename]; !ok { + endpointsByFilename[v.filename] = []*Endpoint{} + } + endpointsByFilename[v.filename] = append(endpointsByFilename[v.filename], v) + + for _, cmt := range v.enterpriseRefLines { + docCache.CacheDocFromInternet(cmt.Text) + } + for _, cmt := range v.stdRefLines { + docCache.CacheDocFromInternet(cmt.Text) + } + + if v.httpMethod == "" && v.helperMethod != "" { + fullName := fmt.Sprintf("%v.%v", v.serviceName, v.helperMethod) + hm, ok := endpoints[fullName] + if !ok { + log.Fatalf("Unable to find helper method %q for %q", fullName, k) + } + if hm.httpMethod == "" { + log.Fatalf("Helper method %q for %q has empty httpMethod: %#v", fullName, k, hm) + } + v.httpMethod = hm.httpMethod + usedHelpers[fullName] = true + } + } + + return usedHelpers, endpointsByFilename +} + +type documentCacheReader interface { + UrlByMethodAndPath(string) (string, bool) +} + +type documentCacheWriter interface { + CacheDocFromInternet(urlWithFragmentID string) +} + +// documentCache implements documentCacheReader and documentCachWriter. +type documentCache struct { + apiDocs map[string]map[string][]*Endpoint // cached by URL, then mapped by web fragment identifier. + urlByMethodAndPath map[string]string +} + +func (dc *documentCache) UrlByMethodAndPath(methodAndPath string) (string, bool) { + url, ok := dc.urlByMethodAndPath[methodAndPath] + return url, ok +} + +func (dc *documentCache) CacheDocFromInternet(urlWithID string) { + if dc.apiDocs == nil { + dc.apiDocs = map[string]map[string][]*Endpoint{} // cached by URL, then mapped by web fragment identifier. + dc.urlByMethodAndPath = map[string]string{} + } + + url := getURL(urlWithID) + if _, ok := dc.apiDocs[url]; ok { + return // already cached + } + + // TODO: Enterprise URLs are currently causing problems - for example: + // GET https://developer.github.com/enterprise/v3/enterprise-admin/users/ + // returns StatusCode=404 + if strings.Contains(url, "enterprise") { + logf("Skipping troublesome Enterprise URL: %v", url) + return + } + + logf("GET %q ...", url) + resp, err := http.Get(url) + check("Unable to get URL: %v: %v", url, err) + if resp.StatusCode != http.StatusOK { + log.Fatalf("url %v - StatusCode=%v", url, resp.StatusCode) + } + + b, err := ioutil.ReadAll(resp.Body) + check("Unable to read body of URL: %v, %v", url, err) + check("Unable to close body of URL: %v, %v", url, resp.Body.Close()) + dc.apiDocs[url] = parseWebPageEndpoints(string(b)) + + // Now reverse-map the methods+paths to URLs. + for fragID, v := range dc.apiDocs[url] { + for _, endpoint := range v { + for _, path := range endpoint.urlFormats { + methodAndPath := fmt.Sprintf("%v %v", endpoint.httpMethod, path) + dc.urlByMethodAndPath[methodAndPath] = fmt.Sprintf("%v#%v", url, fragID) + logf("urlByMethodAndPath[%q] = %q", methodAndPath, dc.urlByMethodAndPath[methodAndPath]) + } + } + } +} + +// FileEdit represents an edit that needs to be performed on a file. +type FileEdit struct { + pos token.Position + fromText string + toText string +} + +func getURL(s string) string { + i := strings.Index(s, "http") + if i < 0 { + return "" + } + j := strings.Index(s, "#") + if j < i { + s = s[i:] + } else { + s = s[i:j] + } + if !strings.HasSuffix(s, "/") { // Prevent unnecessary redirects if possible. + s += "/" + } + return s +} + +// Service represents a go-github service. +type Service struct { + serviceName string +} + +// Endpoint represents an API endpoint in this repo. +type Endpoint struct { + endpointName string + filename string + serviceName string + urlFormats []string + httpMethod string + helperMethod string // If populated, httpMethod lives in helperMethod. + + enterpriseRefLines []*ast.Comment + stdRefLines []*ast.Comment + endpointComments []*ast.Comment +} + +// String helps with debugging by providing an easy-to-read summary of the endpoint. +func (e *Endpoint) String() string { + var b strings.Builder + b.WriteString(fmt.Sprintf(" filename: %v\n", e.filename)) + b.WriteString(fmt.Sprintf(" serviceName: %v\n", e.serviceName)) + b.WriteString(fmt.Sprintf(" endpointName: %v\n", e.endpointName)) + b.WriteString(fmt.Sprintf(" httpMethod: %v\n", e.httpMethod)) + if e.helperMethod != "" { + b.WriteString(fmt.Sprintf(" helperMethod: %v\n", e.helperMethod)) + } + for i := 0; i < len(e.urlFormats); i++ { + b.WriteString(fmt.Sprintf(" urlFormats[%v]: %v\n", i, e.urlFormats[i])) + } + for i := 0; i < len(e.enterpriseRefLines); i++ { + b.WriteString(fmt.Sprintf(" enterpriseRefLines[%v]: comment: %v\n", i, e.enterpriseRefLines[i].Text)) + } + for i := 0; i < len(e.stdRefLines); i++ { + b.WriteString(fmt.Sprintf(" stdRefLines[%v]: comment: %v\n", i, e.stdRefLines[i].Text)) + } + return b.String() +} + +func (ep *Endpoint) checkHttpMethodOverride(path string) { + lookupOverride := fmt.Sprintf("%v.%v: %v %v", ep.serviceName, ep.endpointName, ep.httpMethod, path) + logf("Looking up override for %q", lookupOverride) + if v, ok := methodOverrides[lookupOverride]; ok { + logf("overriding method for %v to %q", lookupOverride, v) + ep.httpMethod = v + return + } +} + +func processAST(filename string, f *ast.File, services servicesMap, endpoints endpointsMap, iter astFileIterator) error { + var errs []string + + for _, decl := range f.Decls { + switch decl := decl.(type) { + case *ast.FuncDecl: // Doc, Recv, Name, Type, Body + if decl.Recv == nil || len(decl.Recv.List) != 1 || decl.Name == nil || decl.Body == nil { + continue + } + + recv := decl.Recv.List[0] + se, ok := recv.Type.(*ast.StarExpr) // Star, X + if !ok || se.X == nil || len(recv.Names) != 1 { + if decl.Name.Name != "String" && decl.Name.Name != "Equal" && decl.Name.Name != "IsPullRequest" { + pos := iter.Position(recv.Pos()) + if id, ok := recv.Type.(*ast.Ident); ok { + pos = iter.Position(id.Pos()) + } + errs = append(errs, fmt.Sprintf("%v:%v:%v: method %v does not use a pointer receiver and needs fixing!", pos.Filename, pos.Line, pos.Column, decl.Name)) + } + continue + } + recvType, ok := se.X.(*ast.Ident) // NamePos, Name, Obj + if !ok { + return fmt.Errorf("unhandled se.X = %T", se.X) + } + serviceName := recvType.Name + if _, ok := services[serviceName]; !ok { + continue + } + endpointName := decl.Name.Name + fullName := fmt.Sprintf("%v.%v", serviceName, endpointName) + if methodBlacklist[fullName] { + logf("skipping %v", fullName) + continue + } + + receiverName := recv.Names[0].Name + + logf("ast.FuncDecl: %#v", *decl) // Doc, Recv, Name, Type, Body + logf("ast.FuncDecl.Name: %#v", *decl.Name) // NamePos, Name, Obj(nil) + // logf("ast.FuncDecl.Recv: %#v", *decl.Recv) // Opening, List, Closing + logf("ast.FuncDecl.Recv.List[0]: %#v", *recv) // Doc, Names, Type, Tag, Comment + // for i, name := range decl.Recv.List[0].Names { + // logf("recv.name[%v] = %v", i, name.Name) + // } + logf("recvType = %#v", recvType) + var enterpriseRefLines []*ast.Comment + var stdRefLines []*ast.Comment + var endpointComments []*ast.Comment + if decl.Doc != nil { + endpointComments = decl.Doc.List + for i, comment := range decl.Doc.List { + logf("doc.comment[%v] = %#v", i, *comment) + if strings.Contains(comment.Text, enterpriseURL) { + enterpriseRefLines = append(enterpriseRefLines, comment) + } else if strings.Contains(comment.Text, stdURL) { + stdRefLines = append(stdRefLines, comment) + } + } + logf("%v comment lines, %v enterprise URLs, %v standard URLs", len(decl.Doc.List), len(enterpriseRefLines), len(stdRefLines)) + } + + bd := &bodyData{receiverName: receiverName} + if err := bd.parseBody(decl.Body); err != nil { // Lbrace, List, Rbrace + return fmt.Errorf("parseBody: %v", err) + } + + ep := &Endpoint{ + endpointName: endpointName, + filename: filename, + serviceName: serviceName, + urlFormats: bd.urlFormats, + httpMethod: bd.httpMethod, + helperMethod: bd.helperMethod, + enterpriseRefLines: enterpriseRefLines, + stdRefLines: stdRefLines, + endpointComments: endpointComments, + } + // ep.checkHttpMethodOverride("") + endpoints[fullName] = ep + logf("endpoints[%q] = %#v", fullName, endpoints[fullName]) + if ep.httpMethod == "" && (ep.helperMethod == "" || len(ep.urlFormats) == 0) { + return fmt.Errorf("could not find body info: %#v", *ep) + } + case *ast.GenDecl: + default: + return fmt.Errorf("unhandled decl type: %T", decl) + } + } + + if len(errs) > 0 { + return errors.New(strings.Join(errs, "\n")) + } + + return nil +} + +// bodyData contains information found in a BlockStmt. +type bodyData struct { + receiverName string // receiver name of method to help identify helper methods. + httpMethod string + urlVarName string + urlFormats []string + assignments []lhsrhs + helperMethod string // If populated, httpMethod lives in helperMethod. +} + +func (b *bodyData) parseBody(body *ast.BlockStmt) error { + logf("body=%#v", *body) + + // Find the variable used for the format string, its one-or-more values, + // and the httpMethod used for the NewRequest. + for _, stmt := range body.List { + switch stmt := stmt.(type) { + case *ast.AssignStmt: + hm, uvn, hlp, asgn := processAssignStmt(b.receiverName, stmt) + if b.httpMethod != "" && hm != "" && b.httpMethod != hm { + return fmt.Errorf("found two httpMethod values: %q and %q", b.httpMethod, hm) + } + if hm != "" { + b.httpMethod = hm + // logf("parseBody: httpMethod=%v", b.httpMethod) + } + if hlp != "" { + b.helperMethod = hlp + } + b.assignments = append(b.assignments, asgn...) + // logf("assignments=%#v", b.assignments) + if b.urlVarName == "" && uvn != "" { + b.urlVarName = uvn + // logf("parseBody: urlVarName=%v", b.urlVarName) + // By the time the urlVarName is found, all assignments should + // have already taken place so that we can find the correct + // ones and determine the urlFormats. + for _, lr := range b.assignments { + if lr.lhs == b.urlVarName { + b.urlFormats = append(b.urlFormats, lr.rhs) + logf("found urlFormat: %v", lr.rhs) + } + } + } + case *ast.DeclStmt: + logf("*ast.DeclStmt: %#v", *stmt) + case *ast.DeferStmt: + logf("*ast.DeferStmt: %#v", *stmt) + case *ast.ExprStmt: + logf("*ast.ExprStmt: %#v", *stmt) + case *ast.IfStmt: + if err := b.parseIf(stmt); err != nil { + return err + } + case *ast.RangeStmt: + logf("*ast.RangeStmt: %#v", *stmt) + case *ast.ReturnStmt: // Return Results + logf("*ast.ReturnStmt: %#v", *stmt) + if len(stmt.Results) > 0 { + ce, ok := stmt.Results[0].(*ast.CallExpr) + if ok { + recv, funcName, args := processCallExpr(ce) + logf("return CallExpr: recv=%q, funcName=%q, args=%#v", recv, funcName, args) + // If the httpMethod has not been found at this point, but + // this method is calling a helper function, then see if + // any of its arguments match a previous assignment, then + // record the urlFormat and remember the helper method. + if b.httpMethod == "" && len(args) > 1 && recv == b.receiverName { + if args[0] != "ctx" { + return fmt.Errorf("expected helper function to get ctx as first arg: %#v, %#v", args, *b) + } + if len(b.assignments) == 0 && len(b.urlFormats) == 0 { + b.urlFormats = append(b.urlFormats, strings.Trim(args[1], `"`)) + b.helperMethod = funcName + logf("found urlFormat: %v and helper method: %v", b.urlFormats[0], b.helperMethod) + } else { + for _, lr := range b.assignments { + if lr.lhs == args[1] { // Multiple matches are possible. Loop over all assignments. + b.urlVarName = args[1] + b.urlFormats = append(b.urlFormats, lr.rhs) + b.helperMethod = funcName + logf("found urlFormat: %v and helper method: %v", lr.rhs, b.helperMethod) + } + } + } + } + } + } + case *ast.SwitchStmt: + logf("*ast.SwitchStmt: %#v", *stmt) + default: + return fmt.Errorf("unhandled stmt type: %T", stmt) + } + } + logf("parseBody: assignments=%#v", b.assignments) + + return nil +} + +func (b *bodyData) parseIf(stmt *ast.IfStmt) error { + logf("*ast.IfStmt: %#v", *stmt) + if err := b.parseBody(stmt.Body); err != nil { + return err + } + logf("if body: b=%#v", *b) + if stmt.Else != nil { + switch els := stmt.Else.(type) { + case *ast.BlockStmt: + if err := b.parseBody(els); err != nil { + return err + } + logf("if else: b=%#v", *b) + case *ast.IfStmt: + if err := b.parseIf(els); err != nil { + return err + } + default: + return fmt.Errorf("unhandled else stmt type %T", els) + } + } + + return nil +} + +// lhsrhs represents an assignment with a variable name on the left +// and a string on the right - used to find the URL format string. +type lhsrhs struct { + lhs string + rhs string +} + +func processAssignStmt(receiverName string, stmt *ast.AssignStmt) (httpMethod, urlVarName, helperMethod string, assignments []lhsrhs) { + logf("*ast.AssignStmt: %#v", *stmt) // Lhs, TokPos, Tok, Rhs + var lhs []string + for _, expr := range stmt.Lhs { + switch expr := expr.(type) { + case *ast.Ident: // NamePos, Name, Obj + logf("processAssignStmt: *ast.Ident: %#v", expr) + lhs = append(lhs, expr.Name) + case *ast.SelectorExpr: // X, Sel + logf("processAssignStmt: *ast.SelectorExpr: %#v", expr) + default: + log.Fatalf("unhandled AssignStmt Lhs type: %T", expr) + } + } + + for i, expr := range stmt.Rhs { + switch expr := expr.(type) { + case *ast.BasicLit: // ValuePos, Kind, Value + v := strings.Trim(expr.Value, `"`) + if !strings.HasPrefix(v, "?") { // Hack to remove "?recursive=1" + assignments = append(assignments, lhsrhs{lhs: lhs[i], rhs: v}) + } + case *ast.BinaryExpr: + logf("processAssignStmt: *ast.BinaryExpr: %#v", *expr) + case *ast.CallExpr: // Fun, Lparen, Args, Ellipsis, Rparen + recv, funcName, args := processCallExpr(expr) + logf("processAssignStmt: CallExpr: recv=%q, funcName=%q, args=%#v", recv, funcName, args) + switch funcName { + case "addOptions": + if v := strings.Trim(args[0], `"`); v != args[0] { + assignments = append(assignments, lhsrhs{lhs: lhs[i], rhs: v}) + urlVarName = lhs[i] + } else { + urlVarName = args[0] + } + case "Sprintf": + assignments = append(assignments, lhsrhs{lhs: lhs[i], rhs: strings.Trim(args[0], `"`)}) + case "NewRequest": + httpMethod = strings.Trim(args[0], `"`) + urlVarName = args[1] + case "NewUploadRequest": + httpMethod = "POST" + urlVarName = args[0] + } + if recv == receiverName && len(args) > 1 && args[0] == "ctx" { // This might be a helper method. + fullName := fmt.Sprintf("%v.%v", recv, funcName) + logf("checking for override: fullName=%v", fullName) + if fn, ok := helperOverrides[fullName]; ok { + logf("found helperOverride for %v", fullName) + hm, url := fn(strings.Trim(args[1], `"`)) + httpMethod = hm + urlVarName = "u" // arbitrary + assignments = []lhsrhs{{lhs: urlVarName, rhs: url}} + } else { + urlVarName = args[1] // For this to work correctly, the URL must be the second arg to the helper method! + helperMethod = funcName + logf("found possible helper method: funcName=%v, urlVarName=%v", funcName, urlVarName) + } + } + case *ast.CompositeLit: // Type, Lbrace, Elts, Rbrace, Incomplete + logf("processAssignStmt: *ast.CompositeLit: %#v", *expr) + case *ast.FuncLit: + logf("processAssignStmt: *ast.FuncLit: %#v", *expr) + case *ast.SelectorExpr: + logf("processAssignStmt: *ast.SelectorExpr: %#v", *expr) + case *ast.UnaryExpr: // OpPos, Op, X + logf("processAssignStmt: *ast.UnaryExpr: %#v", *expr) + default: + log.Fatalf("unhandled AssignStmt Rhs type: %T", expr) + } + } + logf("urlVarName=%v, assignments=%#v", urlVarName, assignments) + + return httpMethod, urlVarName, helperMethod, assignments +} + +func processCallExpr(expr *ast.CallExpr) (recv, funcName string, args []string) { + logf("*ast.CallExpr: %#v", *expr) + + for _, arg := range expr.Args { + switch arg := arg.(type) { + case *ast.ArrayType: + logf("processCallExpr: *ast.ArrayType: %#v", arg) + case *ast.BasicLit: // ValuePos, Kind, Value + args = append(args, arg.Value) // Do not trim quotes here so as to identify it later as a string literal. + case *ast.CallExpr: // Fun, Lparen, Args, Ellipsis, Rparen + logf("processCallExpr: *ast.CallExpr: %#v", arg) + r, fn, as := processCallExpr(arg) + if r == "fmt" && fn == "Sprintf" && len(as) > 0 { // Special case - return format string. + args = append(args, as[0]) + } + case *ast.Ident: // NamePos, Name, Obj + args = append(args, arg.Name) + case *ast.MapType: + logf("processCallExpr: *ast.MapType: %#v", arg) + case *ast.SelectorExpr: // X, Sel + logf("processCallExpr: *ast.SelectorExpr: %#v", arg) + x, ok := arg.X.(*ast.Ident) + if ok { // special case + switch name := fmt.Sprintf("%v.%v", x.Name, arg.Sel.Name); name { + case "http.MethodGet": + args = append(args, http.MethodGet) + case "http.MethodHead": + args = append(args, http.MethodHead) + case "http.MethodPost": + args = append(args, http.MethodPost) + case "http.MethodPut": + args = append(args, http.MethodPut) + case "http.MethodPatch": + args = append(args, http.MethodPatch) + case "http.MethodDelete": + args = append(args, http.MethodDelete) + case "http.MethodConnect": + args = append(args, http.MethodConnect) + case "http.MethodOptions": + args = append(args, http.MethodOptions) + case "http.MethodTrace": + args = append(args, http.MethodTrace) + default: + args = append(args, name) + } + } + case *ast.StarExpr: + logf("processCallExpr: *ast.StarExpr: %#v", arg) + case *ast.StructType: + logf("processCallExpr: *ast.StructType: %#v", arg) + case *ast.UnaryExpr: // OpPos, Op, X + switch x := arg.X.(type) { + case *ast.Ident: + args = append(args, x.Name) + case *ast.CompositeLit: // Type, Lbrace, Elts, Rbrace, Incomplete + logf("processCallExpr: *ast.CompositeLit: %#v", x) + default: + log.Fatalf("processCallExpr: unhandled UnaryExpr.X arg type: %T", arg.X) + } + default: + log.Fatalf("processCallExpr: unhandled arg type: %T", arg) + } + } + + switch fun := expr.Fun.(type) { + case *ast.Ident: // NamePos, Name, Obj + funcName = fun.Name + case *ast.SelectorExpr: // X, Sel + funcName = fun.Sel.Name + switch x := fun.X.(type) { + case *ast.Ident: // NamePos, Name, Obj + logf("processCallExpr: X recv *ast.Ident=%#v", x) + recv = x.Name + case *ast.ParenExpr: + logf("processCallExpr: X recv *ast.ParenExpr: %#v", x) + case *ast.SelectorExpr: // X, Sel + logf("processCallExpr: X recv *ast.SelectorExpr: %#v", x.Sel) + recv = x.Sel.Name + default: + log.Fatalf("processCallExpr: unhandled X receiver type: %T", x) + } + default: + log.Fatalf("processCallExpr: unhandled Fun: %T", expr.Fun) + } + + return recv, funcName, args +} + +// findClientServices finds all go-github services from the Client struct. +func findClientServices(filename string, f *ast.File, services servicesMap) error { + for _, decl := range f.Decls { + switch decl := decl.(type) { + case *ast.GenDecl: + if decl.Tok != token.TYPE || len(decl.Specs) != 1 { + continue + } + ts, ok := decl.Specs[0].(*ast.TypeSpec) + if !ok || decl.Doc == nil || ts.Name == nil || ts.Type == nil || ts.Name.Name != "Client" { + continue + } + st, ok := ts.Type.(*ast.StructType) + if !ok || st.Fields == nil || len(st.Fields.List) == 0 { + continue + } + + for _, field := range st.Fields.List { + se, ok := field.Type.(*ast.StarExpr) + if !ok || se.X == nil || len(field.Names) != 1 { + continue + } + id, ok := se.X.(*ast.Ident) + if !ok { + continue + } + name := id.Name + if !strings.HasSuffix(name, "Service") { + continue + } + + services[name] = &Service{serviceName: name} + } + + return nil // Found all services in Client struct. + } + } + + return fmt.Errorf("unable to find Client struct in github.go") +} + +func check(fmtStr string, args ...interface{}) { + if err := args[len(args)-1]; err != nil { + log.Fatalf(fmtStr, args...) + } +} + +// parseWebPageEndpoints returns endpoint information, mapped by +// web page fragment identifier. +func parseWebPageEndpoints(buf string) map[string][]*Endpoint { + result := map[string][]*Endpoint{} + + // The GitHub v3 API web pages do not appear to be auto-generated + // and therefore, the XML decoder is too strict to reliably parse them. + // Here is a tiny example where the XML decoder completely fails + // due to mal-formed HTML: + // + // + // + // ... + // + + parts := strings.Split(buf, "") + var lastFragmentID string + for _, part := range parts { + for _, method := range httpMethods { + if strings.HasPrefix(part, method) { + eol := strings.Index(part, "\n") + if eol < 0 { + eol = len(part) + } + if v := strings.Index(part, "<"); v > len(method) && v < eol { + eol = v + } + if v := strings.Index(part, "{"); v > len(method) && v < eol { + eol = v + } + path := strings.TrimSpace(part[len(method):eol]) + if strings.HasPrefix(path, ":server") { // Hack to remove :server + path = strings.TrimPrefix(path, ":server") + } + path = paramRE.ReplaceAllString(path, "%v") + // strip leading garbage + if i := strings.Index(path, "/"); i >= 0 { + path = path[i+1:] + } + path = strings.TrimSuffix(path, ".") + logf("Found %v %v", method, path) + result[lastFragmentID] = append(result[lastFragmentID], &Endpoint{ + urlFormats: []string{path}, + httpMethod: method, + }) + } + } + + if i := strings.LastIndex(part, "= 0 { + lastFragmentID = b[:i] + logf("Found lastFragmentID: %v", lastFragmentID) + } + } + } + + return result +} + +var httpMethods = []string{ + "GET", + "HEAD", + "POST", + "PUT", + "PATCH", + "DELETE", + "CONNECT", + "OPTIONS", + "TRACE", +} diff --git a/update-urls/main_test.go b/update-urls/main_test.go new file mode 100644 index 00000000000..e77411a022c --- /dev/null +++ b/update-urls/main_test.go @@ -0,0 +1,563 @@ +// Copyright 2020 The go-github AUTHORS. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +import ( + "fmt" + "go/parser" + "go/token" + "os" + "reflect" + "regexp" + "strings" + "testing" + + "github.com/pmezard/go-difflib/difflib" +) + +type pipelineSetup struct { + // Fields filled in by the unit test: + baseURL string + endpointsFromWebsite endpointsByFragmentID + filename string + serviceName string + originalGoSource string + wantGoSource string + wantNumEndpoints int + + // Fields filled in by setup: + docCache *fakeDocCache + fileRewriter *fakeFileRewriter + iter *fakeAstFileIterator + services servicesMap + wantFailure bool +} + +func (ps *pipelineSetup) setup(t *testing.T, stripURLs, destroyReceiverPointers bool) *pipelineSetup { + t.Helper() + + if stripURLs { + // For every GitHub API doc URL, remove it from the original source, + // and alternate between stripping the previous blank comment line and not. + for removeBlank := false; true; removeBlank = !removeBlank { + var changes bool + if removeBlank { + ps.originalGoSource, changes = removeNextURLAndOptionalBlank(ps.originalGoSource) + } else { + ps.originalGoSource, changes = removeNextURLLineOnly(ps.originalGoSource) + } + if !changes { + break + } + } + // log.Printf("Modified Go Source:\n%v", ps.originalGoSource) + } + + if destroyReceiverPointers { + from := fmt.Sprintf(" *%v) ", ps.serviceName) + to := fmt.Sprintf(" %v) ", ps.serviceName) + ps.originalGoSource = strings.ReplaceAll(ps.originalGoSource, from, to) + ps.wantFailure = true // receiver pointers must be fixed before running. + } + + ps.docCache = &fakeDocCache{ + t: t, + baseURL: ps.baseURL, + endpoints: ps.endpointsFromWebsite, + } + fset := token.NewFileSet() + ps.fileRewriter = &fakeFileRewriter{fset: fset, in: ps.originalGoSource} + ps.services = servicesMap{ps.serviceName: &Service{serviceName: ps.serviceName}} + astFile, err := parser.ParseFile(fset, ps.filename, ps.originalGoSource, parser.ParseComments) + if err != nil { + t.Fatalf("ParseFile: %v", err) + } + ps.iter = &fakeAstFileIterator{ + fset: fset, + orig: &filenameAstFilePair{ + filename: ps.filename, + astFile: astFile, + }, + } + + return ps +} + +func (ps *pipelineSetup) validate(t *testing.T) { + t.Helper() + + // Call pipeline + endpoints, err := findAllServiceEndpoints(ps.iter, ps.services) + if ps.wantFailure { + if err != nil { + // test successful - receivers must be pointers first + return + } + t.Fatalf("Expected non-pointer receivers to fail parsing, but no error was raised") + } + if err != nil { + t.Fatalf("Fail detected but not expected: %v", err) + } + + // log.Printf("endpoints=%#v (%v)", endpoints, len(endpoints)) + if len(endpoints) != ps.wantNumEndpoints { + t.Errorf("got %v endpoints, want %v", len(endpoints), ps.wantNumEndpoints) + } + usedHelpers, endpointsByFilename := resolveHelpersAndCacheDocs(endpoints, ps.docCache) + // log.Printf("endpointsByFilename=%#v (%v)", endpointsByFilename, len(endpointsByFilename[ps.filename])) + if len(endpointsByFilename[ps.filename]) != ps.wantNumEndpoints { + t.Errorf("got %v endpointsByFilename, want %v", len(endpointsByFilename[ps.filename]), ps.wantNumEndpoints) + } + validateRewriteURLs(usedHelpers, endpointsByFilename, ps.docCache, ps.fileRewriter) + + if ps.fileRewriter.out == "" { + t.Fatalf("No modifications were made to the file") + } + + if ps.fileRewriter.out != ps.wantGoSource { + diff := difflib.ContextDiff{ + A: difflib.SplitLines(ps.fileRewriter.out), + B: difflib.SplitLines(ps.wantGoSource), + FromFile: "got", + ToFile: "want", + Context: 1, + Eol: "\n", + } + result, _ := difflib.GetContextDiffString(diff) + t.Errorf(strings.Replace(result, "\t", " ", -1)) + } +} + +var ( + urlWithBlankCommentRE = regexp.MustCompile(`(//\n)?// GitHub API docs: [^\n]+\n`) + urlLineOnlyRE = regexp.MustCompile(`// GitHub API docs: [^\n]+\n`) +) + +func removeNextURLAndOptionalBlank(s string) (string, bool) { + parts := urlWithBlankCommentRE.Split(s, 2) + if len(parts) == 1 { + return parts[0], false + } + return parts[0] + parts[1], true +} + +func TestRemoveNextURLAndOptionalBlank(t *testing.T) { + tests := []struct { + name string + s string + want string + changes bool + }{ + {name: "empty string"}, + {name: "no URLs", s: "// line 1\n//\n// line 3", want: "// line 1\n//\n// line 3"}, + { + name: "URL without prior blank comment", + s: "// line 1\n// GitHub API docs: yeah\nfunc MyFunc() {\n", + want: "// line 1\nfunc MyFunc() {\n", + changes: true, + }, + { + name: "URL with prior blank comment", + s: "// line 1\n//\n// GitHub API docs: yeah\nfunc MyFunc() {\n", + want: "// line 1\nfunc MyFunc() {\n", + changes: true, + }, + } + + for i, tt := range tests { + t.Run(fmt.Sprintf("test #%v: %v", i, tt.name), func(t *testing.T) { + got, changes := removeNextURLAndOptionalBlank(tt.s) + if got != tt.want { + t.Errorf("got = %v, want %v", got, tt.want) + } + if changes != tt.changes { + t.Errorf("got changes = %v, want %v", changes, tt.changes) + } + }) + } +} + +func removeNextURLLineOnly(s string) (string, bool) { + parts := urlLineOnlyRE.Split(s, 2) + if len(parts) == 1 { + return parts[0], false + } + return parts[0] + parts[1], true +} + +func TestRemoveNextURLLineOnly(t *testing.T) { + tests := []struct { + name string + s string + want string + changes bool + }{ + {name: "empty string"}, + {name: "no URLs", s: "// line 1\n//\n// line 3", want: "// line 1\n//\n// line 3"}, + { + name: "URL without prior blank comment", + s: "// line 1\n// GitHub API docs: yeah\nfunc MyFunc() {\n", + want: "// line 1\nfunc MyFunc() {\n", + changes: true, + }, + { + name: "URL with prior blank comment", + s: "// line 1\n//\n// GitHub API docs: yeah\nfunc MyFunc() {\n", + want: "// line 1\n//\nfunc MyFunc() {\n", + changes: true, + }, + } + + for i, tt := range tests { + t.Run(fmt.Sprintf("test #%v: %v", i, tt.name), func(t *testing.T) { + got, changes := removeNextURLLineOnly(tt.s) + if got != tt.want { + t.Errorf("got = %v, want %v", got, tt.want) + } + if changes != tt.changes { + t.Errorf("got changes = %v, want %v", changes, tt.changes) + } + }) + } +} + +type endpointsByFragmentID map[string][]*Endpoint + +// fakeDocCache implements documentCacheReader and documentCacheWriter. +type fakeDocCache struct { + t *testing.T + baseURL string + endpoints endpointsByFragmentID +} + +func (f *fakeDocCache) UrlByMethodAndPath(methodAndPath string) (string, bool) { + for fragmentID, endpoints := range f.endpoints { + for _, endpoint := range endpoints { + for _, urlFormat := range endpoint.urlFormats { + key := fmt.Sprintf("%v %v", endpoint.httpMethod, urlFormat) + if key == methodAndPath { + url := fmt.Sprintf("%v#%v", f.baseURL, fragmentID) + // log.Printf("UrlByMethodAndPath(%q) = (%q, true)", methodAndPath, url) + return url, true + } + } + } + } + f.t.Fatalf("fakeDocCache.UrlByMethodAndPath: unable to find method %v", methodAndPath) + return "", false +} + +func (f *fakeDocCache) CacheDocFromInternet(url string) {} // no-op + +// fakeFileRewriter implements FileRewriter. +type fakeFileRewriter struct { + fset *token.FileSet + in string + out string +} + +func (f *fakeFileRewriter) Position(pos token.Pos) token.Position { + return f.fset.Position(pos) +} + +func (f *fakeFileRewriter) ReadFile(filename string) ([]byte, error) { + return []byte(f.in), nil +} + +func (f *fakeFileRewriter) WriteFile(filename string, buf []byte, mode os.FileMode) error { + f.out = string(buf) + return nil +} + +// fakeAstFileIterator implements astFileIterator. +type fakeAstFileIterator struct { + orig, next *filenameAstFilePair + fset *token.FileSet +} + +func (f *fakeAstFileIterator) Position(pos token.Pos) token.Position { return f.fset.Position(pos) } +func (f *fakeAstFileIterator) Reset() { f.next = f.orig } +func (f *fakeAstFileIterator) Next() *filenameAstFilePair { + v := f.next + f.next = nil + return v +} + +func TestSortAndMergeFileEdits(t *testing.T) { + tests := []struct { + name string + fileEdits []*FileEdit + want []*FileEdit + }{ + {name: "no edits"}, + { + name: "one edit", + fileEdits: []*FileEdit{ + {toText: "one edit"}, + }, + want: []*FileEdit{ + {toText: "one edit"}, + }, + }, + { + name: "two inserts at same offset - no extra blank comment", + fileEdits: []*FileEdit{ + {pos: token.Position{Offset: 2}, fromText: "", toText: "\n// one insert"}, + {pos: token.Position{Offset: 2}, fromText: "", toText: "\n// second insert"}, + }, + want: []*FileEdit{ + {pos: token.Position{Offset: 2}, toText: "\n// one insert\n// second insert"}, + }, + }, + { + name: "two inserts at same offset - strip extra blank comment", + fileEdits: []*FileEdit{ + {pos: token.Position{Offset: 2}, fromText: "", toText: "\n//\n// one insert"}, + {pos: token.Position{Offset: 2}, fromText: "", toText: "\n//\n// second insert"}, + }, + want: []*FileEdit{ + {pos: token.Position{Offset: 2}, toText: "\n//\n// one insert\n// second insert"}, + }, + }, + { + name: "two non-overlapping edits, low offset to high", + fileEdits: []*FileEdit{ + {fromText: ".", pos: token.Position{Offset: 0}, toText: "edit one"}, + {fromText: ".", pos: token.Position{Offset: 100}, toText: "edit two"}, + }, + want: []*FileEdit{ + {fromText: ".", pos: token.Position{Offset: 100}, toText: "edit two"}, + {fromText: ".", pos: token.Position{Offset: 0}, toText: "edit one"}, + }, + }, + { + name: "two non-overlapping edits, high offset to low", + fileEdits: []*FileEdit{ + {fromText: ".", pos: token.Position{Offset: 100}, toText: "edit two"}, + {fromText: ".", pos: token.Position{Offset: 0}, toText: "edit one"}, + }, + want: []*FileEdit{ + {fromText: ".", pos: token.Position{Offset: 100}, toText: "edit two"}, + {fromText: ".", pos: token.Position{Offset: 0}, toText: "edit one"}, + }, + }, + { + name: "two overlapping edits, text low to high", + fileEdits: []*FileEdit{ + {fromText: ".", toText: "edit 0"}, + {fromText: ".", toText: "edit 1"}, + }, + want: []*FileEdit{ + {fromText: ".", toText: "edit 0\nedit 1"}, + }, + }, + { + name: "two overlapping edits, text high to low", + fileEdits: []*FileEdit{ + {fromText: ".", toText: "edit 1"}, + {fromText: ".", toText: "edit 0"}, + }, + want: []*FileEdit{ + {fromText: ".", toText: "edit 0\nedit 1"}, + }, + }, + { + name: "dup, non-dup", + fileEdits: []*FileEdit{ + {fromText: ".", toText: "edit 1"}, + {fromText: ".", toText: "edit 0"}, + {fromText: ".", pos: token.Position{Offset: 100}, toText: "edit 2"}, + }, + want: []*FileEdit{ + {fromText: ".", pos: token.Position{Offset: 100}, toText: "edit 2"}, + {fromText: ".", toText: "edit 0\nedit 1"}, + }, + }, + { + name: "non-dup, dup", + fileEdits: []*FileEdit{ + {fromText: ".", toText: "edit 2"}, + {fromText: ".", pos: token.Position{Offset: 100}, toText: "edit 1"}, + {fromText: ".", pos: token.Position{Offset: 100}, toText: "edit 0"}, + }, + want: []*FileEdit{ + {fromText: ".", pos: token.Position{Offset: 100}, toText: "edit 0\nedit 1"}, + {fromText: ".", toText: "edit 2"}, + }, + }, + { + name: "dup, non-dup, dup", + fileEdits: []*FileEdit{ + {fromText: ".", toText: "edit 1"}, + {fromText: ".", toText: "edit 0"}, + {fromText: ".", pos: token.Position{Offset: 100}, toText: "edit 2"}, + {fromText: ".", pos: token.Position{Offset: 200}, toText: "edit 4"}, + {fromText: ".", pos: token.Position{Offset: 200}, toText: "edit 3"}, + }, + want: []*FileEdit{ + {fromText: ".", pos: token.Position{Offset: 200}, toText: "edit 3\nedit 4"}, + {fromText: ".", pos: token.Position{Offset: 100}, toText: "edit 2"}, + {fromText: ".", toText: "edit 0\nedit 1"}, + }, + }, + { + name: "non-dup, dup, non-dup", + fileEdits: []*FileEdit{ + {fromText: ".", toText: "edit 2"}, + {fromText: ".", pos: token.Position{Offset: 100}, toText: "edit 1"}, + {fromText: ".", pos: token.Position{Offset: 100}, toText: "edit 0"}, + {fromText: ".", pos: token.Position{Offset: 200}, toText: "edit 3"}, + }, + want: []*FileEdit{ + {fromText: ".", pos: token.Position{Offset: 200}, toText: "edit 3"}, + {fromText: ".", pos: token.Position{Offset: 100}, toText: "edit 0\nedit 1"}, + {fromText: ".", toText: "edit 2"}, + }, + }, + { + name: "triplet, non-dup", + fileEdits: []*FileEdit{ + {fromText: ".", toText: "edit 1"}, + {fromText: ".", toText: "edit 0"}, + {fromText: ".", toText: "edit 2"}, + {fromText: ".", pos: token.Position{Offset: 100}, toText: "edit 3"}, + }, + want: []*FileEdit{ + {fromText: ".", pos: token.Position{Offset: 100}, toText: "edit 3"}, + {fromText: ".", toText: "edit 0\nedit 1\nedit 2"}, + }, + }, + } + + for i, tt := range tests { + t.Run(fmt.Sprintf("test #%v: %v", i, tt.name), func(t *testing.T) { + got := sortAndMergeFileEdits(tt.fileEdits) + + if len(got) != len(tt.want) { + t.Errorf("len(got) = %v, len(want) = %v", len(got), len(tt.want)) + } + for i := 0; i < len(got); i++ { + var wantFileEdit *FileEdit + if i < len(tt.want) { + wantFileEdit = tt.want[i] + } + if !reflect.DeepEqual(got[i], wantFileEdit) { + t.Errorf("got[%v] =\n%#v\nwant[%v]:\n%#v", i, got[i], i, wantFileEdit) + } + } + }) + } +} + +func TestPerformBufferEdits(t *testing.T) { + tests := []struct { + name string + fileEdits []*FileEdit + s string + want string + }{ + {name: "no edits", s: "my\nshort\nfile\n", want: "my\nshort\nfile\n"}, + { + name: "one edit", + fileEdits: []*FileEdit{ + {pos: token.Position{Offset: 3}, fromText: "short", toText: "one edit"}, + }, + s: "my\nshort\nfile\n", + want: "my\none edit\nfile\n", + }, + { + name: "one insert", + fileEdits: []*FileEdit{ + {pos: token.Position{Offset: 2}, fromText: "", toText: "\none insert"}, + }, + s: "my\nshort\nfile\n", + want: "my\none insert\nshort\nfile\n", + }, + { + name: "two inserts at same offset", + fileEdits: []*FileEdit{ + {pos: token.Position{Offset: 2}, fromText: "", toText: "\none insert"}, + {pos: token.Position{Offset: 2}, fromText: "", toText: "\nsecond insert"}, + }, + s: "my\nshort\nfile\n", + want: "my\none insert\nsecond insert\nshort\nfile\n", + }, + } + + for i, tt := range tests { + t.Run(fmt.Sprintf("test #%v: %v", i, tt.name), func(t *testing.T) { + b := performBufferEdits([]byte(tt.s), tt.fileEdits) + got := string(b) + + if len(got) != len(tt.want) { + t.Errorf("len(got) = %v, len(want) = %v", len(got), len(tt.want)) + } + if got != tt.want { + t.Errorf("got = %v, want = %v", got, tt.want) + } + }) + } +} + +func TestGitURL(t *testing.T) { + tests := []struct { + name string + s string + want string + }{ + {name: "empty string"}, + {name: "non-http", s: "howdy"}, + { + name: "normal URL, no slash", + s: "https://developer.github.com/v3/activity/events", + want: "https://developer.github.com/v3/activity/events/", + }, + { + name: "normal URL, with slash", + s: "https://developer.github.com/v3/activity/events/", + want: "https://developer.github.com/v3/activity/events/", + }, + { + name: "normal URL, with fragment identifier", + s: "https://developer.github.com/v3/activity/events/#list-public-events", + want: "https://developer.github.com/v3/activity/events/", + }, + } + + for i, tt := range tests { + t.Run(fmt.Sprintf("test #%v: %v", i, tt.name), func(t *testing.T) { + got := getURL(tt.s) + if got != tt.want { + t.Errorf("getURL = %v ; want %v", got, tt.want) + } + }) + } +} + +func testWebPageHelper(t *testing.T, got, want map[string][]*Endpoint) { + t.Helper() + + for k := range got { + w, ok := want[k] + if len(got[k]) != len(w) { + t.Errorf("len(got[%q]) = %v, len(want[%q]) = %v", k, len(got[k]), k, len(w)) + } + for i := 0; i < len(got[k]); i++ { + var wantEndpoint *Endpoint + if ok && i < len(w) { + wantEndpoint = w[i] + } + if !reflect.DeepEqual(got[k][i], wantEndpoint) { + t.Errorf("got[%q][%v] =\n%#v\nwant[%q][%v]:\n%#v", k, i, got[k][i], k, i, wantEndpoint) + } + } + } + for k := range want { + if _, ok := got[k]; !ok { + t.Errorf("got[%q] = nil\nwant[%q]:\n%#v", k, k, want[k]) + } + } +} diff --git a/update-urls/reactions_test.go b/update-urls/reactions_test.go new file mode 100644 index 00000000000..1ef696f7799 --- /dev/null +++ b/update-urls/reactions_test.go @@ -0,0 +1,4143 @@ +// Copyright 2020 The go-github AUTHORS. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +import ( + "testing" +) + +func newReactionsPipeline() *pipelineSetup { + return &pipelineSetup{ + baseURL: "https://developer.github.com/v3/reactions/", + endpointsFromWebsite: reactionsWant, + filename: "reactions.go", + serviceName: "ReactionsService", + originalGoSource: reactionsGoFileOriginal, + wantGoSource: reactionsGoFileWant, + wantNumEndpoints: 25, + } +} + +func TestPipeline_Reactions(t *testing.T) { + ps := newReactionsPipeline() + ps.setup(t, false, false) + ps.validate(t) +} + +func TestPipeline_Reactions_FirstStripAllURLs(t *testing.T) { + ps := newReactionsPipeline() + ps.setup(t, true, false) + ps.validate(t) +} + +func TestPipeline_Reactions_FirstDestroyReceivers(t *testing.T) { + ps := newReactionsPipeline() + ps.setup(t, false, true) + ps.validate(t) +} + +func TestPipeline_Reactions_FirstStripAllURLsAndDestroyReceivers(t *testing.T) { + ps := newReactionsPipeline() + ps.setup(t, true, true) + ps.validate(t) +} + +func TestParseWebPageEndpoints_Reactions(t *testing.T) { + got, want := parseWebPageEndpoints(reactionsTestWebPage), reactionsWant + testWebPageHelper(t, got, want) +} + +var reactionsWant = endpointsByFragmentID{ + "list-reactions-for-a-commit-comment": []*Endpoint{{urlFormats: []string{"repos/%v/%v/comments/%v/reactions"}, httpMethod: "GET"}}, + + "delete-a-commit-comment-reaction": []*Endpoint{ + {urlFormats: []string{"repositories/%v/comments/%v/reactions/%v"}, httpMethod: "DELETE"}, + {urlFormats: []string{"repos/%v/%v/comments/%v/reactions/%v"}, httpMethod: "DELETE"}, + }, + + "create-reaction-for-an-issue": []*Endpoint{{urlFormats: []string{"repos/%v/%v/issues/%v/reactions"}, httpMethod: "POST"}}, + + "delete-an-issue-reaction": []*Endpoint{ + {urlFormats: []string{"repositories/%v/issues/%v/reactions/%v"}, httpMethod: "DELETE"}, + {urlFormats: []string{"repos/%v/%v/issues/%v/reactions/%v"}, httpMethod: "DELETE"}, + }, + + "create-reaction-for-a-pull-request-review-comment": []*Endpoint{{urlFormats: []string{"repos/%v/%v/pulls/comments/%v/reactions"}, httpMethod: "POST"}}, + + "list-reactions-for-a-team-discussion": []*Endpoint{ + {urlFormats: []string{"organizations/%v/team/%v/discussions/%v/reactions"}, httpMethod: "GET"}, + {urlFormats: []string{"orgs/%v/teams/%v/discussions/%v/reactions"}, httpMethod: "GET"}, + }, + + "delete-a-reaction-legacy": []*Endpoint{{urlFormats: []string{"reactions/%v"}, httpMethod: "DELETE"}}, + + "list-reactions-for-a-team-discussion-comment-legacy": []*Endpoint{{urlFormats: []string{"teams/%v/discussions/%v/comments/%v/reactions"}, httpMethod: "GET"}}, + + "delete-an-issue-comment-reaction": []*Endpoint{ + {urlFormats: []string{"repositories/%v/issues/comments/%v/reactions/%v"}, httpMethod: "DELETE"}, + {urlFormats: []string{"repos/%v/%v/issues/comments/%v/reactions/%v"}, httpMethod: "DELETE"}, + }, + + "list-reactions-for-a-pull-request-review-comment": []*Endpoint{{urlFormats: []string{"repos/%v/%v/pulls/comments/%v/reactions"}, httpMethod: "GET"}}, + + "create-reaction-for-a-team-discussion-legacy": []*Endpoint{{urlFormats: []string{"teams/%v/discussions/%v/reactions"}, httpMethod: "POST"}}, + + "create-reaction-for-a-team-discussion-comment-legacy": []*Endpoint{{urlFormats: []string{"teams/%v/discussions/%v/comments/%v/reactions"}, httpMethod: "POST"}}, + + "create-reaction-for-a-commit-comment": []*Endpoint{{urlFormats: []string{"repos/%v/%v/comments/%v/reactions"}, httpMethod: "POST"}}, + + "list-reactions-for-an-issue": []*Endpoint{{urlFormats: []string{"repos/%v/%v/issues/%v/reactions"}, httpMethod: "GET"}}, + + "create-reaction-for-an-issue-comment": []*Endpoint{{urlFormats: []string{"repos/%v/%v/issues/comments/%v/reactions"}, httpMethod: "POST"}}, + + "create-reaction-for-a-team-discussion": []*Endpoint{ + {urlFormats: []string{"organizations/%v/team/%v/discussions/%v/reactions"}, httpMethod: "POST"}, + {urlFormats: []string{"orgs/%v/teams/%v/discussions/%v/reactions"}, httpMethod: "POST"}, + }, + + "delete-team-discussion-reaction": []*Endpoint{ + {urlFormats: []string{"organizations/%v/team/%v/discussions/%v/reactions/%v"}, httpMethod: "DELETE"}, + {urlFormats: []string{"orgs/%v/teams/%v/discussions/%v/reactions/%v"}, httpMethod: "DELETE"}, + }, + + "create-reaction-for-a-team-discussion-comment": []*Endpoint{ + {urlFormats: []string{"organizations/%v/team/%v/discussions/%v/comments/%v/reactions"}, httpMethod: "POST"}, + {urlFormats: []string{"orgs/%v/teams/%v/discussions/%v/comments/%v/reactions"}, httpMethod: "POST"}, + }, + + "list-reactions-for-an-issue-comment": []*Endpoint{{urlFormats: []string{"repos/%v/%v/issues/comments/%v/reactions"}, httpMethod: "GET"}}, + + "delete-a-pull-request-comment-reaction": []*Endpoint{ + {urlFormats: []string{"repositories/%v/pulls/comments/%v/reactions/%v"}, httpMethod: "DELETE"}, + {urlFormats: []string{"repos/%v/%v/pulls/comments/%v/reactions/%v"}, httpMethod: "DELETE"}, + }, + + "list-reactions-for-a-team-discussion-comment": []*Endpoint{ + {urlFormats: []string{"organizations/%v/team/%v/discussions/%v/comments/%v/reactions"}, httpMethod: "GET"}, + {urlFormats: []string{"orgs/%v/teams/%v/discussions/%v/comments/%v/reactions"}, httpMethod: "GET"}, + }, + + "delete-team-discussion-comment-reaction": []*Endpoint{ + {urlFormats: []string{"organizations/%v/team/%v/discussions/%v/comments/%v/reactions/%v"}, httpMethod: "DELETE"}, + {urlFormats: []string{"orgs/%v/teams/%v/discussions/%v/comments/%v/reactions/%v"}, httpMethod: "DELETE"}, + }, + + "list-reactions-for-a-team-discussion-legacy": []*Endpoint{{urlFormats: []string{"teams/%v/discussions/%v/reactions"}, httpMethod: "GET"}}, +} + +var reactionsTestWebPage = ` + + + + + + + + + Reactions | GitHub Developer Guide + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + +
+
+

+ Reactions

+ + + +
+ +

Note: APIs for managing reactions are currently available for developers to preview. See + the blog post for full details. To access the API + during the preview period, you must provide a custom media type in the + Accept header:

+ +
  application/vnd.github.squirrel-girl-preview+json
+
+ +
+ +
+ +

Warning: The API may change without advance notice during the preview period. Preview + features are not supported for production use. If you experience any issues, contact GitHub Support or GitHub + Premium Support.

+ +
+ +

+ Reaction types

+ +

When creating a reaction, the allowed values for the content parameter are as follows (with the + corresponding emoji for reference):

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
contentemoji
+1:+1:
-1:-1:
laugh:smile:
confused:confused:
heart:heart:
hooray:tada:
rocket:rocket:
eyes:eyes:
+ +

+ List reactions for a + commit comment +

+ +
+ +

Note: APIs for managing reactions are currently available for developers to preview. See + the blog post for full details. To access the API + during the preview period, you must provide a custom media type in the + Accept header:

+ +
  application/vnd.github.squirrel-girl-preview+json
+
+ +
+ +
+ +

Warning: The API may change without advance notice during the preview period. Preview + features are not supported for production use. If you experience any issues, contact GitHub Support or GitHub + Premium Support.

+ +
+ +

List the reactions to a commit comment.

+ +
GET /repos/:owner/:repo/comments/:comment_id/reactions
+
+ +

+ Parameters

+ + + + + + + + + + + + + + + + +
NameTypeDescription
contentstringReturns a single reaction type. Omit this parameter to + list all reactions to a commit comment.
+ +

+ Response

+ +
Status: 200 OK
+Link: <https://api.github.com/resource?page=2>; rel="next",
+      <https://api.github.com/resource?page=5>; rel="last"
+
+ + +
[
+  {
+    "id": 1,
+    "node_id": "MDg6UmVhY3Rpb24x",
+    "user": {
+      "login": "octocat",
+      "id": 1,
+      "node_id": "MDQ6VXNlcjE=",
+      "avatar_url": "https://github.com/images/error/octocat_happy.gif",
+      "gravatar_id": "",
+      "url": "https://api.github.com/users/octocat",
+      "html_url": "https://github.com/octocat",
+      "followers_url": "https://api.github.com/users/octocat/followers",
+      "following_url": "https://api.github.com/users/octocat/following{/other_user}",
+      "gists_url": "https://api.github.com/users/octocat/gists{/gist_id}",
+      "starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}",
+      "subscriptions_url": "https://api.github.com/users/octocat/subscriptions",
+      "organizations_url": "https://api.github.com/users/octocat/orgs",
+      "repos_url": "https://api.github.com/users/octocat/repos",
+      "events_url": "https://api.github.com/users/octocat/events{/privacy}",
+      "received_events_url": "https://api.github.com/users/octocat/received_events",
+      "type": "User",
+      "site_admin": false
+    },
+    "content": "heart",
+    "created_at": "2016-05-20T20:09:31Z"
+  }
+]
+
+ + +

+ Create reaction for a + commit comment +

+ +
+ +

Note: APIs for managing reactions are currently available for developers to preview. See + the blog post for full details. To access the API + during the preview period, you must provide a custom media type in the + Accept header:

+ +
  application/vnd.github.squirrel-girl-preview+json
+
+ +
+ +
+ +

Warning: The API may change without advance notice during the preview period. Preview + features are not supported for production use. If you experience any issues, contact GitHub Support or GitHub + Premium Support.

+ +
+ +

Create a reaction to a commit comment. A response with a + Status: 200 OK means that you already added the reaction type to this commit comment.

+ +
POST /repos/:owner/:repo/comments/:comment_id/reactions
+
+ +

+ Parameters

+ + + + + + + + + + + + + + + + +
NameTypeDescription
contentstring + Required. The reaction type to add to the + commit comment.
+ +

+ Example

+ +
{
+  "content": "heart"
+}
+
+ + +

+ Response

+ +
Status: 201 Created
+
+ + +
{
+  "id": 1,
+  "node_id": "MDg6UmVhY3Rpb24x",
+  "user": {
+    "login": "octocat",
+    "id": 1,
+    "node_id": "MDQ6VXNlcjE=",
+    "avatar_url": "https://github.com/images/error/octocat_happy.gif",
+    "gravatar_id": "",
+    "url": "https://api.github.com/users/octocat",
+    "html_url": "https://github.com/octocat",
+    "followers_url": "https://api.github.com/users/octocat/followers",
+    "following_url": "https://api.github.com/users/octocat/following{/other_user}",
+    "gists_url": "https://api.github.com/users/octocat/gists{/gist_id}",
+    "starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}",
+    "subscriptions_url": "https://api.github.com/users/octocat/subscriptions",
+    "organizations_url": "https://api.github.com/users/octocat/orgs",
+    "repos_url": "https://api.github.com/users/octocat/repos",
+    "events_url": "https://api.github.com/users/octocat/events{/privacy}",
+    "received_events_url": "https://api.github.com/users/octocat/received_events",
+    "type": "User",
+    "site_admin": false
+  },
+  "content": "heart",
+  "created_at": "2016-05-20T20:09:31Z"
+}
+
+ + +

+ Delete a commit comment + reaction +

+ +
+ +

Note: APIs for managing reactions are currently available for developers to preview. See + the blog post for full details. To access the API + during the preview period, you must provide a custom media type in the + Accept header:

+ +
  application/vnd.github.squirrel-girl-preview+json
+
+ +
+ +
+ +

Warning: The API may change without advance notice during the preview period. Preview + features are not supported for production use. If you experience any issues, contact GitHub Support or GitHub + Premium Support.

+ +
+ +
+ +

Note: You can also specify a repository by repository_id using the route + DELETE /repositories/:repository_id/comments/:comment_id/reactions/:reaction_id.

+ +
+ +

Delete a reaction to a commit comment.

+ +
DELETE /repos/:owner/:repo/comments/:comment_id/reactions/:reaction_id
+
+ +

+ Response

+ +
Status: 204 No Content
+
+ + +

+ List reactions for an + issue +

+ +
+ +

Note: APIs for managing reactions are currently available for developers to preview. See + the blog post for full details. To access the API + during the preview period, you must provide a custom media type in the + Accept header:

+ +
  application/vnd.github.squirrel-girl-preview+json
+
+ +
+ +
+ +

Warning: The API may change without advance notice during the preview period. Preview + features are not supported for production use. If you experience any issues, contact GitHub Support or GitHub + Premium Support.

+ +
+ +

List the reactions to an issue.

+ +
GET /repos/:owner/:repo/issues/:issue_number/reactions
+
+ +

+ Parameters

+ + + + + + + + + + + + + + + + +
NameTypeDescription
contentstringReturns a single reaction type. Omit this parameter to + list all reactions to an issue.
+ +

+ Response

+ +
Status: 200 OK
+Link: <https://api.github.com/resource?page=2>; rel="next",
+      <https://api.github.com/resource?page=5>; rel="last"
+
+ + +
[
+  {
+    "id": 1,
+    "node_id": "MDg6UmVhY3Rpb24x",
+    "user": {
+      "login": "octocat",
+      "id": 1,
+      "node_id": "MDQ6VXNlcjE=",
+      "avatar_url": "https://github.com/images/error/octocat_happy.gif",
+      "gravatar_id": "",
+      "url": "https://api.github.com/users/octocat",
+      "html_url": "https://github.com/octocat",
+      "followers_url": "https://api.github.com/users/octocat/followers",
+      "following_url": "https://api.github.com/users/octocat/following{/other_user}",
+      "gists_url": "https://api.github.com/users/octocat/gists{/gist_id}",
+      "starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}",
+      "subscriptions_url": "https://api.github.com/users/octocat/subscriptions",
+      "organizations_url": "https://api.github.com/users/octocat/orgs",
+      "repos_url": "https://api.github.com/users/octocat/repos",
+      "events_url": "https://api.github.com/users/octocat/events{/privacy}",
+      "received_events_url": "https://api.github.com/users/octocat/received_events",
+      "type": "User",
+      "site_admin": false
+    },
+    "content": "heart",
+    "created_at": "2016-05-20T20:09:31Z"
+  }
+]
+
+ + +

+ Create reaction for an + issue

+ +
+ +

Note: APIs for managing reactions are currently available for developers to preview. See + the blog post for full details. To access the API + during the preview period, you must provide a custom media type in the + Accept header:

+ +
  application/vnd.github.squirrel-girl-preview+json
+
+ +
+ +
+ +

Warning: The API may change without advance notice during the preview period. Preview + features are not supported for production use. If you experience any issues, contact GitHub Support or GitHub + Premium Support.

+ +
+ +

Create a reaction to an issue. A response with a Status: 200 OK means + that you already added the reaction type to this issue.

+ +
POST /repos/:owner/:repo/issues/:issue_number/reactions
+
+ +

+ Parameters

+ + + + + + + + + + + + + + + + +
NameTypeDescription
contentstring + Required. The reaction type to add to the + issue.
+ +

+ Example

+ +
{
+  "content": "heart"
+}
+
+ + +

+ Response

+ +
Status: 201 Created
+
+ + +
{
+  "id": 1,
+  "node_id": "MDg6UmVhY3Rpb24x",
+  "user": {
+    "login": "octocat",
+    "id": 1,
+    "node_id": "MDQ6VXNlcjE=",
+    "avatar_url": "https://github.com/images/error/octocat_happy.gif",
+    "gravatar_id": "",
+    "url": "https://api.github.com/users/octocat",
+    "html_url": "https://github.com/octocat",
+    "followers_url": "https://api.github.com/users/octocat/followers",
+    "following_url": "https://api.github.com/users/octocat/following{/other_user}",
+    "gists_url": "https://api.github.com/users/octocat/gists{/gist_id}",
+    "starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}",
+    "subscriptions_url": "https://api.github.com/users/octocat/subscriptions",
+    "organizations_url": "https://api.github.com/users/octocat/orgs",
+    "repos_url": "https://api.github.com/users/octocat/repos",
+    "events_url": "https://api.github.com/users/octocat/events{/privacy}",
+    "received_events_url": "https://api.github.com/users/octocat/received_events",
+    "type": "User",
+    "site_admin": false
+  },
+  "content": "heart",
+  "created_at": "2016-05-20T20:09:31Z"
+}
+
+ + +

+ Delete an issue reaction +

+ +
+ +

Note: APIs for managing reactions are currently available for developers to preview. See + the blog post for full details. To access the API + during the preview period, you must provide a custom media type in the + Accept header:

+ +
  application/vnd.github.squirrel-girl-preview+json
+
+ +
+ +
+ +

Warning: The API may change without advance notice during the preview period. Preview + features are not supported for production use. If you experience any issues, contact GitHub Support or GitHub + Premium Support.

+ +
+ +
+ +

Note: You can also specify a repository by repository_id using the route + DELETE /repositories/:repository_id/issues/:issue_number/reactions/:reaction_id.

+ +
+ +

Delete a reaction to an issue.

+ +
DELETE /repos/:owner/:repo/issues/:issue_number/reactions/:reaction_id
+
+ +

+ Response

+ +
Status: 204 No Content
+
+ + +

+ List reactions for an + issue comment +

+ +
+ +

Note: APIs for managing reactions are currently available for developers to preview. See + the blog post for full details. To access the API + during the preview period, you must provide a custom media type in the + Accept header:

+ +
  application/vnd.github.squirrel-girl-preview+json
+
+ +
+ +
+ +

Warning: The API may change without advance notice during the preview period. Preview + features are not supported for production use. If you experience any issues, contact GitHub Support or GitHub + Premium Support.

+ +
+ +

List the reactions to an issue comment.

+ +
GET /repos/:owner/:repo/issues/comments/:comment_id/reactions
+
+ +

+ Parameters

+ + + + + + + + + + + + + + + + +
NameTypeDescription
contentstringReturns a single reaction type. Omit this parameter to + list all reactions to an issue comment.
+ +

+ Response

+ +
Status: 200 OK
+Link: <https://api.github.com/resource?page=2>; rel="next",
+      <https://api.github.com/resource?page=5>; rel="last"
+
+ + +
[
+  {
+    "id": 1,
+    "node_id": "MDg6UmVhY3Rpb24x",
+    "user": {
+      "login": "octocat",
+      "id": 1,
+      "node_id": "MDQ6VXNlcjE=",
+      "avatar_url": "https://github.com/images/error/octocat_happy.gif",
+      "gravatar_id": "",
+      "url": "https://api.github.com/users/octocat",
+      "html_url": "https://github.com/octocat",
+      "followers_url": "https://api.github.com/users/octocat/followers",
+      "following_url": "https://api.github.com/users/octocat/following{/other_user}",
+      "gists_url": "https://api.github.com/users/octocat/gists{/gist_id}",
+      "starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}",
+      "subscriptions_url": "https://api.github.com/users/octocat/subscriptions",
+      "organizations_url": "https://api.github.com/users/octocat/orgs",
+      "repos_url": "https://api.github.com/users/octocat/repos",
+      "events_url": "https://api.github.com/users/octocat/events{/privacy}",
+      "received_events_url": "https://api.github.com/users/octocat/received_events",
+      "type": "User",
+      "site_admin": false
+    },
+    "content": "heart",
+    "created_at": "2016-05-20T20:09:31Z"
+  }
+]
+
+ + +

+ Create reaction for an + issue comment +

+ +
+ +

Note: APIs for managing reactions are currently available for developers to preview. See + the blog post for full details. To access the API + during the preview period, you must provide a custom media type in the + Accept header:

+ +
  application/vnd.github.squirrel-girl-preview+json
+
+ +
+ +
+ +

Warning: The API may change without advance notice during the preview period. Preview + features are not supported for production use. If you experience any issues, contact GitHub Support or GitHub + Premium Support.

+ +
+ +

Create a reaction to an issue comment. A response with a + Status: 200 OK means that you already added the reaction type to this issue comment.

+ +
POST /repos/:owner/:repo/issues/comments/:comment_id/reactions
+
+ +

+ Parameters

+ + + + + + + + + + + + + + + + +
NameTypeDescription
contentstring + Required. The reaction type to add to the + issue comment.
+ +

+ Example

+ +
{
+  "content": "heart"
+}
+
+ + +

+ Response

+ +
Status: 201 Created
+
+ + +
{
+  "id": 1,
+  "node_id": "MDg6UmVhY3Rpb24x",
+  "user": {
+    "login": "octocat",
+    "id": 1,
+    "node_id": "MDQ6VXNlcjE=",
+    "avatar_url": "https://github.com/images/error/octocat_happy.gif",
+    "gravatar_id": "",
+    "url": "https://api.github.com/users/octocat",
+    "html_url": "https://github.com/octocat",
+    "followers_url": "https://api.github.com/users/octocat/followers",
+    "following_url": "https://api.github.com/users/octocat/following{/other_user}",
+    "gists_url": "https://api.github.com/users/octocat/gists{/gist_id}",
+    "starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}",
+    "subscriptions_url": "https://api.github.com/users/octocat/subscriptions",
+    "organizations_url": "https://api.github.com/users/octocat/orgs",
+    "repos_url": "https://api.github.com/users/octocat/repos",
+    "events_url": "https://api.github.com/users/octocat/events{/privacy}",
+    "received_events_url": "https://api.github.com/users/octocat/received_events",
+    "type": "User",
+    "site_admin": false
+  },
+  "content": "heart",
+  "created_at": "2016-05-20T20:09:31Z"
+}
+
+ + +

+ Delete an issue comment + reaction +

+ +
+ +

Note: APIs for managing reactions are currently available for developers to preview. See + the blog post for full details. To access the API + during the preview period, you must provide a custom media type in the + Accept header:

+ +
  application/vnd.github.squirrel-girl-preview+json
+
+ +
+ +
+ +

Warning: The API may change without advance notice during the preview period. Preview + features are not supported for production use. If you experience any issues, contact GitHub Support or GitHub + Premium Support.

+ +
+ +
+ +

Note: You can also specify a repository by repository_id using the route + DELETE delete /repositories/:repository_id/issues/comments/:comment_id/reactions/:reaction_id. +

+ +
+ +

Delete a reaction to an issue comment.

+ +
DELETE /repos/:owner/:repo/issues/comments/:comment_id/reactions/:reaction_id
+
+ +

+ Response

+ +
Status: 204 No Content
+
+ + +

+ List reactions for a pull request review comment +

+ +
+ +

Note: APIs for managing reactions are currently available for developers to preview. See + the blog post for full details. To access the API + during the preview period, you must provide a custom media type in the + Accept header:

+ +
  application/vnd.github.squirrel-girl-preview+json
+
+ +
+ +
+ +

Warning: The API may change without advance notice during the preview period. Preview + features are not supported for production use. If you experience any issues, contact GitHub Support or GitHub + Premium Support.

+ +
+ +

List the reactions to a pull request review comment.

+ +
GET /repos/:owner/:repo/pulls/comments/:comment_id/reactions
+
+ +

+ Parameters

+ + + + + + + + + + + + + + + + +
NameTypeDescription
contentstringReturns a single reaction type. Omit this parameter to + list all reactions to a pull request review comment.
+ +

+ Response

+ +
Status: 200 OK
+Link: <https://api.github.com/resource?page=2>; rel="next",
+      <https://api.github.com/resource?page=5>; rel="last"
+
+ + +
[
+  {
+    "id": 1,
+    "node_id": "MDg6UmVhY3Rpb24x",
+    "user": {
+      "login": "octocat",
+      "id": 1,
+      "node_id": "MDQ6VXNlcjE=",
+      "avatar_url": "https://github.com/images/error/octocat_happy.gif",
+      "gravatar_id": "",
+      "url": "https://api.github.com/users/octocat",
+      "html_url": "https://github.com/octocat",
+      "followers_url": "https://api.github.com/users/octocat/followers",
+      "following_url": "https://api.github.com/users/octocat/following{/other_user}",
+      "gists_url": "https://api.github.com/users/octocat/gists{/gist_id}",
+      "starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}",
+      "subscriptions_url": "https://api.github.com/users/octocat/subscriptions",
+      "organizations_url": "https://api.github.com/users/octocat/orgs",
+      "repos_url": "https://api.github.com/users/octocat/repos",
+      "events_url": "https://api.github.com/users/octocat/events{/privacy}",
+      "received_events_url": "https://api.github.com/users/octocat/received_events",
+      "type": "User",
+      "site_admin": false
+    },
+    "content": "heart",
+    "created_at": "2016-05-20T20:09:31Z"
+  }
+]
+
+ + +

+ Create reaction for a pull request review comment +

+ +
+ +

Note: APIs for managing reactions are currently available for developers to preview. See + the blog post for full details. To access the API + during the preview period, you must provide a custom media type in the + Accept header:

+ +
  application/vnd.github.squirrel-girl-preview+json
+
+ +
+ +
+ +

Warning: The API may change without advance notice during the preview period. Preview + features are not supported for production use. If you experience any issues, contact GitHub Support or GitHub + Premium Support.

+ +
+ +

Create a reaction to a pull request review comment. A response with a + Status: 200 OK means that you already added the reaction type to this pull request review + comment.

+ +
POST /repos/:owner/:repo/pulls/comments/:comment_id/reactions
+
+ +

+ Parameters

+ + + + + + + + + + + + + + + + +
NameTypeDescription
contentstring + Required. The reaction type to add to the + pull request review comment.
+ +

+ Example

+ +
{
+  "content": "heart"
+}
+
+ + +

+ Response

+ +
Status: 201 Created
+
+ + +
{
+  "id": 1,
+  "node_id": "MDg6UmVhY3Rpb24x",
+  "user": {
+    "login": "octocat",
+    "id": 1,
+    "node_id": "MDQ6VXNlcjE=",
+    "avatar_url": "https://github.com/images/error/octocat_happy.gif",
+    "gravatar_id": "",
+    "url": "https://api.github.com/users/octocat",
+    "html_url": "https://github.com/octocat",
+    "followers_url": "https://api.github.com/users/octocat/followers",
+    "following_url": "https://api.github.com/users/octocat/following{/other_user}",
+    "gists_url": "https://api.github.com/users/octocat/gists{/gist_id}",
+    "starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}",
+    "subscriptions_url": "https://api.github.com/users/octocat/subscriptions",
+    "organizations_url": "https://api.github.com/users/octocat/orgs",
+    "repos_url": "https://api.github.com/users/octocat/repos",
+    "events_url": "https://api.github.com/users/octocat/events{/privacy}",
+    "received_events_url": "https://api.github.com/users/octocat/received_events",
+    "type": "User",
+    "site_admin": false
+  },
+  "content": "heart",
+  "created_at": "2016-05-20T20:09:31Z"
+}
+
+ + +

+ Delete a pull request + comment reaction +

+ +
+ +

Note: APIs for managing reactions are currently available for developers to preview. See + the blog post for full details. To access the API + during the preview period, you must provide a custom media type in the + Accept header:

+ +
  application/vnd.github.squirrel-girl-preview+json
+
+ +
+ +
+ +

Warning: The API may change without advance notice during the preview period. Preview + features are not supported for production use. If you experience any issues, contact GitHub Support or GitHub + Premium Support.

+ +
+ +
+ +

Note: You can also specify a repository by repository_id using the route + DELETE /repositories/:repository_id/pulls/comments/:comment_id/reactions/:reaction_id.

+ +
+ +

Delete a reaction to a pull request review comment.

+ +
DELETE /repos/:owner/:repo/pulls/comments/:comment_id/reactions/:reaction_id
+
+ +

+ Response

+ +
Status: 204 No Content
+
+ + +

+ List reactions for a + team discussion +

+ +
+ +

Note: APIs for managing reactions are currently available for developers to preview. See + the blog post for full details. To access the API + during the preview period, you must provide a custom media type in the + Accept header:

+ +
  application/vnd.github.squirrel-girl-preview+json
+
+ +
+ +
+ +

Warning: The API may change without advance notice during the preview period. Preview + features are not supported for production use. If you experience any issues, contact GitHub Support or GitHub + Premium Support.

+ +
+ +

List the reactions to a team discussion. OAuth access tokens require the + read:discussion scope.

+ +
+ +

Note: You can also specify a team by org_id and team_id using + the route GET /organizations/:org_id/team/:team_id/discussions/:discussion_number/reactions. +

+ +
+ +
GET /orgs/:org/teams/:team_slug/discussions/:discussion_number/reactions
+
+ +

+ Parameters

+ + + + + + + + + + + + + + + + +
NameTypeDescription
contentstringReturns a single reaction type. Omit this parameter to + list all reactions to a team discussion.
+ +

+ Response

+ +
Status: 200 OK
+Link: <https://api.github.com/resource?page=2>; rel="next",
+      <https://api.github.com/resource?page=5>; rel="last"
+
+ + +
[
+  {
+    "id": 1,
+    "node_id": "MDg6UmVhY3Rpb24x",
+    "user": {
+      "login": "octocat",
+      "id": 1,
+      "node_id": "MDQ6VXNlcjE=",
+      "avatar_url": "https://github.com/images/error/octocat_happy.gif",
+      "gravatar_id": "",
+      "url": "https://api.github.com/users/octocat",
+      "html_url": "https://github.com/octocat",
+      "followers_url": "https://api.github.com/users/octocat/followers",
+      "following_url": "https://api.github.com/users/octocat/following{/other_user}",
+      "gists_url": "https://api.github.com/users/octocat/gists{/gist_id}",
+      "starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}",
+      "subscriptions_url": "https://api.github.com/users/octocat/subscriptions",
+      "organizations_url": "https://api.github.com/users/octocat/orgs",
+      "repos_url": "https://api.github.com/users/octocat/repos",
+      "events_url": "https://api.github.com/users/octocat/events{/privacy}",
+      "received_events_url": "https://api.github.com/users/octocat/received_events",
+      "type": "User",
+      "site_admin": false
+    },
+    "content": "heart",
+    "created_at": "2016-05-20T20:09:31Z"
+  }
+]
+
+ + +

+ Create reaction for a + team discussion

+ +
+ +

Note: APIs for managing reactions are currently available for developers to preview. See + the blog post for full details. To access the API + during the preview period, you must provide a custom media type in the + Accept header:

+ +
  application/vnd.github.squirrel-girl-preview+json
+
+ +
+ +
+ +

Warning: The API may change without advance notice during the preview period. Preview + features are not supported for production use. If you experience any issues, contact GitHub Support or GitHub + Premium Support.

+ +
+ +

Create a reaction to a team discussion. OAuth access tokens require the + write:discussion scope. A response with a + Status: 200 OK means that you already added the reaction type to this team discussion.

+ +
+ +

Note: You can also specify a team by org_id and team_id using + the route POST /organizations/:org_id/team/:team_id/discussions/:discussion_number/reactions. +

+ +
+ +
POST /orgs/:org/teams/:team_slug/discussions/:discussion_number/reactions
+
+ +

+ Parameters

+ + + + + + + + + + + + + + + + +
NameTypeDescription
contentstring + Required. The reaction type to add to the + team discussion.
+ +

+ Example

+ +
{
+  "content": "heart"
+}
+
+ + +

+ Response

+ +
Status: 201 Created
+
+ + +
{
+  "id": 1,
+  "node_id": "MDg6UmVhY3Rpb24x",
+  "user": {
+    "login": "octocat",
+    "id": 1,
+    "node_id": "MDQ6VXNlcjE=",
+    "avatar_url": "https://github.com/images/error/octocat_happy.gif",
+    "gravatar_id": "",
+    "url": "https://api.github.com/users/octocat",
+    "html_url": "https://github.com/octocat",
+    "followers_url": "https://api.github.com/users/octocat/followers",
+    "following_url": "https://api.github.com/users/octocat/following{/other_user}",
+    "gists_url": "https://api.github.com/users/octocat/gists{/gist_id}",
+    "starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}",
+    "subscriptions_url": "https://api.github.com/users/octocat/subscriptions",
+    "organizations_url": "https://api.github.com/users/octocat/orgs",
+    "repos_url": "https://api.github.com/users/octocat/repos",
+    "events_url": "https://api.github.com/users/octocat/events{/privacy}",
+    "received_events_url": "https://api.github.com/users/octocat/received_events",
+    "type": "User",
+    "site_admin": false
+  },
+  "content": "heart",
+  "created_at": "2016-05-20T20:09:31Z"
+}
+
+ + +

+ Delete team discussion + reaction +

+ +
+ +

Note: APIs for managing reactions are currently available for developers to preview. See + the blog post for full details. To access the API + during the preview period, you must provide a custom media type in the + Accept header:

+ +
  application/vnd.github.squirrel-girl-preview+json
+
+ +
+ +
+ +

Warning: The API may change without advance notice during the preview period. Preview + features are not supported for production use. If you experience any issues, contact GitHub Support or GitHub + Premium Support.

+ +
+ +
+ +

Note: You can also specify a team or organization with team_id and + org_id using the route + DELETE /organizations/:org_id/team/:team_id/discussions/:discussion_number/reactions/:reaction_id. +

+ +
+ +

Delete a reaction to a team discussion. OAuth access tokens require the + write:discussion scope.

+ +
DELETE /orgs/:org/teams/:team_slug/discussions/:discussion_number/reactions/:reaction_id
+
+ +

+ Response

+ +
Status: 204 No Content
+
+ + +

+ List reactions for a team discussion comment +

+ +
+ +

Note: APIs for managing reactions are currently available for developers to preview. See + the blog post for full details. To access the API + during the preview period, you must provide a custom media type in the + Accept header:

+ +
  application/vnd.github.squirrel-girl-preview+json
+
+ +
+ +
+ +

Warning: The API may change without advance notice during the preview period. Preview + features are not supported for production use. If you experience any issues, contact GitHub Support or GitHub + Premium Support.

+ +
+ +

List the reactions to a team discussion comment. OAuth access + tokens require the read:discussion scope.

+ +
+ +

Note: You can also specify a team by org_id and team_id using + the route + GET /organizations/:org_id/team/:team_id/discussions/:discussion_number/comments/:comment_number/reactions. +

+ +
+ +
GET /orgs/:org/teams/:team_slug/discussions/:discussion_number/comments/:comment_number/reactions
+
+ +

+ Parameters

+ + + + + + + + + + + + + + + + +
NameTypeDescription
contentstringReturns a single reaction type. Omit this parameter to + list all reactions to a team discussion comment.
+ +

+ Response

+ +
Status: 200 OK
+Link: <https://api.github.com/resource?page=2>; rel="next",
+      <https://api.github.com/resource?page=5>; rel="last"
+
+ + +
[
+  {
+    "id": 1,
+    "node_id": "MDg6UmVhY3Rpb24x",
+    "user": {
+      "login": "octocat",
+      "id": 1,
+      "node_id": "MDQ6VXNlcjE=",
+      "avatar_url": "https://github.com/images/error/octocat_happy.gif",
+      "gravatar_id": "",
+      "url": "https://api.github.com/users/octocat",
+      "html_url": "https://github.com/octocat",
+      "followers_url": "https://api.github.com/users/octocat/followers",
+      "following_url": "https://api.github.com/users/octocat/following{/other_user}",
+      "gists_url": "https://api.github.com/users/octocat/gists{/gist_id}",
+      "starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}",
+      "subscriptions_url": "https://api.github.com/users/octocat/subscriptions",
+      "organizations_url": "https://api.github.com/users/octocat/orgs",
+      "repos_url": "https://api.github.com/users/octocat/repos",
+      "events_url": "https://api.github.com/users/octocat/events{/privacy}",
+      "received_events_url": "https://api.github.com/users/octocat/received_events",
+      "type": "User",
+      "site_admin": false
+    },
+    "content": "heart",
+    "created_at": "2016-05-20T20:09:31Z"
+  }
+]
+
+ + +

+ Create reaction for a team discussion comment +

+ +
+ +

Note: APIs for managing reactions are currently available for developers to preview. See + the blog post for full details. To access the API + during the preview period, you must provide a custom media type in the + Accept header:

+ +
  application/vnd.github.squirrel-girl-preview+json
+
+ +
+ +
+ +

Warning: The API may change without advance notice during the preview period. Preview + features are not supported for production use. If you experience any issues, contact GitHub Support or GitHub + Premium Support.

+ +
+ +

Create a reaction to a team discussion comment. OAuth access + tokens require the write:discussion scope. A response with a + Status: 200 OK means that you already added the reaction type to this team discussion comment. +

+ +
+ +

Note: You can also specify a team by org_id and team_id using + the route + POST /organizations/:org_id/team/:team_id/discussions/:discussion_number/comments/:comment_number/reactions. +

+ +
+ +
POST /orgs/:org/teams/:team_slug/discussions/:discussion_number/comments/:comment_number/reactions
+
+ +

+ Parameters

+ + + + + + + + + + + + + + + + +
NameTypeDescription
contentstring + Required. The reaction type to add to the + team discussion comment.
+ +

+ Example

+ +
{
+  "content": "heart"
+}
+
+ + +

+ Response

+ +
Status: 201 Created
+
+ + +
{
+  "id": 1,
+  "node_id": "MDg6UmVhY3Rpb24x",
+  "user": {
+    "login": "octocat",
+    "id": 1,
+    "node_id": "MDQ6VXNlcjE=",
+    "avatar_url": "https://github.com/images/error/octocat_happy.gif",
+    "gravatar_id": "",
+    "url": "https://api.github.com/users/octocat",
+    "html_url": "https://github.com/octocat",
+    "followers_url": "https://api.github.com/users/octocat/followers",
+    "following_url": "https://api.github.com/users/octocat/following{/other_user}",
+    "gists_url": "https://api.github.com/users/octocat/gists{/gist_id}",
+    "starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}",
+    "subscriptions_url": "https://api.github.com/users/octocat/subscriptions",
+    "organizations_url": "https://api.github.com/users/octocat/orgs",
+    "repos_url": "https://api.github.com/users/octocat/repos",
+    "events_url": "https://api.github.com/users/octocat/events{/privacy}",
+    "received_events_url": "https://api.github.com/users/octocat/received_events",
+    "type": "User",
+    "site_admin": false
+  },
+  "content": "heart",
+  "created_at": "2016-05-20T20:09:31Z"
+}
+
+ + +

+ Delete team discussion + comment reaction +

+ +
+ +

Note: APIs for managing reactions are currently available for developers to preview. See + the blog post for full details. To access the API + during the preview period, you must provide a custom media type in the + Accept header:

+ +
  application/vnd.github.squirrel-girl-preview+json
+
+ +
+ +
+ +

Warning: The API may change without advance notice during the preview period. Preview + features are not supported for production use. If you experience any issues, contact GitHub Support or GitHub + Premium Support.

+ +
+ +
+ +

Note: You can also specify a team or organization with team_id and + org_id using the route + DELETE /organizations/:org_id/team/:team_id/discussions/:discussion_number/comments/:comment_number/reactions/:reaction_id. +

+ +
+ +

Delete a reaction to a team discussion comment. OAuth access + tokens require the write:discussion scope.

+ +
DELETE /orgs/:org/teams/:team_slug/discussions/:discussion_number/comments/:comment_number/reactions/:reaction_id
+
+ +

+ Response

+ +
Status: 204 No Content
+
+ + +

+ Delete a reaction (Legacy) +

+ +
+ +

Deprecation Notice: This endpoint route is deprecated and will be removed from the + Reactions API. We recommend migrating your existing code to use the new delete reactions endpoints. For more + information, see this blog post.

+ +
+ +
+ +

Note: APIs for managing reactions are currently available for developers to preview. See + the blog post for full details. To access the API + during the preview period, you must provide a custom media type in the + Accept header:

+ +
  application/vnd.github.squirrel-girl-preview+json
+
+ +
+ +
+ +

Warning: The API may change without advance notice during the preview period. Preview + features are not supported for production use. If you experience any issues, contact GitHub Support or GitHub + Premium Support.

+ +
+ +

OAuth access tokens require the write:discussion scope, when deleting a team discussion or team + discussion comment.

+ +
DELETE /reactions/:reaction_id
+
+ +

+ Response

+ +
Status: 204 No Content
+
+ + +

+ List reactions for a team discussion (Legacy) +

+ +
+ +

Deprecation Notice: This endpoint route is deprecated and will be removed from the Teams + API. We recommend migrating your existing code to use the new List reactions for a team discussion + endpoint.

+ +
+ +
+ +

Note: APIs for managing reactions are currently available for developers to preview. See + the blog post for full details. To access the API + during the preview period, you must provide a custom media type in the + Accept header:

+ +
  application/vnd.github.squirrel-girl-preview+json
+
+ +
+ +
+ +

Warning: The API may change without advance notice during the preview period. Preview + features are not supported for production use. If you experience any issues, contact GitHub Support or GitHub + Premium Support.

+ +
+ +

List the reactions to a team discussion. OAuth access tokens require the + read:discussion scope.

+ +
GET /teams/:team_id/discussions/:discussion_number/reactions
+
+ +

+ Parameters

+ + + + + + + + + + + + + + + + +
NameTypeDescription
contentstringReturns a single reaction type. Omit this parameter to + list all reactions to a team discussion.
+ +

+ Response

+ +
Status: 200 OK
+Link: <https://api.github.com/resource?page=2>; rel="next",
+      <https://api.github.com/resource?page=5>; rel="last"
+
+ + +
[
+  {
+    "id": 1,
+    "node_id": "MDg6UmVhY3Rpb24x",
+    "user": {
+      "login": "octocat",
+      "id": 1,
+      "node_id": "MDQ6VXNlcjE=",
+      "avatar_url": "https://github.com/images/error/octocat_happy.gif",
+      "gravatar_id": "",
+      "url": "https://api.github.com/users/octocat",
+      "html_url": "https://github.com/octocat",
+      "followers_url": "https://api.github.com/users/octocat/followers",
+      "following_url": "https://api.github.com/users/octocat/following{/other_user}",
+      "gists_url": "https://api.github.com/users/octocat/gists{/gist_id}",
+      "starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}",
+      "subscriptions_url": "https://api.github.com/users/octocat/subscriptions",
+      "organizations_url": "https://api.github.com/users/octocat/orgs",
+      "repos_url": "https://api.github.com/users/octocat/repos",
+      "events_url": "https://api.github.com/users/octocat/events{/privacy}",
+      "received_events_url": "https://api.github.com/users/octocat/received_events",
+      "type": "User",
+      "site_admin": false
+    },
+    "content": "heart",
+    "created_at": "2016-05-20T20:09:31Z"
+  }
+]
+
+ + +

+ Create reaction for a team discussion (Legacy)

+ +
+ +

Deprecation Notice: This endpoint route is deprecated and will be removed from the Teams + API. We recommend migrating your existing code to use the new Create reaction for a team discussion + endpoint.

+ +
+ +
+ +

Note: APIs for managing reactions are currently available for developers to preview. See + the blog post for full details. To access the API + during the preview period, you must provide a custom media type in the + Accept header:

+ +
  application/vnd.github.squirrel-girl-preview+json
+
+ +
+ +
+ +

Warning: The API may change without advance notice during the preview period. Preview + features are not supported for production use. If you experience any issues, contact GitHub Support or GitHub + Premium Support.

+ +
+ +

Create a reaction to a team discussion. OAuth access tokens require the + write:discussion scope. A response with a + Status: 200 OK means that you already added the reaction type to this team discussion.

+ +
POST /teams/:team_id/discussions/:discussion_number/reactions
+
+ +

+ Parameters

+ + + + + + + + + + + + + + + + +
NameTypeDescription
contentstring + Required. The reaction type to add to the + team discussion.
+ +

+ Example

+ +
{
+  "content": "heart"
+}
+
+ + +

+ Response

+ +
Status: 201 Created
+
+ + +
{
+  "id": 1,
+  "node_id": "MDg6UmVhY3Rpb24x",
+  "user": {
+    "login": "octocat",
+    "id": 1,
+    "node_id": "MDQ6VXNlcjE=",
+    "avatar_url": "https://github.com/images/error/octocat_happy.gif",
+    "gravatar_id": "",
+    "url": "https://api.github.com/users/octocat",
+    "html_url": "https://github.com/octocat",
+    "followers_url": "https://api.github.com/users/octocat/followers",
+    "following_url": "https://api.github.com/users/octocat/following{/other_user}",
+    "gists_url": "https://api.github.com/users/octocat/gists{/gist_id}",
+    "starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}",
+    "subscriptions_url": "https://api.github.com/users/octocat/subscriptions",
+    "organizations_url": "https://api.github.com/users/octocat/orgs",
+    "repos_url": "https://api.github.com/users/octocat/repos",
+    "events_url": "https://api.github.com/users/octocat/events{/privacy}",
+    "received_events_url": "https://api.github.com/users/octocat/received_events",
+    "type": "User",
+    "site_admin": false
+  },
+  "content": "heart",
+  "created_at": "2016-05-20T20:09:31Z"
+}
+
+ + +

+ List reactions for a team discussion comment (Legacy) +

+ +
+ +

Deprecation Notice: This endpoint route is deprecated and will be removed from the Teams + API. We recommend migrating your existing code to use the new List reactions for a team discussion comment + endpoint.

+ +
+ +
+ +

Note: APIs for managing reactions are currently available for developers to preview. See + the blog post for full details. To access the API + during the preview period, you must provide a custom media type in the + Accept header:

+ +
  application/vnd.github.squirrel-girl-preview+json
+
+ +
+ +
+ +

Warning: The API may change without advance notice during the preview period. Preview + features are not supported for production use. If you experience any issues, contact GitHub Support or GitHub + Premium Support.

+ +
+ +

List the reactions to a team discussion comment. OAuth access + tokens require the read:discussion scope.

+ +
GET /teams/:team_id/discussions/:discussion_number/comments/:comment_number/reactions
+
+ +

+ Parameters

+ + + + + + + + + + + + + + + + +
NameTypeDescription
contentstringReturns a single reaction type. Omit this parameter to + list all reactions to a team discussion comment.
+ +

+ Response

+ +
Status: 200 OK
+Link: <https://api.github.com/resource?page=2>; rel="next",
+      <https://api.github.com/resource?page=5>; rel="last"
+
+ + +
[
+  {
+    "id": 1,
+    "node_id": "MDg6UmVhY3Rpb24x",
+    "user": {
+      "login": "octocat",
+      "id": 1,
+      "node_id": "MDQ6VXNlcjE=",
+      "avatar_url": "https://github.com/images/error/octocat_happy.gif",
+      "gravatar_id": "",
+      "url": "https://api.github.com/users/octocat",
+      "html_url": "https://github.com/octocat",
+      "followers_url": "https://api.github.com/users/octocat/followers",
+      "following_url": "https://api.github.com/users/octocat/following{/other_user}",
+      "gists_url": "https://api.github.com/users/octocat/gists{/gist_id}",
+      "starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}",
+      "subscriptions_url": "https://api.github.com/users/octocat/subscriptions",
+      "organizations_url": "https://api.github.com/users/octocat/orgs",
+      "repos_url": "https://api.github.com/users/octocat/repos",
+      "events_url": "https://api.github.com/users/octocat/events{/privacy}",
+      "received_events_url": "https://api.github.com/users/octocat/received_events",
+      "type": "User",
+      "site_admin": false
+    },
+    "content": "heart",
+    "created_at": "2016-05-20T20:09:31Z"
+  }
+]
+
+ + +

+ Create reaction for a team discussion comment (Legacy) +

+ +
+ +

Deprecation Notice: This endpoint route is deprecated and will be removed from the Teams + API. We recommend migrating your existing code to use the new Create reaction for a team discussion comment + endpoint.

+ +
+ +
+ +

Note: APIs for managing reactions are currently available for developers to preview. See + the blog post for full details. To access the API + during the preview period, you must provide a custom media type in the + Accept header:

+ +
  application/vnd.github.squirrel-girl-preview+json
+
+ +
+ +
+ +

Warning: The API may change without advance notice during the preview period. Preview + features are not supported for production use. If you experience any issues, contact GitHub Support or GitHub + Premium Support.

+ +
+ +

Create a reaction to a team discussion comment. OAuth access + tokens require the write:discussion scope. A response with a + Status: 200 OK means that you already added the reaction type to this team discussion comment. +

+ +
POST /teams/:team_id/discussions/:discussion_number/comments/:comment_number/reactions
+
+ +

+ Parameters

+ + + + + + + + + + + + + + + + +
NameTypeDescription
contentstring + Required. The reaction type to add to the + team discussion comment.
+ +

+ Example

+ +
{
+  "content": "heart"
+}
+
+ + +

+ Response

+ +
Status: 201 Created
+
+ + +
{
+  "id": 1,
+  "node_id": "MDg6UmVhY3Rpb24x",
+  "user": {
+    "login": "octocat",
+    "id": 1,
+    "node_id": "MDQ6VXNlcjE=",
+    "avatar_url": "https://github.com/images/error/octocat_happy.gif",
+    "gravatar_id": "",
+    "url": "https://api.github.com/users/octocat",
+    "html_url": "https://github.com/octocat",
+    "followers_url": "https://api.github.com/users/octocat/followers",
+    "following_url": "https://api.github.com/users/octocat/following{/other_user}",
+    "gists_url": "https://api.github.com/users/octocat/gists{/gist_id}",
+    "starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}",
+    "subscriptions_url": "https://api.github.com/users/octocat/subscriptions",
+    "organizations_url": "https://api.github.com/users/octocat/orgs",
+    "repos_url": "https://api.github.com/users/octocat/repos",
+    "events_url": "https://api.github.com/users/octocat/events{/privacy}",
+    "received_events_url": "https://api.github.com/users/octocat/received_events",
+    "type": "User",
+    "site_admin": false
+  },
+  "content": "heart",
+  "created_at": "2016-05-20T20:09:31Z"
+}
+
+ +
+ + + + + +
+
+ + + + + + + + +` + +var reactionsGoFileOriginal = `// Copyright 2016 The go-github AUTHORS. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package github + +import ( + "context" + "fmt" + "net/http" +) + +// ReactionsService provides access to the reactions-related functions in the +// GitHub API. +type ReactionsService service + +// Reaction represents a GitHub reaction. +type Reaction struct { + // ID is the Reaction ID. + ID *int64 ` + "`" + `json:"id,omitempty"` + "`" + ` + User *User ` + "`" + `json:"user,omitempty"` + "`" + ` + NodeID *string ` + "`" + `json:"node_id,omitempty"` + "`" + ` + // Content is the type of reaction. + // Possible values are: + // "+1", "-1", "laugh", "confused", "heart", "hooray". + Content *string ` + "`" + `json:"content,omitempty"` + "`" + ` +} + +// Reactions represents a summary of GitHub reactions. +type Reactions struct { + TotalCount *int ` + "`" + `json:"total_count,omitempty"` + "`" + ` + PlusOne *int ` + "`" + `json:"+1,omitempty"` + "`" + ` + MinusOne *int ` + "`" + `json:"-1,omitempty"` + "`" + ` + Laugh *int ` + "`" + `json:"laugh,omitempty"` + "`" + ` + Confused *int ` + "`" + `json:"confused,omitempty"` + "`" + ` + Heart *int ` + "`" + `json:"heart,omitempty"` + "`" + ` + Hooray *int ` + "`" + `json:"hooray,omitempty"` + "`" + ` + URL *string ` + "`" + `json:"url,omitempty"` + "`" + ` +} + +func (r Reaction) String() string { + return Stringify(r) +} + +// ListCommentReactionOptions specifies the optional parameters to the +// ReactionsService.ListCommentReactions method. +type ListCommentReactionOptions struct { + // Content restricts the returned comment reactions to only those with the given type. + // Omit this parameter to list all reactions to a commit comment. + // Possible values are: "+1", "-1", "laugh", "confused", "heart", "hooray", "rocket", or "eyes". + Content string ` + "`" + `url:"content,omitempty"` + "`" + ` + + ListOptions +} + +// ListCommentReactions lists the reactions for a commit comment. +// +// GitHub API docs: https://developer.github.com/v3/reactions/#list-reactions-for-a-commit-comment +func (s *ReactionsService) ListCommentReactions(ctx context.Context, owner, repo string, id int64, opts *ListCommentReactionOptions) ([]*Reaction, *Response, error) { + u := fmt.Sprintf("repos/%v/%v/comments/%v/reactions", owner, repo, id) + u, err := addOptions(u, opts) + 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 headers when APIs fully launch. + req.Header.Set("Accept", mediaTypeReactionsPreview) + + var m []*Reaction + resp, err := s.client.Do(ctx, req, &m) + if err != nil { + return nil, resp, err + } + + return m, resp, nil +} + +// CreateCommentReaction creates a reaction for a commit comment. +// Note that if you have already created a reaction of type content, the +// previously created reaction will be returned with Status: 200 OK. +// The content should have one of the following values: "+1", "-1", "laugh", "confused", "heart", "hooray". +// +// GitHub API docs: https://developer.github.com/v3/reactions/#create-reaction-for-a-commit-comment +func (s *ReactionsService) CreateCommentReaction(ctx context.Context, owner, repo string, id int64, content string) (*Reaction, *Response, error) { + u := fmt.Sprintf("repos/%v/%v/comments/%v/reactions", owner, repo, id) + + body := &Reaction{Content: String(content)} + req, err := s.client.NewRequest("POST", u, body) + if err != nil { + return nil, nil, err + } + + // TODO: remove custom Accept headers when APIs fully launch. + req.Header.Set("Accept", mediaTypeReactionsPreview) + + m := &Reaction{} + resp, err := s.client.Do(ctx, req, m) + if err != nil { + return nil, resp, err + } + + return m, resp, nil +} + +// DeleteCommentReaction deletes the reaction for a commit comment. +// +// GitHub API docs: https://developer.github.com/v3/reactions/#delete-a-commit-comment-reaction +func (s *ReactionsService) DeleteCommentReaction(ctx context.Context, owner, repo string, commentID, reactionID int64) (*Response, error) { + u := fmt.Sprintf("repos/%v/%v/comments/%v/reactions/%v", owner, repo, commentID, reactionID) + + return s.deleteReaction(ctx, u) +} + +// DeleteCommentReactionByID deletes the reaction for a commit comment by repository ID. +// +// GitHub API docs: https://developer.github.com/v3/reactions/#delete-a-commit-comment-reaction +func (s *ReactionsService) DeleteCommentReactionByID(ctx context.Context, repoID, commentID, reactionID int64) (*Response, error) { + u := fmt.Sprintf("repositories/%v/comments/%v/reactions/%v", repoID, commentID, reactionID) + + return s.deleteReaction(ctx, u) +} + +// ListIssueReactions lists the reactions for an issue. +// +// GitHub API docs: https://developer.github.com/v3/reactions/#list-reactions-for-an-issue +func (s *ReactionsService) ListIssueReactions(ctx context.Context, owner, repo string, number int, opts *ListOptions) ([]*Reaction, *Response, error) { + u := fmt.Sprintf("repos/%v/%v/issues/%v/reactions", owner, repo, number) + u, err := addOptions(u, opts) + 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 headers when APIs fully launch. + req.Header.Set("Accept", mediaTypeReactionsPreview) + + var m []*Reaction + resp, err := s.client.Do(ctx, req, &m) + if err != nil { + return nil, resp, err + } + + return m, resp, nil +} + +// CreateIssueReaction creates a reaction for an issue. +// Note that if you have already created a reaction of type content, the +// previously created reaction will be returned with Status: 200 OK. +// The content should have one of the following values: "+1", "-1", "laugh", "confused", "heart", "hooray". +// +// GitHub API docs: https://developer.github.com/v3/reactions/#create-reaction-for-an-issue +func (s *ReactionsService) CreateIssueReaction(ctx context.Context, owner, repo string, number int, content string) (*Reaction, *Response, error) { + u := fmt.Sprintf("repos/%v/%v/issues/%v/reactions", owner, repo, number) + + body := &Reaction{Content: String(content)} + req, err := s.client.NewRequest("POST", u, body) + if err != nil { + return nil, nil, err + } + + // TODO: remove custom Accept headers when APIs fully launch. + req.Header.Set("Accept", mediaTypeReactionsPreview) + + m := &Reaction{} + resp, err := s.client.Do(ctx, req, m) + if err != nil { + return nil, resp, err + } + + return m, resp, nil +} + +// DeleteIssueReaction deletes the reaction to an issue. +// +// GitHub API docs: https://developer.github.com/v3/reactions/#delete-an-issue-reaction +func (s *ReactionsService) DeleteIssueReaction(ctx context.Context, owner, repo string, issueNumber int, reactionID int64) (*Response, error) { + url := fmt.Sprintf("repos/%v/%v/issues/%v/reactions/%v", owner, repo, issueNumber, reactionID) + + return s.deleteReaction(ctx, url) +} + +// DeleteIssueReactionByID deletes the reaction to an issue by repository ID. +// +// GitHub API docs: https://developer.github.com/v3/reactions/#delete-an-issue-reaction +func (s *ReactionsService) DeleteIssueReactionByID(ctx context.Context, repoID, issueNumber int, reactionID int64) (*Response, error) { + url := fmt.Sprintf("repositories/%v/issues/%v/reactions/%v", repoID, issueNumber, reactionID) + + return s.deleteReaction(ctx, url) +} + +// ListIssueCommentReactions lists the reactions for an issue comment. +// +// GitHub API docs: https://developer.github.com/v3/reactions/#list-reactions-for-an-issue-comment +func (s *ReactionsService) ListIssueCommentReactions(ctx context.Context, owner, repo string, id int64, opts *ListOptions) ([]*Reaction, *Response, error) { + u := fmt.Sprintf("repos/%v/%v/issues/comments/%v/reactions", owner, repo, id) + u, err := addOptions(u, opts) + 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 headers when APIs fully launch. + req.Header.Set("Accept", mediaTypeReactionsPreview) + + var m []*Reaction + resp, err := s.client.Do(ctx, req, &m) + if err != nil { + return nil, resp, err + } + + return m, resp, nil +} + +// CreateIssueCommentReaction creates a reaction for an issue comment. +// Note that if you have already created a reaction of type content, the +// previously created reaction will be returned with Status: 200 OK. +// The content should have one of the following values: "+1", "-1", "laugh", "confused", "heart", "hooray". +// +// GitHub API docs: https://developer.github.com/v3/reactions/#create-reaction-for-an-issue-comment +func (s *ReactionsService) CreateIssueCommentReaction(ctx context.Context, owner, repo string, id int64, content string) (*Reaction, *Response, error) { + u := fmt.Sprintf("repos/%v/%v/issues/comments/%v/reactions", owner, repo, id) + + body := &Reaction{Content: String(content)} + req, err := s.client.NewRequest("POST", u, body) + if err != nil { + return nil, nil, err + } + + // TODO: remove custom Accept headers when APIs fully launch. + req.Header.Set("Accept", mediaTypeReactionsPreview) + + m := &Reaction{} + resp, err := s.client.Do(ctx, req, m) + if err != nil { + return nil, resp, err + } + + return m, resp, nil +} + +// DeleteIssueCommentReaction deletes the reaction to an issue comment. +// +// GitHub API docs: https://developer.github.com/v3/reactions/#delete-an-issue-comment-reaction +func (s *ReactionsService) DeleteIssueCommentReaction(ctx context.Context, owner, repo string, commentID, reactionID int64) (*Response, error) { + url := fmt.Sprintf("repos/%v/%v/issues/comments/%v/reactions/%v", owner, repo, commentID, reactionID) + + return s.deleteReaction(ctx, url) +} + +// DeleteIssueCommentReactionByID deletes the reaction to an issue comment by repository ID. +// +// GitHub API docs: https://developer.github.com/v3/reactions/#delete-an-issue-comment-reaction +func (s *ReactionsService) DeleteIssueCommentReactionByID(ctx context.Context, repoID, commentID, reactionID int64) (*Response, error) { + url := fmt.Sprintf("repositories/%v/issues/comments/%v/reactions/%v", repoID, commentID, reactionID) + + return s.deleteReaction(ctx, url) +} + +// ListPullRequestCommentReactions lists the reactions for a pull request review comment. +// +// GitHub API docs: https://developer.github.com/v3/reactions/#list-reactions-for-an-issue-comment +func (s *ReactionsService) ListPullRequestCommentReactions(ctx context.Context, owner, repo string, id int64, opts *ListOptions) ([]*Reaction, *Response, error) { + u := fmt.Sprintf("repos/%v/%v/pulls/comments/%v/reactions", owner, repo, id) + u, err := addOptions(u, opts) + 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 headers when APIs fully launch. + req.Header.Set("Accept", mediaTypeReactionsPreview) + + var m []*Reaction + resp, err := s.client.Do(ctx, req, &m) + if err != nil { + return nil, resp, err + } + + return m, resp, nil +} + +// CreatePullRequestCommentReaction creates a reaction for a pull request review comment. +// Note that if you have already created a reaction of type content, the +// previously created reaction will be returned with Status: 200 OK. +// The content should have one of the following values: "+1", "-1", "laugh", "confused", "heart", "hooray". +// +// GitHub API docs: https://developer.github.com/v3/reactions/#create-reaction-for-an-issue-comment +func (s *ReactionsService) CreatePullRequestCommentReaction(ctx context.Context, owner, repo string, id int64, content string) (*Reaction, *Response, error) { + u := fmt.Sprintf("repos/%v/%v/pulls/comments/%v/reactions", owner, repo, id) + + body := &Reaction{Content: String(content)} + req, err := s.client.NewRequest("POST", u, body) + if err != nil { + return nil, nil, err + } + + // TODO: remove custom Accept headers when APIs fully launch. + req.Header.Set("Accept", mediaTypeReactionsPreview) + + m := &Reaction{} + resp, err := s.client.Do(ctx, req, m) + if err != nil { + return nil, resp, err + } + + return m, resp, nil +} + +// DeletePullRequestCommentReaction deletes the reaction to a pull request review comment. +// +// GitHub API docs: https://developer.github.com/v3/reactions/#delete-a-pull-request-comment-reaction +func (s *ReactionsService) DeletePullRequestCommentReaction(ctx context.Context, owner, repo string, commentID, reactionID int64) (*Response, error) { + url := fmt.Sprintf("repos/%v/%v/pulls/comments/%v/reactions/%v", owner, repo, commentID, reactionID) + + return s.deleteReaction(ctx, url) +} + +// DeletePullRequestCommentReactionByID deletes the reaction to a pull request review comment by repository ID. +// +// GitHub API docs: https://developer.github.com/v3/reactions/#delete-a-pull-request-comment-reaction +func (s *ReactionsService) DeletePullRequestCommentReactionByID(ctx context.Context, repoID, commentID, reactionID int64) (*Response, error) { + url := fmt.Sprintf("repositories/%v/pulls/comments/%v/reactions/%v", repoID, commentID, reactionID) + + return s.deleteReaction(ctx, url) +} + +// ListTeamDiscussionReactions lists the reactions for a team discussion. +// +// GitHub API docs: https://developer.github.com/v3/reactions/#list-reactions-for-a-team-discussion +func (s *ReactionsService) ListTeamDiscussionReactions(ctx context.Context, teamID int64, discussionNumber int, opts *ListOptions) ([]*Reaction, *Response, error) { + u := fmt.Sprintf("teams/%v/discussions/%v/reactions", teamID, discussionNumber) + u, err := addOptions(u, opts) + if err != nil { + return nil, nil, err + } + + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + + req.Header.Set("Accept", mediaTypeReactionsPreview) + + var m []*Reaction + resp, err := s.client.Do(ctx, req, &m) + if err != nil { + return nil, resp, err + } + + return m, resp, nil +} + +// CreateTeamDiscussionReaction creates a reaction for a team discussion. +// The content should have one of the following values: "+1", "-1", "laugh", "confused", "heart", "hooray". +// +// GitHub API docs: https://developer.github.com/v3/reactions/#create-reaction-for-a-team-discussion +func (s *ReactionsService) CreateTeamDiscussionReaction(ctx context.Context, teamID int64, discussionNumber int, content string) (*Reaction, *Response, error) { + u := fmt.Sprintf("teams/%v/discussions/%v/reactions", teamID, discussionNumber) + + body := &Reaction{Content: String(content)} + req, err := s.client.NewRequest("POST", u, body) + if err != nil { + return nil, nil, err + } + + req.Header.Set("Accept", mediaTypeReactionsPreview) + + m := &Reaction{} + resp, err := s.client.Do(ctx, req, m) + if err != nil { + return nil, resp, err + } + + return m, resp, nil +} + +// DeleteTeamDiscussionReaction deletes the reaction to a team discussion. +// +// GitHub API docs: https://developer.github.com/v3/reactions/#delete-team-discussion-reaction +func (s *ReactionsService) DeleteTeamDiscussionReaction(ctx context.Context, org, teamSlug string, discussionNumber int, reactionID int64) (*Response, error) { + url := fmt.Sprintf("orgs/%v/teams/%v/discussions/%v/reactions/%v", org, teamSlug, discussionNumber, reactionID) + + return s.deleteReaction(ctx, url) +} + +// DeleteTeamDiscussionReactionByOrgIDAndTeamID deletes the reaction to a team discussion by organization ID and team ID. +// +// GitHub API docs: https://developer.github.com/v3/reactions/#delete-team-discussion-reaction +func (s *ReactionsService) DeleteTeamDiscussionReactionByOrgIDAndTeamID(ctx context.Context, orgID, teamID, discussionNumber int, reactionID int64) (*Response, error) { + url := fmt.Sprintf("organizations/%v/team/%v/discussions/%v/reactions/%v", orgID, teamID, discussionNumber, reactionID) + + return s.deleteReaction(ctx, url) +} + +// ListTeamDiscussionCommentReactions lists the reactions for a team discussion comment. +// +// GitHub API docs: https://developer.github.com/v3/reactions/#list-reactions-for-a-team-discussion-comment +func (s *ReactionsService) ListTeamDiscussionCommentReactions(ctx context.Context, teamID int64, discussionNumber, commentNumber int, opts *ListOptions) ([]*Reaction, *Response, error) { + u := fmt.Sprintf("teams/%v/discussions/%v/comments/%v/reactions", teamID, discussionNumber, commentNumber) + u, err := addOptions(u, opts) + if err != nil { + return nil, nil, err + } + + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + + req.Header.Set("Accept", mediaTypeReactionsPreview) + + var m []*Reaction + resp, err := s.client.Do(ctx, req, &m) + if err != nil { + return nil, nil, err + } + return m, resp, nil +} + +// CreateTeamDiscussionCommentReaction creates a reaction for a team discussion comment. +// The content should have one of the following values: "+1", "-1", "laugh", "confused", "heart", "hooray". +// +// GitHub API docs: https://developer.github.com/v3/reactions/#create-reaction-for-a-team-discussion-comment +func (s *ReactionsService) CreateTeamDiscussionCommentReaction(ctx context.Context, teamID int64, discussionNumber, commentNumber int, content string) (*Reaction, *Response, error) { + u := fmt.Sprintf("teams/%v/discussions/%v/comments/%v/reactions", teamID, discussionNumber, commentNumber) + + body := &Reaction{Content: String(content)} + req, err := s.client.NewRequest("POST", u, body) + if err != nil { + return nil, nil, err + } + + req.Header.Set("Accept", mediaTypeReactionsPreview) + + m := &Reaction{} + resp, err := s.client.Do(ctx, req, m) + if err != nil { + return nil, resp, err + } + + return m, resp, nil +} + +// DeleteTeamDiscussionCommentReaction deletes the reaction to a team discussion comment. +// +// GitHub API docs: https://developer.github.com/v3/reactions/#delete-team-discussion-comment-reaction +func (s *ReactionsService) DeleteTeamDiscussionCommentReaction(ctx context.Context, org, teamSlug string, discussionNumber, commentNumber int, reactionID int64) (*Response, error) { + url := fmt.Sprintf("orgs/%v/teams/%v/discussions/%v/comments/%v/reactions/%v", org, teamSlug, discussionNumber, commentNumber, reactionID) + + return s.deleteReaction(ctx, url) +} + +// DeleteTeamDiscussionCommentReactionByOrgIDAndTeamID deletes the reaction to a team discussion comment by organization ID and team ID. +// +// GitHub API docs: https://developer.github.com/v3/reactions/#delete-team-discussion-comment-reaction +func (s *ReactionsService) DeleteTeamDiscussionCommentReactionByOrgIDAndTeamID(ctx context.Context, orgID, teamID, discussionNumber, commentNumber int, reactionID int64) (*Response, error) { + url := fmt.Sprintf("organizations/%v/team/%v/discussions/%v/comments/%v/reactions/%v", orgID, teamID, discussionNumber, commentNumber, reactionID) + + return s.deleteReaction(ctx, url) +} + +func (s *ReactionsService) deleteReaction(ctx context.Context, url string) (*Response, error) { + req, err := s.client.NewRequest(http.MethodDelete, url, nil) + if err != nil { + return nil, err + } + + // TODO: remove custom Accept headers when APIs fully launch. + req.Header.Set("Accept", mediaTypeReactionsPreview) + + return s.client.Do(ctx, req, nil) +} +` + +var reactionsGoFileWant = `// Copyright 2016 The go-github AUTHORS. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package github + +import ( + "context" + "fmt" + "net/http" +) + +// ReactionsService provides access to the reactions-related functions in the +// GitHub API. +type ReactionsService service + +// Reaction represents a GitHub reaction. +type Reaction struct { + // ID is the Reaction ID. + ID *int64 ` + "`" + `json:"id,omitempty"` + "`" + ` + User *User ` + "`" + `json:"user,omitempty"` + "`" + ` + NodeID *string ` + "`" + `json:"node_id,omitempty"` + "`" + ` + // Content is the type of reaction. + // Possible values are: + // "+1", "-1", "laugh", "confused", "heart", "hooray". + Content *string ` + "`" + `json:"content,omitempty"` + "`" + ` +} + +// Reactions represents a summary of GitHub reactions. +type Reactions struct { + TotalCount *int ` + "`" + `json:"total_count,omitempty"` + "`" + ` + PlusOne *int ` + "`" + `json:"+1,omitempty"` + "`" + ` + MinusOne *int ` + "`" + `json:"-1,omitempty"` + "`" + ` + Laugh *int ` + "`" + `json:"laugh,omitempty"` + "`" + ` + Confused *int ` + "`" + `json:"confused,omitempty"` + "`" + ` + Heart *int ` + "`" + `json:"heart,omitempty"` + "`" + ` + Hooray *int ` + "`" + `json:"hooray,omitempty"` + "`" + ` + URL *string ` + "`" + `json:"url,omitempty"` + "`" + ` +} + +func (r Reaction) String() string { + return Stringify(r) +} + +// ListCommentReactionOptions specifies the optional parameters to the +// ReactionsService.ListCommentReactions method. +type ListCommentReactionOptions struct { + // Content restricts the returned comment reactions to only those with the given type. + // Omit this parameter to list all reactions to a commit comment. + // Possible values are: "+1", "-1", "laugh", "confused", "heart", "hooray", "rocket", or "eyes". + Content string ` + "`" + `url:"content,omitempty"` + "`" + ` + + ListOptions +} + +// ListCommentReactions lists the reactions for a commit comment. +// +// GitHub API docs: https://developer.github.com/v3/reactions/#list-reactions-for-a-commit-comment +func (s *ReactionsService) ListCommentReactions(ctx context.Context, owner, repo string, id int64, opts *ListCommentReactionOptions) ([]*Reaction, *Response, error) { + u := fmt.Sprintf("repos/%v/%v/comments/%v/reactions", owner, repo, id) + u, err := addOptions(u, opts) + 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 headers when APIs fully launch. + req.Header.Set("Accept", mediaTypeReactionsPreview) + + var m []*Reaction + resp, err := s.client.Do(ctx, req, &m) + if err != nil { + return nil, resp, err + } + + return m, resp, nil +} + +// CreateCommentReaction creates a reaction for a commit comment. +// Note that if you have already created a reaction of type content, the +// previously created reaction will be returned with Status: 200 OK. +// The content should have one of the following values: "+1", "-1", "laugh", "confused", "heart", "hooray". +// +// GitHub API docs: https://developer.github.com/v3/reactions/#create-reaction-for-a-commit-comment +func (s *ReactionsService) CreateCommentReaction(ctx context.Context, owner, repo string, id int64, content string) (*Reaction, *Response, error) { + u := fmt.Sprintf("repos/%v/%v/comments/%v/reactions", owner, repo, id) + + body := &Reaction{Content: String(content)} + req, err := s.client.NewRequest("POST", u, body) + if err != nil { + return nil, nil, err + } + + // TODO: remove custom Accept headers when APIs fully launch. + req.Header.Set("Accept", mediaTypeReactionsPreview) + + m := &Reaction{} + resp, err := s.client.Do(ctx, req, m) + if err != nil { + return nil, resp, err + } + + return m, resp, nil +} + +// DeleteCommentReaction deletes the reaction for a commit comment. +// +// GitHub API docs: https://developer.github.com/v3/reactions/#delete-a-commit-comment-reaction +func (s *ReactionsService) DeleteCommentReaction(ctx context.Context, owner, repo string, commentID, reactionID int64) (*Response, error) { + u := fmt.Sprintf("repos/%v/%v/comments/%v/reactions/%v", owner, repo, commentID, reactionID) + + return s.deleteReaction(ctx, u) +} + +// DeleteCommentReactionByID deletes the reaction for a commit comment by repository ID. +// +// GitHub API docs: https://developer.github.com/v3/reactions/#delete-a-commit-comment-reaction +func (s *ReactionsService) DeleteCommentReactionByID(ctx context.Context, repoID, commentID, reactionID int64) (*Response, error) { + u := fmt.Sprintf("repositories/%v/comments/%v/reactions/%v", repoID, commentID, reactionID) + + return s.deleteReaction(ctx, u) +} + +// ListIssueReactions lists the reactions for an issue. +// +// GitHub API docs: https://developer.github.com/v3/reactions/#list-reactions-for-an-issue +func (s *ReactionsService) ListIssueReactions(ctx context.Context, owner, repo string, number int, opts *ListOptions) ([]*Reaction, *Response, error) { + u := fmt.Sprintf("repos/%v/%v/issues/%v/reactions", owner, repo, number) + u, err := addOptions(u, opts) + 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 headers when APIs fully launch. + req.Header.Set("Accept", mediaTypeReactionsPreview) + + var m []*Reaction + resp, err := s.client.Do(ctx, req, &m) + if err != nil { + return nil, resp, err + } + + return m, resp, nil +} + +// CreateIssueReaction creates a reaction for an issue. +// Note that if you have already created a reaction of type content, the +// previously created reaction will be returned with Status: 200 OK. +// The content should have one of the following values: "+1", "-1", "laugh", "confused", "heart", "hooray". +// +// GitHub API docs: https://developer.github.com/v3/reactions/#create-reaction-for-an-issue +func (s *ReactionsService) CreateIssueReaction(ctx context.Context, owner, repo string, number int, content string) (*Reaction, *Response, error) { + u := fmt.Sprintf("repos/%v/%v/issues/%v/reactions", owner, repo, number) + + body := &Reaction{Content: String(content)} + req, err := s.client.NewRequest("POST", u, body) + if err != nil { + return nil, nil, err + } + + // TODO: remove custom Accept headers when APIs fully launch. + req.Header.Set("Accept", mediaTypeReactionsPreview) + + m := &Reaction{} + resp, err := s.client.Do(ctx, req, m) + if err != nil { + return nil, resp, err + } + + return m, resp, nil +} + +// DeleteIssueReaction deletes the reaction to an issue. +// +// GitHub API docs: https://developer.github.com/v3/reactions/#delete-an-issue-reaction +func (s *ReactionsService) DeleteIssueReaction(ctx context.Context, owner, repo string, issueNumber int, reactionID int64) (*Response, error) { + url := fmt.Sprintf("repos/%v/%v/issues/%v/reactions/%v", owner, repo, issueNumber, reactionID) + + return s.deleteReaction(ctx, url) +} + +// DeleteIssueReactionByID deletes the reaction to an issue by repository ID. +// +// GitHub API docs: https://developer.github.com/v3/reactions/#delete-an-issue-reaction +func (s *ReactionsService) DeleteIssueReactionByID(ctx context.Context, repoID, issueNumber int, reactionID int64) (*Response, error) { + url := fmt.Sprintf("repositories/%v/issues/%v/reactions/%v", repoID, issueNumber, reactionID) + + return s.deleteReaction(ctx, url) +} + +// ListIssueCommentReactions lists the reactions for an issue comment. +// +// GitHub API docs: https://developer.github.com/v3/reactions/#list-reactions-for-an-issue-comment +func (s *ReactionsService) ListIssueCommentReactions(ctx context.Context, owner, repo string, id int64, opts *ListOptions) ([]*Reaction, *Response, error) { + u := fmt.Sprintf("repos/%v/%v/issues/comments/%v/reactions", owner, repo, id) + u, err := addOptions(u, opts) + 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 headers when APIs fully launch. + req.Header.Set("Accept", mediaTypeReactionsPreview) + + var m []*Reaction + resp, err := s.client.Do(ctx, req, &m) + if err != nil { + return nil, resp, err + } + + return m, resp, nil +} + +// CreateIssueCommentReaction creates a reaction for an issue comment. +// Note that if you have already created a reaction of type content, the +// previously created reaction will be returned with Status: 200 OK. +// The content should have one of the following values: "+1", "-1", "laugh", "confused", "heart", "hooray". +// +// GitHub API docs: https://developer.github.com/v3/reactions/#create-reaction-for-an-issue-comment +func (s *ReactionsService) CreateIssueCommentReaction(ctx context.Context, owner, repo string, id int64, content string) (*Reaction, *Response, error) { + u := fmt.Sprintf("repos/%v/%v/issues/comments/%v/reactions", owner, repo, id) + + body := &Reaction{Content: String(content)} + req, err := s.client.NewRequest("POST", u, body) + if err != nil { + return nil, nil, err + } + + // TODO: remove custom Accept headers when APIs fully launch. + req.Header.Set("Accept", mediaTypeReactionsPreview) + + m := &Reaction{} + resp, err := s.client.Do(ctx, req, m) + if err != nil { + return nil, resp, err + } + + return m, resp, nil +} + +// DeleteIssueCommentReaction deletes the reaction to an issue comment. +// +// GitHub API docs: https://developer.github.com/v3/reactions/#delete-an-issue-comment-reaction +func (s *ReactionsService) DeleteIssueCommentReaction(ctx context.Context, owner, repo string, commentID, reactionID int64) (*Response, error) { + url := fmt.Sprintf("repos/%v/%v/issues/comments/%v/reactions/%v", owner, repo, commentID, reactionID) + + return s.deleteReaction(ctx, url) +} + +// DeleteIssueCommentReactionByID deletes the reaction to an issue comment by repository ID. +// +// GitHub API docs: https://developer.github.com/v3/reactions/#delete-an-issue-comment-reaction +func (s *ReactionsService) DeleteIssueCommentReactionByID(ctx context.Context, repoID, commentID, reactionID int64) (*Response, error) { + url := fmt.Sprintf("repositories/%v/issues/comments/%v/reactions/%v", repoID, commentID, reactionID) + + return s.deleteReaction(ctx, url) +} + +// ListPullRequestCommentReactions lists the reactions for a pull request review comment. +// +// GitHub API docs: https://developer.github.com/v3/reactions/#list-reactions-for-a-pull-request-review-comment +func (s *ReactionsService) ListPullRequestCommentReactions(ctx context.Context, owner, repo string, id int64, opts *ListOptions) ([]*Reaction, *Response, error) { + u := fmt.Sprintf("repos/%v/%v/pulls/comments/%v/reactions", owner, repo, id) + u, err := addOptions(u, opts) + 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 headers when APIs fully launch. + req.Header.Set("Accept", mediaTypeReactionsPreview) + + var m []*Reaction + resp, err := s.client.Do(ctx, req, &m) + if err != nil { + return nil, resp, err + } + + return m, resp, nil +} + +// CreatePullRequestCommentReaction creates a reaction for a pull request review comment. +// Note that if you have already created a reaction of type content, the +// previously created reaction will be returned with Status: 200 OK. +// The content should have one of the following values: "+1", "-1", "laugh", "confused", "heart", "hooray". +// +// GitHub API docs: https://developer.github.com/v3/reactions/#create-reaction-for-a-pull-request-review-comment +func (s *ReactionsService) CreatePullRequestCommentReaction(ctx context.Context, owner, repo string, id int64, content string) (*Reaction, *Response, error) { + u := fmt.Sprintf("repos/%v/%v/pulls/comments/%v/reactions", owner, repo, id) + + body := &Reaction{Content: String(content)} + req, err := s.client.NewRequest("POST", u, body) + if err != nil { + return nil, nil, err + } + + // TODO: remove custom Accept headers when APIs fully launch. + req.Header.Set("Accept", mediaTypeReactionsPreview) + + m := &Reaction{} + resp, err := s.client.Do(ctx, req, m) + if err != nil { + return nil, resp, err + } + + return m, resp, nil +} + +// DeletePullRequestCommentReaction deletes the reaction to a pull request review comment. +// +// GitHub API docs: https://developer.github.com/v3/reactions/#delete-a-pull-request-comment-reaction +func (s *ReactionsService) DeletePullRequestCommentReaction(ctx context.Context, owner, repo string, commentID, reactionID int64) (*Response, error) { + url := fmt.Sprintf("repos/%v/%v/pulls/comments/%v/reactions/%v", owner, repo, commentID, reactionID) + + return s.deleteReaction(ctx, url) +} + +// DeletePullRequestCommentReactionByID deletes the reaction to a pull request review comment by repository ID. +// +// GitHub API docs: https://developer.github.com/v3/reactions/#delete-a-pull-request-comment-reaction +func (s *ReactionsService) DeletePullRequestCommentReactionByID(ctx context.Context, repoID, commentID, reactionID int64) (*Response, error) { + url := fmt.Sprintf("repositories/%v/pulls/comments/%v/reactions/%v", repoID, commentID, reactionID) + + return s.deleteReaction(ctx, url) +} + +// ListTeamDiscussionReactions lists the reactions for a team discussion. +// +// GitHub API docs: https://developer.github.com/v3/reactions/#list-reactions-for-a-team-discussion-legacy +func (s *ReactionsService) ListTeamDiscussionReactions(ctx context.Context, teamID int64, discussionNumber int, opts *ListOptions) ([]*Reaction, *Response, error) { + u := fmt.Sprintf("teams/%v/discussions/%v/reactions", teamID, discussionNumber) + u, err := addOptions(u, opts) + if err != nil { + return nil, nil, err + } + + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + + req.Header.Set("Accept", mediaTypeReactionsPreview) + + var m []*Reaction + resp, err := s.client.Do(ctx, req, &m) + if err != nil { + return nil, resp, err + } + + return m, resp, nil +} + +// CreateTeamDiscussionReaction creates a reaction for a team discussion. +// The content should have one of the following values: "+1", "-1", "laugh", "confused", "heart", "hooray". +// +// GitHub API docs: https://developer.github.com/v3/reactions/#create-reaction-for-a-team-discussion-legacy +func (s *ReactionsService) CreateTeamDiscussionReaction(ctx context.Context, teamID int64, discussionNumber int, content string) (*Reaction, *Response, error) { + u := fmt.Sprintf("teams/%v/discussions/%v/reactions", teamID, discussionNumber) + + body := &Reaction{Content: String(content)} + req, err := s.client.NewRequest("POST", u, body) + if err != nil { + return nil, nil, err + } + + req.Header.Set("Accept", mediaTypeReactionsPreview) + + m := &Reaction{} + resp, err := s.client.Do(ctx, req, m) + if err != nil { + return nil, resp, err + } + + return m, resp, nil +} + +// DeleteTeamDiscussionReaction deletes the reaction to a team discussion. +// +// GitHub API docs: https://developer.github.com/v3/reactions/#delete-team-discussion-reaction +func (s *ReactionsService) DeleteTeamDiscussionReaction(ctx context.Context, org, teamSlug string, discussionNumber int, reactionID int64) (*Response, error) { + url := fmt.Sprintf("orgs/%v/teams/%v/discussions/%v/reactions/%v", org, teamSlug, discussionNumber, reactionID) + + return s.deleteReaction(ctx, url) +} + +// DeleteTeamDiscussionReactionByOrgIDAndTeamID deletes the reaction to a team discussion by organization ID and team ID. +// +// GitHub API docs: https://developer.github.com/v3/reactions/#delete-team-discussion-reaction +func (s *ReactionsService) DeleteTeamDiscussionReactionByOrgIDAndTeamID(ctx context.Context, orgID, teamID, discussionNumber int, reactionID int64) (*Response, error) { + url := fmt.Sprintf("organizations/%v/team/%v/discussions/%v/reactions/%v", orgID, teamID, discussionNumber, reactionID) + + return s.deleteReaction(ctx, url) +} + +// ListTeamDiscussionCommentReactions lists the reactions for a team discussion comment. +// +// GitHub API docs: https://developer.github.com/v3/reactions/#list-reactions-for-a-team-discussion-comment-legacy +func (s *ReactionsService) ListTeamDiscussionCommentReactions(ctx context.Context, teamID int64, discussionNumber, commentNumber int, opts *ListOptions) ([]*Reaction, *Response, error) { + u := fmt.Sprintf("teams/%v/discussions/%v/comments/%v/reactions", teamID, discussionNumber, commentNumber) + u, err := addOptions(u, opts) + if err != nil { + return nil, nil, err + } + + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + + req.Header.Set("Accept", mediaTypeReactionsPreview) + + var m []*Reaction + resp, err := s.client.Do(ctx, req, &m) + if err != nil { + return nil, nil, err + } + return m, resp, nil +} + +// CreateTeamDiscussionCommentReaction creates a reaction for a team discussion comment. +// The content should have one of the following values: "+1", "-1", "laugh", "confused", "heart", "hooray". +// +// GitHub API docs: https://developer.github.com/v3/reactions/#create-reaction-for-a-team-discussion-comment-legacy +func (s *ReactionsService) CreateTeamDiscussionCommentReaction(ctx context.Context, teamID int64, discussionNumber, commentNumber int, content string) (*Reaction, *Response, error) { + u := fmt.Sprintf("teams/%v/discussions/%v/comments/%v/reactions", teamID, discussionNumber, commentNumber) + + body := &Reaction{Content: String(content)} + req, err := s.client.NewRequest("POST", u, body) + if err != nil { + return nil, nil, err + } + + req.Header.Set("Accept", mediaTypeReactionsPreview) + + m := &Reaction{} + resp, err := s.client.Do(ctx, req, m) + if err != nil { + return nil, resp, err + } + + return m, resp, nil +} + +// DeleteTeamDiscussionCommentReaction deletes the reaction to a team discussion comment. +// +// GitHub API docs: https://developer.github.com/v3/reactions/#delete-team-discussion-comment-reaction +func (s *ReactionsService) DeleteTeamDiscussionCommentReaction(ctx context.Context, org, teamSlug string, discussionNumber, commentNumber int, reactionID int64) (*Response, error) { + url := fmt.Sprintf("orgs/%v/teams/%v/discussions/%v/comments/%v/reactions/%v", org, teamSlug, discussionNumber, commentNumber, reactionID) + + return s.deleteReaction(ctx, url) +} + +// DeleteTeamDiscussionCommentReactionByOrgIDAndTeamID deletes the reaction to a team discussion comment by organization ID and team ID. +// +// GitHub API docs: https://developer.github.com/v3/reactions/#delete-team-discussion-comment-reaction +func (s *ReactionsService) DeleteTeamDiscussionCommentReactionByOrgIDAndTeamID(ctx context.Context, orgID, teamID, discussionNumber, commentNumber int, reactionID int64) (*Response, error) { + url := fmt.Sprintf("organizations/%v/team/%v/discussions/%v/comments/%v/reactions/%v", orgID, teamID, discussionNumber, commentNumber, reactionID) + + return s.deleteReaction(ctx, url) +} + +func (s *ReactionsService) deleteReaction(ctx context.Context, url string) (*Response, error) { + req, err := s.client.NewRequest(http.MethodDelete, url, nil) + if err != nil { + return nil, err + } + + // TODO: remove custom Accept headers when APIs fully launch. + req.Header.Set("Accept", mediaTypeReactionsPreview) + + return s.client.Do(ctx, req, nil) +} +` From e0066688b631702f66e0435ee1633f9d0091e4b9 Mon Sep 17 00:00:00 2001 From: Glenn Lewis <6598971+gmlewis@users.noreply.github.com> Date: Thu, 9 Apr 2020 21:45:09 -0400 Subject: [PATCH 0164/1468] Prepare for release v31 (#1489) --- README.md | 4 ++-- example/appengine/app.go | 2 +- example/basicauth/main.go | 2 +- example/commitpr/main.go | 2 +- example/migrations/main.go | 2 +- example/newrepo/main.go | 2 +- example/simple/main.go | 2 +- example/topics/main.go | 2 +- github/doc.go | 2 +- github/examples_test.go | 2 +- go.mod | 2 +- test/fields/fields.go | 2 +- test/integration/activity_test.go | 2 +- test/integration/authorizations_test.go | 2 +- test/integration/github_test.go | 2 +- test/integration/repos_test.go | 2 +- test/integration/users_test.go | 2 +- 17 files changed, 18 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index deb37542272..86bafb07151 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # go-github # -[![GoDoc](https://img.shields.io/static/v1?label=godoc&message=reference&color=blue)](https://pkg.go.dev/github.com/google/go-github/v30/github) +[![GoDoc](https://img.shields.io/static/v1?label=godoc&message=reference&color=blue)](https://pkg.go.dev/github.com/google/go-github/v31/github) [![Test Status](https://github.com/google/go-github/workflows/tests/badge.svg)](https://github.com/google/go-github/actions?query=workflow%3Atests) [![Test Coverage](https://codecov.io/gh/google/go-github/branch/master/graph/badge.svg)](https://codecov.io/gh/google/go-github) [![Discuss at go-github@googlegroups.com](https://img.shields.io/badge/discuss-go--github%40googlegroups.com-blue.svg)](https://groups.google.com/group/go-github) @@ -21,7 +21,7 @@ If you're interested in using the [GraphQL API v4][], the recommended library is ## Usage ## ```go -import "github.com/google/go-github/v30/github" // with go modules enabled (GO111MODULE=on or outside GOPATH) +import "github.com/google/go-github/v31/github" // with go modules enabled (GO111MODULE=on or outside GOPATH) import "github.com/google/go-github/github" // with go modules disabled ``` diff --git a/example/appengine/app.go b/example/appengine/app.go index bf6829d1402..421d313be60 100644 --- a/example/appengine/app.go +++ b/example/appengine/app.go @@ -12,7 +12,7 @@ import ( "net/http" "os" - "github.com/google/go-github/v30/github" + "github.com/google/go-github/v31/github" "golang.org/x/oauth2" "google.golang.org/appengine" "google.golang.org/appengine/log" diff --git a/example/basicauth/main.go b/example/basicauth/main.go index 53db11200c5..627491afd15 100644 --- a/example/basicauth/main.go +++ b/example/basicauth/main.go @@ -16,7 +16,7 @@ import ( "strings" "syscall" - "github.com/google/go-github/v30/github" + "github.com/google/go-github/v31/github" "golang.org/x/crypto/ssh/terminal" ) diff --git a/example/commitpr/main.go b/example/commitpr/main.go index 0535ef1bcf9..2aeb5faadea 100644 --- a/example/commitpr/main.go +++ b/example/commitpr/main.go @@ -31,7 +31,7 @@ import ( "strings" "time" - "github.com/google/go-github/v30/github" + "github.com/google/go-github/v31/github" "golang.org/x/oauth2" ) diff --git a/example/migrations/main.go b/example/migrations/main.go index 2869337da42..6c36f2efebc 100644 --- a/example/migrations/main.go +++ b/example/migrations/main.go @@ -12,7 +12,7 @@ import ( "context" "fmt" - "github.com/google/go-github/v30/github" + "github.com/google/go-github/v31/github" "golang.org/x/oauth2" ) diff --git a/example/newrepo/main.go b/example/newrepo/main.go index 77baac29e8b..c8b3a4f76ee 100644 --- a/example/newrepo/main.go +++ b/example/newrepo/main.go @@ -16,7 +16,7 @@ import ( "log" "os" - "github.com/google/go-github/v30/github" + "github.com/google/go-github/v31/github" "golang.org/x/oauth2" ) diff --git a/example/simple/main.go b/example/simple/main.go index 179c6423cae..cec4fb8cd52 100644 --- a/example/simple/main.go +++ b/example/simple/main.go @@ -12,7 +12,7 @@ import ( "context" "fmt" - "github.com/google/go-github/v30/github" + "github.com/google/go-github/v31/github" ) // Fetch all the public organizations' membership of a user. diff --git a/example/topics/main.go b/example/topics/main.go index b25e6be4d4a..41f53c1578d 100644 --- a/example/topics/main.go +++ b/example/topics/main.go @@ -12,7 +12,7 @@ import ( "context" "fmt" - "github.com/google/go-github/v30/github" + "github.com/google/go-github/v31/github" ) // Fetch all the public organizations' membership of a user. diff --git a/github/doc.go b/github/doc.go index bad4821b2ad..c2f0b9cd830 100644 --- a/github/doc.go +++ b/github/doc.go @@ -8,7 +8,7 @@ Package github provides a client for using the GitHub API. Usage: - import "github.com/google/go-github/v30/github" // with go modules enabled (GO111MODULE=on or outside GOPATH) + import "github.com/google/go-github/v31/github" // with go modules enabled (GO111MODULE=on or outside GOPATH) import "github.com/google/go-github/github" // with go modules disabled Construct a new GitHub client, then use the various services on the client to diff --git a/github/examples_test.go b/github/examples_test.go index f0b01905be6..83b2ade7bfd 100644 --- a/github/examples_test.go +++ b/github/examples_test.go @@ -12,7 +12,7 @@ import ( "fmt" "log" - "github.com/google/go-github/v30/github" + "github.com/google/go-github/v31/github" ) func ExampleClient_Markdown() { diff --git a/go.mod b/go.mod index 6cf63d146dc..a3eac102338 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module github.com/google/go-github/v30 +module github.com/google/go-github/v31 require ( github.com/golang/protobuf v1.3.2 // indirect diff --git a/test/fields/fields.go b/test/fields/fields.go index ed14a451502..c4a6a7dae6a 100644 --- a/test/fields/fields.go +++ b/test/fields/fields.go @@ -25,7 +25,7 @@ import ( "reflect" "strings" - "github.com/google/go-github/v30/github" + "github.com/google/go-github/v31/github" "golang.org/x/oauth2" ) diff --git a/test/integration/activity_test.go b/test/integration/activity_test.go index 5f7a1d305df..d3145c7f084 100644 --- a/test/integration/activity_test.go +++ b/test/integration/activity_test.go @@ -11,7 +11,7 @@ import ( "context" "testing" - "github.com/google/go-github/v30/github" + "github.com/google/go-github/v31/github" ) const ( diff --git a/test/integration/authorizations_test.go b/test/integration/authorizations_test.go index 3934a0de15d..f244cd44e63 100644 --- a/test/integration/authorizations_test.go +++ b/test/integration/authorizations_test.go @@ -16,7 +16,7 @@ import ( "testing" "time" - "github.com/google/go-github/v30/github" + "github.com/google/go-github/v31/github" ) const msgEnvMissing = "Skipping test because the required environment variable (%v) is not present." diff --git a/test/integration/github_test.go b/test/integration/github_test.go index 9b4fa942963..d54455d42d5 100644 --- a/test/integration/github_test.go +++ b/test/integration/github_test.go @@ -14,7 +14,7 @@ import ( "net/http" "os" - "github.com/google/go-github/v30/github" + "github.com/google/go-github/v31/github" "golang.org/x/oauth2" ) diff --git a/test/integration/repos_test.go b/test/integration/repos_test.go index 9282fa0bbfc..8d452b79bf2 100644 --- a/test/integration/repos_test.go +++ b/test/integration/repos_test.go @@ -15,7 +15,7 @@ import ( "reflect" "testing" - "github.com/google/go-github/v30/github" + "github.com/google/go-github/v31/github" ) func TestRepositories_CRUD(t *testing.T) { diff --git a/test/integration/users_test.go b/test/integration/users_test.go index a038d45b6bd..df834e9999c 100644 --- a/test/integration/users_test.go +++ b/test/integration/users_test.go @@ -13,7 +13,7 @@ import ( "math/rand" "testing" - "github.com/google/go-github/v30/github" + "github.com/google/go-github/v31/github" ) func TestUsers_Get(t *testing.T) { From 96260e22bbc2391de5883f0e0d960d3e4f925eed Mon Sep 17 00:00:00 2001 From: Vaibhav Date: Sat, 11 Apr 2020 18:56:57 +0530 Subject: [PATCH 0165/1468] Add test for Actions.ListRepositoryWorkflowRuns (#1492) Relates to #55. --- github/actions_workflow_runs_test.go | 35 ++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/github/actions_workflow_runs_test.go b/github/actions_workflow_runs_test.go index b31ca18d11e..2e7a8260baf 100644 --- a/github/actions_workflow_runs_test.go +++ b/github/actions_workflow_runs_test.go @@ -200,3 +200,38 @@ func TestActionsService_GetWorkflowRunLogs_StatusMovedPermanently_followRedirect t.Errorf("Actions.GetWorkflowJobLogs returned %+v, want %+v", url.String(), want) } } + +func TestActionService_ListRepositoryWorkflowRuns(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/repos/o/r/actions/runs", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + testFormValues(t, r, values{"per_page": "2", "page": "2"}) + fmt.Fprint(w, `{"total_count":2, + "workflow_runs":[ + {"id":298499444,"run_number":301,"created_at":"2020-04-11T11:14:54Z","updated_at":"2020-04-11T11:14:54Z"}, + {"id":298499445,"run_number":302,"created_at":"2020-04-11T11:14:54Z","updated_at":"2020-04-11T11:14:54Z"}]}`) + + }) + + opts := &ListOptions{Page: 2, PerPage: 2} + runs, _, err := client.Actions.ListRepositoryWorkflowRuns(context.Background(), "o", "r", opts) + + if err != nil { + t.Errorf("Actions.ListRepositoryWorkflowRuns returned error: %v", err) + } + + expected := &WorkflowRuns{ + TotalCount: Int(2), + WorkflowRuns: []*WorkflowRun{ + {ID: Int64(298499444), RunNumber: Int(301), CreatedAt: &Timestamp{time.Date(2020, time.April, 11, 11, 14, 54, 0, time.UTC)}, UpdatedAt: &Timestamp{time.Date(2020, time.April, 11, 11, 14, 54, 0, time.UTC)}}, + {ID: Int64(298499445), RunNumber: Int(302), CreatedAt: &Timestamp{time.Date(2020, time.April, 11, 11, 14, 54, 0, time.UTC)}, UpdatedAt: &Timestamp{time.Date(2020, time.April, 11, 11, 14, 54, 0, time.UTC)}}, + }, + } + + if !reflect.DeepEqual(runs, expected) { + t.Errorf("Actions.ListRepositoryWorkflowRuns returned %+v, want %+v", runs, expected) + } + +} From 4cd002782ff204f27f2b554886440c3c84641722 Mon Sep 17 00:00:00 2001 From: Jason Date: Thu, 16 Apr 2020 23:14:46 +1000 Subject: [PATCH 0166/1468] Update DeploymentStatus type (#1495) Fixes #1494. --- github/github-accessors.go | 32 ++++++++++++++++++++++++++++++++ github/repos_deployments.go | 29 +++++++++++++++++++---------- github/repos_deployments_test.go | 2 ++ 3 files changed, 53 insertions(+), 10 deletions(-) diff --git a/github/github-accessors.go b/github/github-accessors.go index 4141b9cd602..ca4b2678fcb 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -2556,6 +2556,22 @@ func (d *DeploymentStatus) GetDescription() string { return *d.Description } +// GetEnvironment returns the Environment field if it's non-nil, zero value otherwise. +func (d *DeploymentStatus) GetEnvironment() string { + if d == nil || d.Environment == nil { + return "" + } + return *d.Environment +} + +// GetEnvironmentURL returns the EnvironmentURL field if it's non-nil, zero value otherwise. +func (d *DeploymentStatus) GetEnvironmentURL() string { + if d == nil || d.EnvironmentURL == nil { + return "" + } + return *d.EnvironmentURL +} + // GetID returns the ID field if it's non-nil, zero value otherwise. func (d *DeploymentStatus) GetID() int64 { if d == nil || d.ID == nil { @@ -2564,6 +2580,14 @@ func (d *DeploymentStatus) GetID() int64 { return *d.ID } +// GetLogURL returns the LogURL field if it's non-nil, zero value otherwise. +func (d *DeploymentStatus) GetLogURL() string { + if d == nil || d.LogURL == nil { + return "" + } + return *d.LogURL +} + // GetNodeID returns the NodeID field if it's non-nil, zero value otherwise. func (d *DeploymentStatus) GetNodeID() string { if d == nil || d.NodeID == nil { @@ -2604,6 +2628,14 @@ func (d *DeploymentStatus) GetUpdatedAt() Timestamp { return *d.UpdatedAt } +// GetURL returns the URL field if it's non-nil, zero value otherwise. +func (d *DeploymentStatus) GetURL() string { + if d == nil || d.URL == nil { + return "" + } + return *d.URL +} + // GetDeployment returns the Deployment field. func (d *DeploymentStatusEvent) GetDeployment() *Deployment { if d == nil { diff --git a/github/repos_deployments.go b/github/repos_deployments.go index ace1778e9eb..57de0a22692 100644 --- a/github/repos_deployments.go +++ b/github/repos_deployments.go @@ -134,16 +134,21 @@ func (s *RepositoriesService) CreateDeployment(ctx context.Context, owner, repo type DeploymentStatus struct { ID *int64 `json:"id,omitempty"` // State is the deployment state. - // Possible values are: "pending", "success", "failure", "error", "inactive". - State *string `json:"state,omitempty"` - Creator *User `json:"creator,omitempty"` - Description *string `json:"description,omitempty"` - TargetURL *string `json:"target_url,omitempty"` - CreatedAt *Timestamp `json:"created_at,omitempty"` - UpdatedAt *Timestamp `json:"updated_at,omitempty"` - DeploymentURL *string `json:"deployment_url,omitempty"` - RepositoryURL *string `json:"repository_url,omitempty"` - NodeID *string `json:"node_id,omitempty"` + // Possible values are: "pending", "success", "failure", "error", + // "inactive", "in_progress", "queued". + State *string `json:"state,omitempty"` + Creator *User `json:"creator,omitempty"` + Description *string `json:"description,omitempty"` + Environment *string `json:"environment,omitempty"` + NodeID *string `json:"node_id,omitempty"` + CreatedAt *Timestamp `json:"created_at,omitempty"` + UpdatedAt *Timestamp `json:"updated_at,omitempty"` + TargetURL *string `json:"target_url,omitempty"` + DeploymentURL *string `json:"deployment_url,omitempty"` + RepositoryURL *string `json:"repository_url,omitempty"` + EnvironmentURL *string `json:"environment_url,omitempty"` + LogURL *string `json:"log_url,omitempty"` + URL *string `json:"url,omitempty"` } // DeploymentStatusRequest represents a deployment request @@ -171,6 +176,10 @@ func (s *RepositoriesService) ListDeploymentStatuses(ctx context.Context, owner, return nil, nil, err } + // TODO: remove custom Accept headers when APIs fully launch. + acceptHeaders := []string{mediaTypeDeploymentStatusPreview, mediaTypeExpandDeploymentStatusPreview} + req.Header.Set("Accept", strings.Join(acceptHeaders, ", ")) + var statuses []*DeploymentStatus resp, err := s.client.Do(ctx, req, &statuses) if err != nil { diff --git a/github/repos_deployments_test.go b/github/repos_deployments_test.go index 4e6ae6dcf54..fdbfdd3a9f8 100644 --- a/github/repos_deployments_test.go +++ b/github/repos_deployments_test.go @@ -93,8 +93,10 @@ func TestRepositoriesService_ListDeploymentStatuses(t *testing.T) { client, mux, _, teardown := setup() defer teardown() + wantAcceptHeaders := []string{mediaTypeDeploymentStatusPreview, mediaTypeExpandDeploymentStatusPreview} mux.HandleFunc("/repos/o/r/deployments/1/statuses", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") + testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", ")) testFormValues(t, r, values{"page": "2"}) fmt.Fprint(w, `[{"id":1}, {"id":2}]`) }) From 4ca0dcc089f42d84097334ba2376686736e28a95 Mon Sep 17 00:00:00 2001 From: Weslei Juan Moser Pereira Date: Sun, 19 Apr 2020 13:02:45 -0700 Subject: [PATCH 0167/1468] Remove graduated custom media headers (#1493) Fixes #1488. --- github/apps_installation.go | 1 - github/apps_installation_test.go | 1 - github/github.go | 6 ------ github/pulls.go | 10 +++------- github/pulls_test.go | 8 +++----- 5 files changed, 6 insertions(+), 20 deletions(-) diff --git a/github/apps_installation.go b/github/apps_installation.go index 2f7664cfbac..914afeaa61b 100644 --- a/github/apps_installation.go +++ b/github/apps_installation.go @@ -111,7 +111,6 @@ func (s *AppsService) RevokeInstallationToken(ctx context.Context) (*Response, e if err != nil { return nil, err } - req.Header.Set("Accept", mediaTypeRevokeTokenPreview) return s.client.Do(ctx, req, nil) } diff --git a/github/apps_installation_test.go b/github/apps_installation_test.go index 10955bf55f2..03a381d74b1 100644 --- a/github/apps_installation_test.go +++ b/github/apps_installation_test.go @@ -108,7 +108,6 @@ func TestAppsService_RevokeInstallationToken(t *testing.T) { mux.HandleFunc("/installation/token", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "DELETE") - testHeader(t, r, "Accept", mediaTypeRevokeTokenPreview) w.WriteHeader(http.StatusNoContent) }) diff --git a/github/github.go b/github/github.go index 94f31a4c261..c28aa591edc 100644 --- a/github/github.go +++ b/github/github.go @@ -46,9 +46,6 @@ const ( // Media Type values to access preview APIs - // https://developer.github.com/changes/2020-01-10-revoke-installation-token/ - mediaTypeRevokeTokenPreview = "application/vnd.github.gambit-preview+json" - // https://developer.github.com/changes/2014-12-09-new-attributes-for-stars-api/ mediaTypeStarringPreview = "application/vnd.github.v3.star+json" @@ -109,9 +106,6 @@ const ( // https://developer.github.com/changes/2018-12-18-interactions-preview/ mediaTypeInteractionRestrictionsPreview = "application/vnd.github.sombra-preview+json" - // https://developer.github.com/changes/2019-02-14-draft-pull-requests/ - mediaTypeDraftPreview = "application/vnd.github.shadow-cat-preview+json" - // https://developer.github.com/changes/2019-03-14-enabling-disabling-pages/ mediaTypeEnablePagesAPIPreview = "application/vnd.github.switcheroo-preview+json" diff --git a/github/pulls.go b/github/pulls.go index 019432659a2..685493f118a 100644 --- a/github/pulls.go +++ b/github/pulls.go @@ -149,7 +149,7 @@ func (s *PullRequestsService) List(ctx context.Context, owner string, repo strin } // TODO: remove custom Accept header when this API fully launches. - acceptHeaders := []string{mediaTypeLockReasonPreview, mediaTypeDraftPreview} + acceptHeaders := []string{mediaTypeLockReasonPreview} req.Header.Set("Accept", strings.Join(acceptHeaders, ", ")) var pulls []*PullRequest @@ -179,7 +179,7 @@ func (s *PullRequestsService) ListPullRequestsWithCommit(ctx context.Context, ow } // TODO: remove custom Accept header when this API fully launches. - acceptHeaders := []string{mediaTypeListPullsOrBranchesForCommitPreview, mediaTypeDraftPreview, mediaTypeLockReasonPreview} + acceptHeaders := []string{mediaTypeListPullsOrBranchesForCommitPreview, mediaTypeLockReasonPreview} req.Header.Set("Accept", strings.Join(acceptHeaders, ", ")) var pulls []*PullRequest resp, err := s.client.Do(ctx, req, &pulls) @@ -201,7 +201,7 @@ func (s *PullRequestsService) Get(ctx context.Context, owner string, repo string } // TODO: remove custom Accept header when this API fully launches. - acceptHeaders := []string{mediaTypeLockReasonPreview, mediaTypeDraftPreview} + acceptHeaders := []string{mediaTypeLockReasonPreview} req.Header.Set("Accept", strings.Join(acceptHeaders, ", ")) pull := new(PullRequest) @@ -262,10 +262,6 @@ func (s *PullRequestsService) Create(ctx context.Context, owner string, repo str return nil, nil, err } - // TODO: remove custom Accept header when this API fully launches. - acceptHeaders := []string{mediaTypeDraftPreview} - req.Header.Set("Accept", strings.Join(acceptHeaders, ", ")) - p := new(PullRequest) resp, err := s.client.Do(ctx, req, p) if err != nil { diff --git a/github/pulls_test.go b/github/pulls_test.go index d05e7a9b42c..67f6d0b0033 100644 --- a/github/pulls_test.go +++ b/github/pulls_test.go @@ -20,7 +20,7 @@ func TestPullRequestsService_List(t *testing.T) { client, mux, _, teardown := setup() defer teardown() - wantAcceptHeaders := []string{mediaTypeLockReasonPreview, mediaTypeDraftPreview} + wantAcceptHeaders := []string{mediaTypeLockReasonPreview} mux.HandleFunc("/repos/o/r/pulls", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", ")) @@ -51,7 +51,7 @@ func TestPullRequestsService_ListPullRequestsWithCommit(t *testing.T) { client, mux, _, teardown := setup() defer teardown() - wantAcceptHeaders := []string{mediaTypeListPullsOrBranchesForCommitPreview, mediaTypeDraftPreview, mediaTypeLockReasonPreview} + wantAcceptHeaders := []string{mediaTypeListPullsOrBranchesForCommitPreview, 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, ", ")) @@ -90,7 +90,7 @@ func TestPullRequestsService_Get(t *testing.T) { client, mux, _, teardown := setup() defer teardown() - wantAcceptHeaders := []string{mediaTypeLockReasonPreview, mediaTypeDraftPreview} + wantAcceptHeaders := []string{mediaTypeLockReasonPreview} mux.HandleFunc("/repos/o/r/pulls/1", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", ")) @@ -306,8 +306,6 @@ func TestPullRequestsService_Create(t *testing.T) { json.NewDecoder(r.Body).Decode(v) testMethod(t, r, "POST") - wantAcceptHeaders := []string{mediaTypeDraftPreview} - testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", ")) if !reflect.DeepEqual(v, input) { t.Errorf("Request body = %+v, want %+v", v, input) } From 8ac6f14a9aeb705bcc5d70a3761187848d2e640e Mon Sep 17 00:00:00 2001 From: Ryan Williams <49515+ryanwi@users.noreply.github.com> Date: Sun, 19 Apr 2020 17:53:25 -0700 Subject: [PATCH 0168/1468] Add Repository to the RepositoryVulnerabilityAlertEvent struct (#1496) --- github/event_types.go | 3 +++ github/github-accessors.go | 8 ++++++++ 2 files changed, 11 insertions(+) diff --git a/github/event_types.go b/github/event_types.go index 2c18de6c13f..bbb25af2a7e 100644 --- a/github/event_types.go +++ b/github/event_types.go @@ -819,6 +819,9 @@ type RepositoryVulnerabilityAlertEvent struct { DismissReason *string `json:"dismiss_reason,omitempty"` DismissedAt *Timestamp `json:"dismissed_at,omitempty"` } `json:"alert,omitempty"` + + //The repository of the vulnerable dependency. + Repository *Repository `json:"repository,omitempty"` } // StarEvent is triggered when a star is added or removed from a repository. diff --git a/github/github-accessors.go b/github/github-accessors.go index ca4b2678fcb..884f1acc6de 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -11540,6 +11540,14 @@ func (r *RepositoryVulnerabilityAlertEvent) GetAction() string { return *r.Action } +// GetRepository returns the Repository field. +func (r *RepositoryVulnerabilityAlertEvent) GetRepository() *Repository { + if r == nil { + return nil + } + return r.Repository +} + // GetForkRepos returns the ForkRepos field if it's non-nil, zero value otherwise. func (r *RepoStats) GetForkRepos() int { if r == nil || r.ForkRepos == nil { From 7623a89a08ea24ad76df72a8d7fb8bc6efbff241 Mon Sep 17 00:00:00 2001 From: Austin Burdine Date: Mon, 20 Apr 2020 14:30:02 -0400 Subject: [PATCH 0169/1468] Update ListRepositoryWorkflowRuns to support all query parameters (#1498) Fixes #1497 --- github/actions_workflow_runs.go | 2 +- github/actions_workflow_runs_test.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/github/actions_workflow_runs.go b/github/actions_workflow_runs.go index b365bb1c75a..8b12944184a 100644 --- a/github/actions_workflow_runs.go +++ b/github/actions_workflow_runs.go @@ -93,7 +93,7 @@ func (s *ActionsService) ListWorkflowRunsByFileName(ctx context.Context, owner, // ListRepositoryWorkflowRuns lists all workflow runs for a repository. // // GitHub API docs: https://developer.github.com/v3/actions/workflow_runs/#list-repository-workflow-runs -func (s *ActionsService) ListRepositoryWorkflowRuns(ctx context.Context, owner, repo string, opts *ListOptions) (*WorkflowRuns, *Response, error) { +func (s *ActionsService) ListRepositoryWorkflowRuns(ctx context.Context, owner, repo string, opts *ListWorkflowRunsOptions) (*WorkflowRuns, *Response, error) { u := fmt.Sprintf("repos/%s/%s/actions/runs", owner, repo) u, err := addOptions(u, opts) if err != nil { diff --git a/github/actions_workflow_runs_test.go b/github/actions_workflow_runs_test.go index 2e7a8260baf..48e5cc30af3 100644 --- a/github/actions_workflow_runs_test.go +++ b/github/actions_workflow_runs_test.go @@ -215,7 +215,7 @@ func TestActionService_ListRepositoryWorkflowRuns(t *testing.T) { }) - opts := &ListOptions{Page: 2, PerPage: 2} + opts := &ListWorkflowRunsOptions{ListOptions: ListOptions{Page: 2, PerPage: 2}} runs, _, err := client.Actions.ListRepositoryWorkflowRuns(context.Background(), "o", "r", opts) if err != nil { From 6a666c5177f516c840488bb4a0bb4a2d7799a5fe Mon Sep 17 00:00:00 2001 From: Reinier Timmer Date: Fri, 24 Apr 2020 16:18:32 +0200 Subject: [PATCH 0170/1468] Support self-hosted organization runners (#1506) Fixes #1505. --- github/actions_runners.go | 128 +++++++++++++++++++++++++++++-- github/actions_runners_test.go | 135 +++++++++++++++++++++++++++++++++ 2 files changed, 257 insertions(+), 6 deletions(-) diff --git a/github/actions_runners.go b/github/actions_runners.go index 24f88f0f990..ce5dd56049d 100644 --- a/github/actions_runners.go +++ b/github/actions_runners.go @@ -20,7 +20,7 @@ type RunnerApplicationDownload struct { // ListRunnerApplicationDownloads lists self-hosted runner application binaries that can be downloaded and run. // -// GitHub API docs: https://developer.github.com/v3/actions/self_hosted_runners/#list-downloads-for-the-self-hosted-runner-application +// GitHub API docs: https://developer.github.com/v3/actions/self-hosted-runners/#list-runner-applications-for-a-repository func (s *ActionsService) ListRunnerApplicationDownloads(ctx context.Context, owner, repo string) ([]*RunnerApplicationDownload, *Response, error) { u := fmt.Sprintf("repos/%v/%v/actions/runners/downloads", owner, repo) req, err := s.client.NewRequest("GET", u, nil) @@ -45,7 +45,7 @@ type RegistrationToken struct { // CreateRegistrationToken creates a token that can be used to add a self-hosted runner. // -// GitHub API docs: https://developer.github.com/v3/actions/self_hosted_runners/#create-a-registration-token +// GitHub API docs: https://developer.github.com/v3/actions/self-hosted-runners/#create-a-registration-token-for-a-repository func (s *ActionsService) CreateRegistrationToken(ctx context.Context, owner, repo string) (*RegistrationToken, *Response, error) { u := fmt.Sprintf("repos/%v/%v/actions/runners/registration-token", owner, repo) @@ -79,7 +79,7 @@ type Runners struct { // ListRunners lists all the self-hosted runners for a repository. // -// GitHub API docs: https://developer.github.com/v3/actions/self_hosted_runners/#list-self-hosted-runners-for-a-repository +// GitHub API docs: https://developer.github.com/v3/actions/self-hosted-runners/#list-self-hosted-runners-for-a-repository func (s *ActionsService) ListRunners(ctx context.Context, owner, repo string, opts *ListOptions) (*Runners, *Response, error) { u := fmt.Sprintf("repos/%v/%v/actions/runners", owner, repo) u, err := addOptions(u, opts) @@ -103,7 +103,7 @@ func (s *ActionsService) ListRunners(ctx context.Context, owner, repo string, op // GetRunner gets a specific self-hosted runner for a repository using its runner ID. // -// GitHub API docs: https://developer.github.com/v3/actions/self_hosted_runners/#get-a-self-hosted-runner +// GitHub API docs: https://developer.github.com/v3/actions/self-hosted-runners/#get-a-self-hosted-runner-for-a-repository func (s *ActionsService) GetRunner(ctx context.Context, owner, repo string, runnerID int64) (*Runner, *Response, error) { u := fmt.Sprintf("repos/%v/%v/actions/runners/%v", owner, repo, runnerID) req, err := s.client.NewRequest("GET", u, nil) @@ -128,7 +128,7 @@ type RemoveToken struct { // CreateRemoveToken creates a token that can be used to remove a self-hosted runner from a repository. // -// GitHub API docs: https://developer.github.com/v3/actions/self_hosted_runners/#create-a-remove-token +// GitHub API docs: https://developer.github.com/v3/actions/self-hosted-runners/#create-a-remove-token-for-a-repository func (s *ActionsService) CreateRemoveToken(ctx context.Context, owner, repo string) (*RemoveToken, *Response, error) { u := fmt.Sprintf("repos/%v/%v/actions/runners/remove-token", owner, repo) @@ -148,7 +148,7 @@ func (s *ActionsService) CreateRemoveToken(ctx context.Context, owner, repo stri // RemoveRunner forces the removal of a self-hosted runner in a repository using the runner id. // -// GitHub API docs: https://developer.github.com/v3/actions/self_hosted_runners/#remove-a-self-hosted-runner +// GitHub API docs: https://developer.github.com/v3/actions/self-hosted-runners/#delete-a-self-hosted-runner-from-a-repository func (s *ActionsService) RemoveRunner(ctx context.Context, owner, repo string, runnerID int64) (*Response, error) { u := fmt.Sprintf("repos/%v/%v/actions/runners/%v", owner, repo, runnerID) @@ -159,3 +159,119 @@ func (s *ActionsService) RemoveRunner(ctx context.Context, owner, repo string, r return s.client.Do(ctx, req, nil) } + +// ListOrganizationRunnerApplicationDownloads lists self-hosted runner application binaries that can be downloaded and run. +// +// GitHub API docs: https://developer.github.com/v3/actions/self-hosted-runners/#list-runner-applications-for-an-organization +func (s *ActionsService) ListOrganizationRunnerApplicationDownloads(ctx context.Context, owner string) ([]*RunnerApplicationDownload, *Response, error) { + u := fmt.Sprintf("orgs/%v/actions/runners/downloads", owner) + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + + var rads []*RunnerApplicationDownload + resp, err := s.client.Do(ctx, req, &rads) + if err != nil { + return nil, resp, err + } + + return rads, resp, nil +} + +// CreateOrganizationRegistrationToken creates a token that can be used to add a self-hosted runner to an organization. +// +// GitHub API docs: https://developer.github.com/v3/actions/self-hosted-runners/#create-a-registration-token-for-an-organization +func (s *ActionsService) CreateOrganizationRegistrationToken(ctx context.Context, owner string) (*RegistrationToken, *Response, error) { + u := fmt.Sprintf("orgs/%v/actions/runners/registration-token", owner) + + req, err := s.client.NewRequest("POST", u, nil) + if err != nil { + return nil, nil, err + } + + registrationToken := new(RegistrationToken) + resp, err := s.client.Do(ctx, req, registrationToken) + if err != nil { + return nil, resp, err + } + + return registrationToken, resp, nil +} + +// ListOrganizationRunners lists all the self-hosted runners for an organization. +// +// GitHub API docs: https://developer.github.com/v3/actions/self-hosted-runners/#list-self-hosted-runners-for-an-organization +func (s *ActionsService) ListOrganizationRunners(ctx context.Context, owner string, opts *ListOptions) (*Runners, *Response, error) { + u := fmt.Sprintf("orgs/%v/actions/runners", owner) + u, err := addOptions(u, opts) + if err != nil { + return nil, nil, err + } + + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + + runners := &Runners{} + resp, err := s.client.Do(ctx, req, &runners) + if err != nil { + return nil, resp, err + } + + return runners, resp, nil +} + +// GetOrganizationRunner gets a specific self-hosted runner for an organization using its runner ID. +// +// GitHub API docs: https://developer.github.com/v3/actions/self-hosted-runners/#list-self-hosted-runners-for-an-organization +func (s *ActionsService) GetOrganizationRunner(ctx context.Context, owner string, runnerID int64) (*Runner, *Response, error) { + u := fmt.Sprintf("orgs/%v/actions/runners/%v", owner, runnerID) + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + + runner := new(Runner) + resp, err := s.client.Do(ctx, req, runner) + if err != nil { + return nil, resp, err + } + + return runner, resp, nil +} + +// CreateOrganizationRemoveToken creates a token that can be used to remove a self-hosted runner from an organization. +// +// GitHub API docs: https://developer.github.com/v3/actions/self-hosted-runners/#create-a-remove-token-for-an-organization +func (s *ActionsService) CreateOrganizationRemoveToken(ctx context.Context, owner string) (*RemoveToken, *Response, error) { + u := fmt.Sprintf("orgs/%v/actions/runners/remove-token", owner) + + req, err := s.client.NewRequest("POST", u, nil) + if err != nil { + return nil, nil, err + } + + removeToken := new(RemoveToken) + resp, err := s.client.Do(ctx, req, removeToken) + if err != nil { + return nil, resp, err + } + + return removeToken, resp, nil +} + +// RemoveOrganizationRunner forces the removal of a self-hosted runner from an organization using the runner id. +// +// GitHub API docs: https://developer.github.com/v3/actions/self-hosted-runners/#delete-a-self-hosted-runner-from-an-organization +func (s *ActionsService) RemoveOrganizationRunner(ctx context.Context, owner string, runnerID int64) (*Response, error) { + u := fmt.Sprintf("orgs/%v/actions/runners/%v", owner, runnerID) + + req, err := s.client.NewRequest("DELETE", u, nil) + if err != nil { + return nil, err + } + + return s.client.Do(ctx, req, nil) +} diff --git a/github/actions_runners_test.go b/github/actions_runners_test.go index 13ceeea6a9d..86bec24047c 100644 --- a/github/actions_runners_test.go +++ b/github/actions_runners_test.go @@ -148,3 +148,138 @@ func TestActionsService_RemoveRunner(t *testing.T) { t.Errorf("Actions.RemoveRunner returned error: %v", err) } } + +func TestActionsService_ListOrganizationRunnerApplicationDownloads(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/orgs/o/actions/runners/downloads", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + fmt.Fprint(w, `[{"os":"osx","architecture":"x64","download_url":"https://github.com/actions/runner/releases/download/v2.164.0/actions-runner-osx-x64-2.164.0.tar.gz","filename":"actions-runner-osx-x64-2.164.0.tar.gz"},{"os":"linux","architecture":"x64","download_url":"https://github.com/actions/runner/releases/download/v2.164.0/actions-runner-linux-x64-2.164.0.tar.gz","filename":"actions-runner-linux-x64-2.164.0.tar.gz"},{"os": "linux","architecture":"arm","download_url":"https://github.com/actions/runner/releases/download/v2.164.0/actions-runner-linux-arm-2.164.0.tar.gz","filename":"actions-runner-linux-arm-2.164.0.tar.gz"},{"os":"win","architecture":"x64","download_url":"https://github.com/actions/runner/releases/download/v2.164.0/actions-runner-win-x64-2.164.0.zip","filename":"actions-runner-win-x64-2.164.0.zip"},{"os":"linux","architecture":"arm64","download_url":"https://github.com/actions/runner/releases/download/v2.164.0/actions-runner-linux-arm64-2.164.0.tar.gz","filename":"actions-runner-linux-arm64-2.164.0.tar.gz"}]`) + }) + + downloads, _, err := client.Actions.ListOrganizationRunnerApplicationDownloads(context.Background(), "o") + if err != nil { + t.Errorf("Actions.ListRunnerApplicationDownloads returned error: %v", err) + } + + want := []*RunnerApplicationDownload{ + {OS: String("osx"), Architecture: String("x64"), DownloadURL: String("https://github.com/actions/runner/releases/download/v2.164.0/actions-runner-osx-x64-2.164.0.tar.gz"), Filename: String("actions-runner-osx-x64-2.164.0.tar.gz")}, + {OS: String("linux"), Architecture: String("x64"), DownloadURL: String("https://github.com/actions/runner/releases/download/v2.164.0/actions-runner-linux-x64-2.164.0.tar.gz"), Filename: String("actions-runner-linux-x64-2.164.0.tar.gz")}, + {OS: String("linux"), Architecture: String("arm"), DownloadURL: String("https://github.com/actions/runner/releases/download/v2.164.0/actions-runner-linux-arm-2.164.0.tar.gz"), Filename: String("actions-runner-linux-arm-2.164.0.tar.gz")}, + {OS: String("win"), Architecture: String("x64"), DownloadURL: String("https://github.com/actions/runner/releases/download/v2.164.0/actions-runner-win-x64-2.164.0.zip"), Filename: String("actions-runner-win-x64-2.164.0.zip")}, + {OS: String("linux"), Architecture: String("arm64"), DownloadURL: String("https://github.com/actions/runner/releases/download/v2.164.0/actions-runner-linux-arm64-2.164.0.tar.gz"), Filename: String("actions-runner-linux-arm64-2.164.0.tar.gz")}, + } + if !reflect.DeepEqual(downloads, want) { + t.Errorf("Actions.ListOrganizationRunnerApplicationDownloads returned %+v, want %+v", downloads, want) + } +} + +func TestActionsService_CreateOrganizationRegistrationToken(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/orgs/o/actions/runners/registration-token", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "POST") + fmt.Fprint(w, `{"token":"LLBF3JGZDX3P5PMEXLND6TS6FCWO6","expires_at":"2020-01-22T12:13:35.123Z"}`) + }) + + token, _, err := client.Actions.CreateOrganizationRegistrationToken(context.Background(), "o") + if err != nil { + t.Errorf("Actions.CreateRegistrationToken returned error: %v", err) + } + + want := &RegistrationToken{Token: String("LLBF3JGZDX3P5PMEXLND6TS6FCWO6"), + ExpiresAt: &Timestamp{time.Date(2020, time.January, 22, 12, 13, 35, + 123000000, time.UTC)}} + if !reflect.DeepEqual(token, want) { + t.Errorf("Actions.CreateRegistrationToken returned %+v, want %+v", token, want) + } +} + +func TestActionsService_ListOrganizationRunners(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/orgs/o/actions/runners", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + testFormValues(t, r, values{"per_page": "2", "page": "2"}) + fmt.Fprint(w, `{"total_count":2,"runners":[{"id":23,"name":"MBP","os":"macos","status":"online"},{"id":24,"name":"iMac","os":"macos","status":"offline"}]}`) + }) + + opts := &ListOptions{Page: 2, PerPage: 2} + runners, _, err := client.Actions.ListOrganizationRunners(context.Background(), "o", opts) + if err != nil { + t.Errorf("Actions.ListRunners returned error: %v", err) + } + + want := &Runners{ + TotalCount: 2, + Runners: []*Runner{ + {ID: Int64(23), Name: String("MBP"), OS: String("macos"), Status: String("online")}, + {ID: Int64(24), Name: String("iMac"), OS: String("macos"), Status: String("offline")}, + }, + } + if !reflect.DeepEqual(runners, want) { + t.Errorf("Actions.ListRunners returned %+v, want %+v", runners, want) + } +} + +func TestActionsService_GetOrganizationRunner(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/orgs/o/actions/runners/23", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + fmt.Fprint(w, `{"id":23,"name":"MBP","os":"macos","status":"online"}`) + }) + + runner, _, err := client.Actions.GetOrganizationRunner(context.Background(), "o", 23) + if err != nil { + t.Errorf("Actions.GetRunner returned error: %v", err) + } + + want := &Runner{ + ID: Int64(23), + Name: String("MBP"), + OS: String("macos"), + Status: String("online"), + } + if !reflect.DeepEqual(runner, want) { + t.Errorf("Actions.GetRunner returned %+v, want %+v", runner, want) + } +} + +func TestActionsService_CreateOrganizationRemoveToken(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/orgs/o/actions/runners/remove-token", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "POST") + fmt.Fprint(w, `{"token":"AABF3JGZDX3P5PMEXLND6TS6FCWO6","expires_at":"2020-01-29T12:13:35.123Z"}`) + }) + + token, _, err := client.Actions.CreateOrganizationRemoveToken(context.Background(), "o") + if err != nil { + t.Errorf("Actions.CreateRemoveToken returned error: %v", err) + } + + want := &RemoveToken{Token: String("AABF3JGZDX3P5PMEXLND6TS6FCWO6"), ExpiresAt: &Timestamp{time.Date(2020, time.January, 29, 12, 13, 35, 123000000, time.UTC)}} + if !reflect.DeepEqual(token, want) { + t.Errorf("Actions.CreateRemoveToken returned %+v, want %+v", token, want) + } +} + +func TestActionsService_RemoveOrganizationRunner(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/orgs/o/actions/runners/21", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "DELETE") + }) + + _, err := client.Actions.RemoveOrganizationRunner(context.Background(), "o", 21) + if err != nil { + t.Errorf("Actions.RemoveOganizationRunner returned error: %v", err) + } +} From 48d6e3eb954ecd18b8976cf6b705494eafbd0be2 Mon Sep 17 00:00:00 2001 From: Ryan Mast Date: Sat, 25 Apr 2020 09:29:21 -0700 Subject: [PATCH 0171/1468] Update changed API doc URLs (#1507) Fixes #1502. --- github/actions_workflow_jobs.go | 6 +++--- github/actions_workflow_runs.go | 14 +++++++------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/github/actions_workflow_jobs.go b/github/actions_workflow_jobs.go index 0838ce48d74..2d7973fbc5d 100644 --- a/github/actions_workflow_jobs.go +++ b/github/actions_workflow_jobs.go @@ -60,7 +60,7 @@ type ListWorkflowJobsOptions struct { // ListWorkflowJobs lists all jobs for a workflow run. // -// GitHub API docs: https://developer.github.com/v3/actions/workflow_jobs/#list-jobs-for-a-workflow-run +// GitHub API docs: https://developer.github.com/v3/actions/workflow-jobs/#list-jobs-for-a-workflow-run func (s *ActionsService) ListWorkflowJobs(ctx context.Context, owner, repo string, runID int64, opts *ListWorkflowJobsOptions) (*Jobs, *Response, error) { u := fmt.Sprintf("repos/%s/%s/actions/runs/%v/jobs", owner, repo, runID) u, err := addOptions(u, opts) @@ -84,7 +84,7 @@ func (s *ActionsService) ListWorkflowJobs(ctx context.Context, owner, repo strin // GetWorkflowJobByID gets a specific job in a workflow run by ID. // -// GitHub API docs: https://developer.github.com/v3/actions/workflow_jobs/#get-a-workflow-job +// GitHub API docs: https://developer.github.com/v3/actions/workflow-jobs/#get-a-workflow-job func (s *ActionsService) GetWorkflowJobByID(ctx context.Context, owner, repo string, jobID int64) (*WorkflowJob, *Response, error) { u := fmt.Sprintf("repos/%v/%v/actions/jobs/%v", owner, repo, jobID) @@ -104,7 +104,7 @@ func (s *ActionsService) GetWorkflowJobByID(ctx context.Context, owner, repo str // GetWorkflowJobLogs gets a redirect URL to download a plain text file of logs for a workflow job. // -// GitHub API docs: https://developer.github.com/v3/actions/workflow_jobs/#list-workflow-job-logs +// GitHub API docs: https://developer.github.com/v3/actions/workflow-jobs/#list-workflow-job-logs func (s *ActionsService) GetWorkflowJobLogs(ctx context.Context, owner, repo string, jobID int64, followRedirects bool) (*url.URL, *Response, error) { u := fmt.Sprintf("repos/%v/%v/actions/jobs/%v/logs", owner, repo, jobID) diff --git a/github/actions_workflow_runs.go b/github/actions_workflow_runs.go index 8b12944184a..cd8e33fa809 100644 --- a/github/actions_workflow_runs.go +++ b/github/actions_workflow_runs.go @@ -76,7 +76,7 @@ func (s *ActionsService) listWorkflowRuns(ctx context.Context, endpoint string, // ListWorkflowRunsByID lists all workflow runs by workflow ID. // -// GitHub API docs: https://developer.github.com/v3/actions/workflow_runs/#list-workflow-runs +// GitHub API docs: https://developer.github.com/v3/actions/workflow-runs/#list-workflow-runs func (s *ActionsService) ListWorkflowRunsByID(ctx context.Context, owner, repo string, workflowID int64, opts *ListWorkflowRunsOptions) (*WorkflowRuns, *Response, error) { u := fmt.Sprintf("repos/%s/%s/actions/workflows/%v/runs", owner, repo, workflowID) return s.listWorkflowRuns(ctx, u, opts) @@ -84,7 +84,7 @@ func (s *ActionsService) ListWorkflowRunsByID(ctx context.Context, owner, repo s // ListWorkflowRunsByFileName lists all workflow runs by workflow file name. // -// GitHub API docs: https://developer.github.com/v3/actions/workflow_runs/#list-workflow-runs +// GitHub API docs: https://developer.github.com/v3/actions/workflow-runs/#list-workflow-runs func (s *ActionsService) ListWorkflowRunsByFileName(ctx context.Context, owner, repo, workflowFileName string, opts *ListWorkflowRunsOptions) (*WorkflowRuns, *Response, error) { u := fmt.Sprintf("repos/%s/%s/actions/workflows/%v/runs", owner, repo, workflowFileName) return s.listWorkflowRuns(ctx, u, opts) @@ -92,7 +92,7 @@ func (s *ActionsService) ListWorkflowRunsByFileName(ctx context.Context, owner, // ListRepositoryWorkflowRuns lists all workflow runs for a repository. // -// GitHub API docs: https://developer.github.com/v3/actions/workflow_runs/#list-repository-workflow-runs +// GitHub API docs: https://developer.github.com/v3/actions/workflow-runs/#list-repository-workflow-runs func (s *ActionsService) ListRepositoryWorkflowRuns(ctx context.Context, owner, repo string, opts *ListWorkflowRunsOptions) (*WorkflowRuns, *Response, error) { u := fmt.Sprintf("repos/%s/%s/actions/runs", owner, repo) u, err := addOptions(u, opts) @@ -116,7 +116,7 @@ func (s *ActionsService) ListRepositoryWorkflowRuns(ctx context.Context, owner, // GetWorkflowRunByID gets a specific workflow run by ID. // -// GitHub API docs: https://developer.github.com/v3/actions/workflow_runs/#get-a-workflow-run +// GitHub API docs: https://developer.github.com/v3/actions/workflow-runs/#get-a-workflow-run func (s *ActionsService) GetWorkflowRunByID(ctx context.Context, owner, repo string, runID int64) (*WorkflowRun, *Response, error) { u := fmt.Sprintf("repos/%v/%v/actions/runs/%v", owner, repo, runID) @@ -136,7 +136,7 @@ func (s *ActionsService) GetWorkflowRunByID(ctx context.Context, owner, repo str // RerunWorkflow re-runs a workflow by ID. // -// GitHub API docs: https://developer.github.com/v3/actions/workflow_runs/#re-run-a-workflow +// GitHub API docs: https://developer.github.com/v3/actions/workflow-runs/#re-run-a-workflow func (s *ActionsService) RerunWorkflowByID(ctx context.Context, owner, repo string, runID int64) (*Response, error) { u := fmt.Sprintf("repos/%v/%v/actions/runs/%v/rerun", owner, repo, runID) @@ -150,7 +150,7 @@ func (s *ActionsService) RerunWorkflowByID(ctx context.Context, owner, repo stri // CancelWorkflowRunByID cancels a workflow run by ID. // -// GitHub API docs: https://developer.github.com/v3/actions/workflow_runs/#cancel-a-workflow-run +// GitHub API docs: https://developer.github.com/v3/actions/workflow-runs/#cancel-a-workflow-run func (s *ActionsService) CancelWorkflowRunByID(ctx context.Context, owner, repo string, runID int64) (*Response, error) { u := fmt.Sprintf("repos/%v/%v/actions/runs/%v/cancel", owner, repo, runID) @@ -164,7 +164,7 @@ func (s *ActionsService) CancelWorkflowRunByID(ctx context.Context, owner, repo // GetWorkflowRunLogs gets a redirect URL to download a plain text file of logs for a workflow run. // -// GitHub API docs: https://developer.github.com/v3/actions/workflow_runs/#list-workflow-run-logs +// GitHub API docs: https://developer.github.com/v3/actions/workflow-runs/#list-workflow-run-logs func (s *ActionsService) GetWorkflowRunLogs(ctx context.Context, owner, repo string, runID int64, followRedirects bool) (*url.URL, *Response, error) { u := fmt.Sprintf("repos/%v/%v/actions/runs/%v/logs", owner, repo, runID) From 3b4049a036b626f505d37740bac9e5d03ab12347 Mon Sep 17 00:00:00 2001 From: Glenn Lewis <6598971+gmlewis@users.noreply.github.com> Date: Sat, 25 Apr 2020 12:45:38 -0400 Subject: [PATCH 0172/1468] Update URL (#1508) --- github/actions_runners.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/github/actions_runners.go b/github/actions_runners.go index ce5dd56049d..2cac674e043 100644 --- a/github/actions_runners.go +++ b/github/actions_runners.go @@ -225,7 +225,7 @@ func (s *ActionsService) ListOrganizationRunners(ctx context.Context, owner stri // GetOrganizationRunner gets a specific self-hosted runner for an organization using its runner ID. // -// GitHub API docs: https://developer.github.com/v3/actions/self-hosted-runners/#list-self-hosted-runners-for-an-organization +// GitHub API docs: https://developer.github.com/v3/actions/self-hosted-runners/#get-a-self-hosted-runner-for-an-organization func (s *ActionsService) GetOrganizationRunner(ctx context.Context, owner string, runnerID int64) (*Runner, *Response, error) { u := fmt.Sprintf("orgs/%v/actions/runners/%v", owner, runnerID) req, err := s.client.NewRequest("GET", u, nil) From 80d007d8679f58cc1bcc9647849501219ea831ca Mon Sep 17 00:00:00 2001 From: Glenn Lewis <6598971+gmlewis@users.noreply.github.com> Date: Sat, 25 Apr 2020 12:54:33 -0400 Subject: [PATCH 0173/1468] Update AUTHORS with recent contributors (#1509) --- AUTHORS | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/AUTHORS b/AUTHORS index 4dd8d21b80d..cafdf91de42 100644 --- a/AUTHORS +++ b/AUTHORS @@ -9,12 +9,14 @@ # their employer, as appropriate). 178inaba +2BFL 413x Abhinav Gupta adrienzieba Ahmed Hagy Aidan Steele Ainsley Chong +ajz01 Akeda Bagus Akhil Mohan Alec Thomas @@ -30,6 +32,7 @@ Andrew Ryabchun Andy Grunwald Andy Hume Andy Lindeman +angie pinilla anjanashenoy Anshuman Bhartiya Antoine @@ -39,6 +42,7 @@ appilon Aravind Arda Kuyumcu Arıl Bozoluk +Austin Burdine Austin Dizzy Ben Batha Benjamen Keroack @@ -209,6 +213,7 @@ Pete Wagner Petr Shevtsov Pierre Carrier Piotr Zurek +Pratik Mallya Qais Patankar Quang Le Hong Quentin Leffray @@ -223,6 +228,7 @@ Ravi Shekhar Jethani RaviTeja Pothana rc1140 Red Hat, Inc. +Reinier Timmer Ricco Førgaard Rob Figueiredo Rohit Upadhyay @@ -275,6 +281,7 @@ Victor Vrantchan vikkyomkar Vlad Ungureanu Wasim Thabraze +Weslei Juan Moser Pereira Will Maier Willem D'Haeseleer William Bailey From 378bcfd2d1d7a0e32308180b5beb06d3351ca9d1 Mon Sep 17 00:00:00 2001 From: SteelPhase Date: Mon, 27 Apr 2020 20:58:39 -0400 Subject: [PATCH 0174/1468] Correct Enterprise upload url (#1510) --- github/github.go | 12 +++++++----- github/github_test.go | 8 ++++---- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/github/github.go b/github/github.go index c28aa591edc..888da212746 100644 --- a/github/github.go +++ b/github/github.go @@ -291,8 +291,9 @@ func NewClient(httpClient *http.Client) *Client { } // NewEnterpriseClient returns a new GitHub API client with provided -// base URL and upload URL (often the same URL and is your GitHub Enterprise hostname). -// If either URL does not have the suffix "/api/v3/", it will be added automatically. +// base URL and upload URL (often is your GitHub Enterprise hostname). +// If the base URL does not have the suffix "/api/v3/", it will be added automatically. +// If the upload URL does not have the suffix "/api/uploads", it will be added automatically. // If a nil httpClient is provided, a new http.Client will be used. // // Note that NewEnterpriseClient is a convenience helper only; @@ -300,7 +301,8 @@ func NewClient(httpClient *http.Client) *Client { // the BaseURL and UploadURL fields. // // Another important thing is that by default, the GitHub Enterprise URL format -// should be http(s)://[hostname]/api/v3 or you will always receive the 406 status code. +// should be http(s)://[hostname]/api/v3/ or you will always receive the 406 status code. +// The upload URL format should be http(s)://[hostname]/api/uploads/. func NewEnterpriseClient(baseURL, uploadURL string, httpClient *http.Client) (*Client, error) { baseEndpoint, err := url.Parse(baseURL) if err != nil { @@ -320,8 +322,8 @@ func NewEnterpriseClient(baseURL, uploadURL string, httpClient *http.Client) (*C if !strings.HasSuffix(uploadEndpoint.Path, "/") { uploadEndpoint.Path += "/" } - if !strings.HasSuffix(uploadEndpoint.Path, "/api/v3/") { - uploadEndpoint.Path += "api/v3/" + if !strings.HasSuffix(uploadEndpoint.Path, "/api/uploads/") { + uploadEndpoint.Path += "api/uploads/" } c := NewClient(httpClient) diff --git a/github/github_test.go b/github/github_test.go index 719741bc57b..2d5ac738dca 100644 --- a/github/github_test.go +++ b/github/github_test.go @@ -184,7 +184,7 @@ func TestNewClient(t *testing.T) { func TestNewEnterpriseClient(t *testing.T) { baseURL := "https://custom-url/api/v3/" - uploadURL := "https://custom-upload-url/api/v3/" + uploadURL := "https://custom-upload-url/api/uploads/" c, err := NewEnterpriseClient(baseURL, uploadURL, nil) if err != nil { t.Fatalf("NewEnterpriseClient returned unexpected error: %v", err) @@ -200,7 +200,7 @@ func TestNewEnterpriseClient(t *testing.T) { func TestNewEnterpriseClient_addsTrailingSlashToURLs(t *testing.T) { baseURL := "https://custom-url/api/v3" - uploadURL := "https://custom-upload-url/api/v3" + uploadURL := "https://custom-upload-url/api/uploads" formattedBaseURL := baseURL + "/" formattedUploadURL := uploadURL + "/" @@ -221,7 +221,7 @@ func TestNewEnterpriseClient_addsEnterpriseSuffixToURLs(t *testing.T) { baseURL := "https://custom-url/" uploadURL := "https://custom-upload-url/" formattedBaseURL := baseURL + "api/v3/" - formattedUploadURL := uploadURL + "api/v3/" + formattedUploadURL := uploadURL + "api/uploads/" c, err := NewEnterpriseClient(baseURL, uploadURL, nil) if err != nil { @@ -240,7 +240,7 @@ func TestNewEnterpriseClient_addsEnterpriseSuffixAndTrailingSlashToURLs(t *testi baseURL := "https://custom-url" uploadURL := "https://custom-upload-url" formattedBaseURL := baseURL + "/api/v3/" - formattedUploadURL := uploadURL + "/api/v3/" + formattedUploadURL := uploadURL + "/api/uploads/" c, err := NewEnterpriseClient(baseURL, uploadURL, nil) if err != nil { From b14be9f9baad9ec41211eb575adc2bd8e222f334 Mon Sep 17 00:00:00 2001 From: Ryan Mast Date: Tue, 28 Apr 2020 16:55:25 -0700 Subject: [PATCH 0175/1468] Add DeleteWorkflowRunLogs function (#1501) Fixes #1500. --- github/actions_workflow_runs.go | 14 ++++++++++++++ github/actions_workflow_runs_test.go | 15 +++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/github/actions_workflow_runs.go b/github/actions_workflow_runs.go index cd8e33fa809..e118cedca9d 100644 --- a/github/actions_workflow_runs.go +++ b/github/actions_workflow_runs.go @@ -179,3 +179,17 @@ func (s *ActionsService) GetWorkflowRunLogs(ctx context.Context, owner, repo str parsedURL, err := url.Parse(resp.Header.Get("Location")) return parsedURL, newResponse(resp), err } + +// DeleteWorkflowRunLogs deletes all logs for a workflow run. +// +// GitHub API docs: https://developer.github.com/v3/actions/workflow-runs/#delete-workflow-run-logs +func (s *ActionsService) DeleteWorkflowRunLogs(ctx context.Context, owner, repo string, runID int64) (*Response, error) { + u := fmt.Sprintf("repos/%v/%v/actions/runs/%v/logs", owner, repo, runID) + + req, err := s.client.NewRequest("DELETE", u, nil) + if err != nil { + return nil, err + } + + return s.client.Do(ctx, req, nil) +} diff --git a/github/actions_workflow_runs_test.go b/github/actions_workflow_runs_test.go index 48e5cc30af3..d233819b7f8 100644 --- a/github/actions_workflow_runs_test.go +++ b/github/actions_workflow_runs_test.go @@ -235,3 +235,18 @@ func TestActionService_ListRepositoryWorkflowRuns(t *testing.T) { } } + +func TestActionService_DeleteWorkflowRunLogs(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/repos/o/r/actions/runs/399444496/logs", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "DELETE") + + w.WriteHeader(http.StatusNoContent) + }) + + if _, err := client.Actions.DeleteWorkflowRunLogs(context.Background(), "o", "r", 399444496); err != nil { + t.Errorf("DeleteWorkflowRunLogs returned error: %v", err) + } +} From bac7f5e246d73e075be6fedbce8476a46973f0e5 Mon Sep 17 00:00:00 2001 From: Vaibhav Date: Mon, 4 May 2020 09:19:28 +0530 Subject: [PATCH 0176/1468] Update permission levels for repositories owned by an organization (#1518) Fixes #1515. --- github/repos_collaborators.go | 2 ++ github/teams.go | 2 ++ 2 files changed, 4 insertions(+) diff --git a/github/repos_collaborators.go b/github/repos_collaborators.go index e461516cae0..65a533083b7 100644 --- a/github/repos_collaborators.go +++ b/github/repos_collaborators.go @@ -115,6 +115,8 @@ type RepositoryAddCollaboratorOptions struct { // pull - team members can pull, but not push to or administer this repository // push - team members can pull and push, but not administer this repository // admin - team members can pull, push and administer this repository + // maintain - team members can manage the repository without access to sensitive or destructive actions. + // triage - team members can proactively manage issues and pull requests without write access. // // Default value is "push". This option is only valid for organization-owned repositories. Permission string `json:"permission,omitempty"` diff --git a/github/teams.go b/github/teams.go index 6eab37fd545..6a2d0318870 100644 --- a/github/teams.go +++ b/github/teams.go @@ -452,6 +452,8 @@ type TeamAddTeamRepoOptions struct { // pull - team members can pull, but not push to or administer this repository // push - team members can pull and push, but not administer this repository // admin - team members can pull, push and administer this repository + // maintain - team members can manage the repository without access to sensitive or destructive actions. + // triage - team members can proactively manage issues and pull requests without write access. // // If not specified, the team's permission attribute will be used. Permission string `json:"permission,omitempty"` From 0498a666dd971823cdee11e147c31c198b31a3f3 Mon Sep 17 00:00:00 2001 From: Joshua Bezaleel Abednego Date: Thu, 7 May 2020 08:22:20 +0700 Subject: [PATCH 0177/1468] Add SuspendInstallation and UnsuspendInstallation for GitHub Apps (#1519) Fixes #1517. --- github/apps.go | 28 ++++++++++++++++++++++++++++ github/apps_test.go | 30 ++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+) diff --git a/github/apps.go b/github/apps.go index c0e8c9a0bfe..ab51c9aeaa5 100644 --- a/github/apps.go +++ b/github/apps.go @@ -211,6 +211,34 @@ func (s *AppsService) ListUserInstallations(ctx context.Context, opts *ListOptio return i.Installations, resp, nil } +// SuspendInstallation suspends the specified installation. +// +// GitHub API docs: https://developer.github.com/v3/apps/#suspend-an-installation +func (s *AppsService) SuspendInstallation(ctx context.Context, id int64) (*Response, error) { + u := fmt.Sprintf("app/installations/%v/suspended", id) + + req, err := s.client.NewRequest("PUT", u, nil) + if err != nil { + return nil, err + } + + return s.client.Do(ctx, req, nil) +} + +// UnsuspendInstallation unsuspends the specified installation. +// +// GitHub API docs: https://developer.github.com/v3/apps/#unsuspend-an-installation +func (s *AppsService) UnsuspendInstallation(ctx context.Context, id int64) (*Response, error) { + u := fmt.Sprintf("app/installations/%v/suspended", id) + + req, err := s.client.NewRequest("DELETE", u, nil) + if err != nil { + return nil, err + } + + return s.client.Do(ctx, req, nil) +} + // CreateInstallationToken creates a new installation token. // // GitHub API docs: https://developer.github.com/v3/apps/#create-a-new-installation-token diff --git a/github/apps_test.go b/github/apps_test.go index 55ef2a095ae..3370caf3e86 100644 --- a/github/apps_test.go +++ b/github/apps_test.go @@ -208,6 +208,36 @@ func TestAppsService_ListUserInstallations(t *testing.T) { } } +func TestAppsService_SuspendInstallation(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/app/installations/1/suspended", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "PUT") + + w.WriteHeader(http.StatusNoContent) + }) + + if _, err := client.Apps.SuspendInstallation(context.Background(), 1); err != nil { + t.Errorf("Apps.SuspendInstallation returned error: %v", err) + } +} + +func TestAppsService_UnsuspendInstallation(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/app/installations/1/suspended", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "DELETE") + + w.WriteHeader(http.StatusNoContent) + }) + + if _, err := client.Apps.UnsuspendInstallation(context.Background(), 1); err != nil { + t.Errorf("Apps.UnsuspendInstallation returned error: %v", err) + } +} + func TestAppsService_CreateInstallationToken(t *testing.T) { client, mux, _, teardown := setup() defer teardown() From 85b6463f21f9fae4e388ae8d391fcf14529101ac Mon Sep 17 00:00:00 2001 From: Ryan Mast Date: Wed, 6 May 2020 18:45:28 -0700 Subject: [PATCH 0178/1468] Add DeleteInstallation for GitHub Apps (#1516) Fixes https://github.com/google/go-github/issues/1436. --- github/apps.go | 17 +++++++++++++++++ github/apps_test.go | 16 ++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/github/apps.go b/github/apps.go index ab51c9aeaa5..ffec99d7b51 100644 --- a/github/apps.go +++ b/github/apps.go @@ -239,6 +239,23 @@ func (s *AppsService) UnsuspendInstallation(ctx context.Context, id int64) (*Res return s.client.Do(ctx, req, nil) } +// DeleteInstallation deletes the specified installation. +// +// GitHub API docs: https://developer.github.com/v3/apps/#delete-an-installation +func (s *AppsService) DeleteInstallation(ctx context.Context, id int64) (*Response, error) { + u := fmt.Sprintf("app/installations/%v", id) + + req, err := s.client.NewRequest("DELETE", u, nil) + if err != nil { + return nil, err + } + + // TODO: remove custom Accept header when this API fully launches. + req.Header.Set("Accept", mediaTypeIntegrationPreview) + + return s.client.Do(ctx, req, nil) +} + // CreateInstallationToken creates a new installation token. // // GitHub API docs: https://developer.github.com/v3/apps/#create-a-new-installation-token diff --git a/github/apps_test.go b/github/apps_test.go index 3370caf3e86..e80a2986f6a 100644 --- a/github/apps_test.go +++ b/github/apps_test.go @@ -238,6 +238,22 @@ func TestAppsService_UnsuspendInstallation(t *testing.T) { } } +func TestAppsService_DeleteInstallation(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/app/installations/1", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "DELETE") + w.WriteHeader(http.StatusNoContent) + testHeader(t, r, "Accept", mediaTypeIntegrationPreview) + }) + + _, err := client.Apps.DeleteInstallation(context.Background(), 1) + if err != nil { + t.Errorf("Apps.DeleteInstallation returned error: %v", err) + } +} + func TestAppsService_CreateInstallationToken(t *testing.T) { client, mux, _, teardown := setup() defer teardown() From da2666cfac55334bc3ad33e86d541268fde352c5 Mon Sep 17 00:00:00 2001 From: Billy Keyes Date: Wed, 6 May 2020 19:14:22 -0700 Subject: [PATCH 0179/1468] Use new endpoints to get and list references (#1513) Fixes #1512. --- github/git_refs.go | 85 ++++-------------------- github/git_refs_test.go | 141 ++++++++++++++++------------------------ update-urls/main.go | 3 - 3 files changed, 71 insertions(+), 158 deletions(-) diff --git a/github/git_refs.go b/github/git_refs.go index a6269e5a9e4..94053aaea1c 100644 --- a/github/git_refs.go +++ b/github/git_refs.go @@ -7,8 +7,6 @@ package github import ( "context" - "encoding/json" - "errors" "fmt" "net/url" "strings" @@ -49,16 +47,12 @@ type updateRefRequest struct { Force *bool `json:"force"` } -// GetRef fetches a single Reference object for a given Git ref. -// If there is no exact match, GetRef will return an error. +// GetRef fetches a single reference in a repository. // -// Note: The GitHub API can return multiple matches. -// If you wish to use this functionality please use the GetRefs() method. -// -// GitHub API docs: https://developer.github.com/v3/git/refs/#get-a-reference +// GitHub API docs: https://developer.github.com/v3/git/refs/#get-a-single-reference func (s *GitService) GetRef(ctx context.Context, owner string, repo string, ref string) (*Reference, *Response, error) { ref = strings.TrimPrefix(ref, "refs/") - u := fmt.Sprintf("repos/%v/%v/git/refs/%v", owner, repo, refURLEscape(ref)) + u := fmt.Sprintf("repos/%v/%v/git/ref/%v", owner, repo, refURLEscape(ref)) req, err := s.client.NewRequest("GET", u, nil) if err != nil { return nil, nil, err @@ -66,13 +60,7 @@ func (s *GitService) GetRef(ctx context.Context, owner string, repo string, ref r := new(Reference) resp, err := s.client.Do(ctx, req, r) - if _, ok := err.(*json.UnmarshalTypeError); ok { - // Multiple refs, means there wasn't an exact match. - return nil, resp, errors.New("multiple matches found for this ref") - } else if _, ok := err.(*ErrorResponse); ok && resp.StatusCode == 404 { - // No ref, there was no match for the ref - return nil, resp, errors.New("no match found for this ref") - } else if err != nil { + if err != nil { return nil, resp, err } @@ -89,69 +77,24 @@ func refURLEscape(ref string) string { return strings.Join(parts, "/") } -// GetRefs fetches a slice of Reference objects for a given Git ref. -// If there is an exact match, only that ref is returned. -// If there is no exact match, GitHub returns all refs that start with ref. -// If returned error is nil, there will be at least 1 ref returned. -// For example: -// -// "heads/featureA" -> ["refs/heads/featureA"] // Exact match, single ref is returned. -// "heads/feature" -> ["refs/heads/featureA", "refs/heads/featureB"] // All refs that start with ref. -// "heads/notexist" -> [] // Returns an error. -// -// GitHub API docs: https://developer.github.com/v3/git/refs/#get-a-reference -func (s *GitService) GetRefs(ctx context.Context, owner string, repo string, ref string) ([]*Reference, *Response, error) { - ref = strings.TrimPrefix(ref, "refs/") - u := fmt.Sprintf("repos/%v/%v/git/refs/%v", owner, repo, refURLEscape(ref)) - req, err := s.client.NewRequest("GET", u, nil) - if err != nil { - return nil, nil, err - } - - var rawJSON json.RawMessage - resp, err := s.client.Do(ctx, req, &rawJSON) - if err != nil { - return nil, resp, err - } - - // Prioritize the most common case: a single returned ref. - r := new(Reference) - singleUnmarshalError := json.Unmarshal(rawJSON, r) - if singleUnmarshalError == nil { - return []*Reference{r}, resp, nil - } - - // Attempt to unmarshal multiple refs. - var rs []*Reference - multipleUnmarshalError := json.Unmarshal(rawJSON, &rs) - if multipleUnmarshalError == nil { - if len(rs) == 0 { - return nil, resp, fmt.Errorf("unexpected response from GitHub API: an array of refs with length 0") - } - return rs, resp, nil - } - - return nil, resp, fmt.Errorf("unmarshalling failed for both single and multiple refs: %s and %s", singleUnmarshalError, multipleUnmarshalError) -} - // ReferenceListOptions specifies optional parameters to the -// GitService.ListRefs method. +// GitService.ListMatchingRefs method. type ReferenceListOptions struct { - Type string `url:"-"` + Ref string `url:"-"` ListOptions } -// ListRefs lists all refs in a repository. +// ListMatchingRefs lists references in a repository that match a supplied ref. +// Use an empty ref to list all references. // -// GitHub API docs: https://developer.github.com/v3/git/refs/#get-all-references -func (s *GitService) ListRefs(ctx context.Context, owner, repo string, opts *ReferenceListOptions) ([]*Reference, *Response, error) { - var u string - if opts != nil && opts.Type != "" { - u = fmt.Sprintf("repos/%v/%v/git/refs/%v", owner, repo, opts.Type) - } else { - u = fmt.Sprintf("repos/%v/%v/git/refs", owner, repo) +// GitHub API docs: https://developer.github.com/v3/git/refs/#list-matching-references +func (s *GitService) ListMatchingRefs(ctx context.Context, owner, repo string, opts *ReferenceListOptions) ([]*Reference, *Response, error) { + var ref string + if opts != nil { + ref = strings.TrimPrefix(opts.Ref, "refs/") } + u := fmt.Sprintf("repos/%v/%v/git/matching-refs/%v", owner, repo, refURLEscape(ref)) u, err := addOptions(u, opts) if err != nil { return nil, nil, err diff --git a/github/git_refs_test.go b/github/git_refs_test.go index 22dc8eb6247..73c193b20f1 100644 --- a/github/git_refs_test.go +++ b/github/git_refs_test.go @@ -19,7 +19,7 @@ func TestGitService_GetRef_singleRef(t *testing.T) { client, mux, _, teardown := setup() defer teardown() - mux.HandleFunc("/repos/o/r/git/refs/heads/b", func(w http.ResponseWriter, r *http.Request) { + mux.HandleFunc("/repos/o/r/git/ref/heads/b", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") fmt.Fprint(w, ` { @@ -64,75 +64,44 @@ func TestGitService_GetRef_noRefs(t *testing.T) { mux.HandleFunc("/repos/o/r/git/refs/heads/b", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") w.WriteHeader(http.StatusNotFound) - fmt.Fprint(w, "[]") }) - _, _, err := client.Git.GetRef(context.Background(), "o", "r", "refs/heads/b") - want := "no match found for this ref" - if err.Error() != want { - t.Errorf("Git.GetRef returned %+v, want %+v", err, want) + ref, resp, err := client.Git.GetRef(context.Background(), "o", "r", "refs/heads/b") + if err == nil { + t.Errorf("Expected HTTP 404 response") + } + if got, want := resp.Response.StatusCode, http.StatusNotFound; got != want { + t.Errorf("Git.GetRef returned status %d, want %d", got, want) + } + if ref != nil { + t.Errorf("Git.GetRef return %+v, want nil", ref) } } -func TestGitService_GetRef_multipleRefs(t *testing.T) { +func TestGitService_ListMatchingRefs_singleRef(t *testing.T) { client, mux, _, teardown := setup() defer teardown() - mux.HandleFunc("/repos/o/r/git/refs/heads/b", func(w http.ResponseWriter, r *http.Request) { + mux.HandleFunc("/repos/o/r/git/matching-refs/heads/b", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") fmt.Fprint(w, ` [ { - "ref": "refs/heads/booger", - "url": "https://api.github.com/repos/o/r/git/refs/heads/booger", - "object": { - "type": "commit", - "sha": "aa218f56b14c9653891f9e74264a383fa43fefbd", - "url": "https://api.github.com/repos/o/r/git/commits/aa218f56b14c9653891f9e74264a383fa43fefbd" - } - }, - { - "ref": "refs/heads/bandsaw", - "url": "https://api.github.com/repos/o/r/git/refs/heads/bandsaw", + "ref": "refs/heads/b", + "url": "https://api.github.com/repos/o/r/git/refs/heads/b", "object": { "type": "commit", - "sha": "612077ae6dffb4d2fbd8ce0cccaa58893b07b5ac", - "url": "https://api.github.com/repos/o/r/git/commits/612077ae6dffb4d2fbd8ce0cccaa58893b07b5ac" + "sha": "aa218f56b14c9653891f9e74264a383fa43fefbd", + "url": "https://api.github.com/repos/o/r/git/commits/aa218f56b14c9653891f9e74264a383fa43fefbd" } } - ] - `) - }) - - _, _, err := client.Git.GetRef(context.Background(), "o", "r", "refs/heads/b") - want := "multiple matches found for this ref" - if err.Error() != want { - t.Errorf("Git.GetRef returned %+v, want %+v", err, want) - } - -} - -func TestGitService_GetRefs_singleRef(t *testing.T) { - client, mux, _, teardown := setup() - defer teardown() - - mux.HandleFunc("/repos/o/r/git/refs/heads/b", func(w http.ResponseWriter, r *http.Request) { - testMethod(t, r, "GET") - fmt.Fprint(w, ` - { - "ref": "refs/heads/b", - "url": "https://api.github.com/repos/o/r/git/refs/heads/b", - "object": { - "type": "commit", - "sha": "aa218f56b14c9653891f9e74264a383fa43fefbd", - "url": "https://api.github.com/repos/o/r/git/commits/aa218f56b14c9653891f9e74264a383fa43fefbd" - } - }`) + ]`) }) - refs, _, err := client.Git.GetRefs(context.Background(), "o", "r", "refs/heads/b") + opts := &ReferenceListOptions{Ref: "refs/heads/b"} + refs, _, err := client.Git.ListMatchingRefs(context.Background(), "o", "r", opts) if err != nil { - t.Fatalf("Git.GetRefs returned error: %v", err) + t.Fatalf("Git.ListMatchingRefs returned error: %v", err) } ref := refs[0] @@ -146,20 +115,21 @@ func TestGitService_GetRefs_singleRef(t *testing.T) { }, } if !reflect.DeepEqual(ref, want) { - t.Errorf("Git.GetRefs returned %+v, want %+v", ref, want) + t.Errorf("Git.ListMatchingRefs returned %+v, want %+v", ref, want) } // without 'refs/' prefix - if _, _, err := client.Git.GetRefs(context.Background(), "o", "r", "heads/b"); err != nil { - t.Errorf("Git.GetRefs returned error: %v", err) + opts = &ReferenceListOptions{Ref: "heads/b"} + if _, _, err := client.Git.ListMatchingRefs(context.Background(), "o", "r", opts); err != nil { + t.Errorf("Git.ListMatchingRefs returned error: %v", err) } } -func TestGitService_GetRefs_multipleRefs(t *testing.T) { +func TestGitService_ListMatchingRefs_multipleRefs(t *testing.T) { client, mux, _, teardown := setup() defer teardown() - mux.HandleFunc("/repos/o/r/git/refs/heads/b", func(w http.ResponseWriter, r *http.Request) { + mux.HandleFunc("/repos/o/r/git/matching-refs/heads/b", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") fmt.Fprint(w, ` [ @@ -185,9 +155,10 @@ func TestGitService_GetRefs_multipleRefs(t *testing.T) { `) }) - refs, _, err := client.Git.GetRefs(context.Background(), "o", "r", "refs/heads/b") + opts := &ReferenceListOptions{Ref: "refs/heads/b"} + refs, _, err := client.Git.ListMatchingRefs(context.Background(), "o", "r", opts) if err != nil { - t.Errorf("Git.GetRefs returned error: %v", err) + t.Errorf("Git.ListMatchingRefs returned error: %v", err) } want := &Reference{ @@ -200,33 +171,35 @@ func TestGitService_GetRefs_multipleRefs(t *testing.T) { }, } if !reflect.DeepEqual(refs[0], want) { - t.Errorf("Git.GetRefs returned %+v, want %+v", refs[0], want) + t.Errorf("Git.ListMatchingRefs returned %+v, want %+v", refs[0], want) } } -// TestGitService_GetRefs_noRefs tests for behaviour resulting from an unexpected GH response. This should never actually happen. -func TestGitService_GetRefs_noRefs(t *testing.T) { +func TestGitService_ListMatchingRefs_noRefs(t *testing.T) { client, mux, _, teardown := setup() defer teardown() - mux.HandleFunc("/repos/o/r/git/refs/heads/b", func(w http.ResponseWriter, r *http.Request) { + mux.HandleFunc("/repos/o/r/git/matching-refs/heads/b", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") fmt.Fprint(w, "[]") }) - _, _, err := client.Git.GetRefs(context.Background(), "o", "r", "refs/heads/b") - want := "unexpected response from GitHub API: an array of refs with length 0" - if err.Error() != want { - t.Errorf("Git.GetRefs returned %+v, want %+v", err, want) + opts := &ReferenceListOptions{Ref: "refs/heads/b"} + refs, _, err := client.Git.ListMatchingRefs(context.Background(), "o", "r", opts) + if err != nil { + t.Errorf("Git.ListMatchingRefs returned error: %v", err) } + if len(refs) != 0 { + t.Errorf("Git.ListMatchingRefs returned %+v, want an empty slice", refs) + } } -func TestGitService_ListRefs(t *testing.T) { +func TestGitService_ListMatchingRefs_allRefs(t *testing.T) { client, mux, _, teardown := setup() defer teardown() - mux.HandleFunc("/repos/o/r/git/refs", func(w http.ResponseWriter, r *http.Request) { + mux.HandleFunc("/repos/o/r/git/matching-refs/", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") fmt.Fprint(w, ` [ @@ -234,26 +207,26 @@ func TestGitService_ListRefs(t *testing.T) { "ref": "refs/heads/branchA", "url": "https://api.github.com/repos/o/r/git/refs/heads/branchA", "object": { - "type": "commit", - "sha": "aa218f56b14c9653891f9e74264a383fa43fefbd", - "url": "https://api.github.com/repos/o/r/git/commits/aa218f56b14c9653891f9e74264a383fa43fefbd" + "type": "commit", + "sha": "aa218f56b14c9653891f9e74264a383fa43fefbd", + "url": "https://api.github.com/repos/o/r/git/commits/aa218f56b14c9653891f9e74264a383fa43fefbd" } }, { "ref": "refs/heads/branchB", "url": "https://api.github.com/repos/o/r/git/refs/heads/branchB", "object": { - "type": "commit", - "sha": "aa218f56b14c9653891f9e74264a383fa43fefbd", - "url": "https://api.github.com/repos/o/r/git/commits/aa218f56b14c9653891f9e74264a383fa43fefbd" + "type": "commit", + "sha": "aa218f56b14c9653891f9e74264a383fa43fefbd", + "url": "https://api.github.com/repos/o/r/git/commits/aa218f56b14c9653891f9e74264a383fa43fefbd" } } ]`) }) - refs, _, err := client.Git.ListRefs(context.Background(), "o", "r", nil) + refs, _, err := client.Git.ListMatchingRefs(context.Background(), "o", "r", nil) if err != nil { - t.Errorf("Git.ListRefs returned error: %v", err) + t.Errorf("Git.ListMatchingRefs returned error: %v", err) } want := []*Reference{ @@ -277,29 +250,29 @@ func TestGitService_ListRefs(t *testing.T) { }, } if !reflect.DeepEqual(refs, want) { - t.Errorf("Git.ListRefs returned %+v, want %+v", refs, want) + t.Errorf("Git.ListMatchingRefs returned %+v, want %+v", refs, want) } } -func TestGitService_ListRefs_options(t *testing.T) { +func TestGitService_ListMatchingRefs_options(t *testing.T) { client, mux, _, teardown := setup() defer teardown() - mux.HandleFunc("/repos/o/r/git/refs/t", func(w http.ResponseWriter, r *http.Request) { + mux.HandleFunc("/repos/o/r/git/matching-refs/t", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") testFormValues(t, r, values{"page": "2"}) fmt.Fprint(w, `[{"ref": "r"}]`) }) - opts := &ReferenceListOptions{Type: "t", ListOptions: ListOptions{Page: 2}} - refs, _, err := client.Git.ListRefs(context.Background(), "o", "r", opts) + opts := &ReferenceListOptions{Ref: "t", ListOptions: ListOptions{Page: 2}} + refs, _, err := client.Git.ListMatchingRefs(context.Background(), "o", "r", opts) if err != nil { - t.Errorf("Git.ListRefs returned error: %v", err) + t.Errorf("Git.ListMatchingRefs returned error: %v", err) } want := []*Reference{{Ref: String("r")}} if !reflect.DeepEqual(refs, want) { - t.Errorf("Git.ListRefs returned %+v, want %+v", refs, want) + t.Errorf("Git.ListMatchingRefs returned %+v, want %+v", refs, want) } } @@ -450,7 +423,7 @@ func TestGitService_GetRef_pathEscape(t *testing.T) { client, mux, _, teardown := setup() defer teardown() - mux.HandleFunc("/repos/o/r/git/refs/heads/b", func(w http.ResponseWriter, r *http.Request) { + mux.HandleFunc("/repos/o/r/git/ref/heads/b", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") if strings.Contains(r.URL.RawPath, "%2F") { t.Errorf("RawPath still contains escaped / as %%2F: %v", r.URL.RawPath) diff --git a/update-urls/main.go b/update-urls/main.go index 73c2e9ca3aa..3c07812467d 100644 --- a/update-urls/main.go +++ b/update-urls/main.go @@ -61,9 +61,6 @@ var ( "AppsService.FindRepositoryInstallationByID": true, "AuthorizationsService.CreateImpersonation": true, "AuthorizationsService.DeleteImpersonation": true, - "GitService.GetRef": true, - "GitService.GetRefs": true, - "GitService.ListRefs": true, "MarketplaceService.marketplaceURI": true, "OrganizationsService.GetByID": true, "RepositoriesService.DeletePreReceiveHook": true, From 45c502145579f884f5a107c227333fd25090b7e3 Mon Sep 17 00:00:00 2001 From: Ryan Mast Date: Sun, 10 May 2020 15:20:49 -0700 Subject: [PATCH 0180/1468] Add skipped conclusion to list in check run options (#1522) --- github/checks.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/github/checks.go b/github/checks.go index 8d08cb39fbc..55b69ab7e1d 100644 --- a/github/checks.go +++ b/github/checks.go @@ -143,7 +143,7 @@ type CreateCheckRunOptions struct { DetailsURL *string `json:"details_url,omitempty"` // The URL of the integrator's site that has the full details of the check. (Optional.) ExternalID *string `json:"external_id,omitempty"` // A reference for the run on the integrator's system. (Optional.) Status *string `json:"status,omitempty"` // The current status. Can be one of "queued", "in_progress", or "completed". Default: "queued". (Optional.) - Conclusion *string `json:"conclusion,omitempty"` // Can be one of "success", "failure", "neutral", "cancelled", "timed_out", or "action_required". (Optional. Required if you provide a status of "completed".) + Conclusion *string `json:"conclusion,omitempty"` // Can be one of "success", "failure", "neutral", "cancelled", "skipped", "timed_out", or "action_required". (Optional. Required if you provide a status of "completed".) StartedAt *Timestamp `json:"started_at,omitempty"` // The time that the check run began. (Optional.) CompletedAt *Timestamp `json:"completed_at,omitempty"` // The time the check completed. (Optional. Required if you provide conclusion.) Output *CheckRunOutput `json:"output,omitempty"` // Provide descriptive details about the run. (Optional) @@ -185,7 +185,7 @@ type UpdateCheckRunOptions struct { DetailsURL *string `json:"details_url,omitempty"` // The URL of the integrator's site that has the full details of the check. (Optional.) ExternalID *string `json:"external_id,omitempty"` // A reference for the run on the integrator's system. (Optional.) Status *string `json:"status,omitempty"` // The current status. Can be one of "queued", "in_progress", or "completed". Default: "queued". (Optional.) - Conclusion *string `json:"conclusion,omitempty"` // Can be one of "success", "failure", "neutral", "cancelled", "timed_out", or "action_required". (Optional. Required if you provide a status of "completed".) + Conclusion *string `json:"conclusion,omitempty"` // Can be one of "success", "failure", "neutral", "cancelled", "skipped", "timed_out", or "action_required". (Optional. Required if you provide a status of "completed".) CompletedAt *Timestamp `json:"completed_at,omitempty"` // The time the check completed. (Optional. Required if you provide conclusion.) Output *CheckRunOutput `json:"output,omitempty"` // Provide descriptive details about the run. (Optional) Actions []*CheckRunAction `json:"actions,omitempty"` // Possible further actions the integrator can perform, which a user may trigger. (Optional.) From 439286037023367e76a7b74f0ead311a7ee78e0b Mon Sep 17 00:00:00 2001 From: Joshua Bezaleel Abednego Date: Tue, 19 May 2020 04:32:32 +0700 Subject: [PATCH 0181/1468] Fix error message for the test of GetWorkflowRunByID (#1529) --- github/actions_workflow_runs_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/github/actions_workflow_runs_test.go b/github/actions_workflow_runs_test.go index d233819b7f8..c2e512ebd46 100644 --- a/github/actions_workflow_runs_test.go +++ b/github/actions_workflow_runs_test.go @@ -82,7 +82,7 @@ func TestActionsService_GetWorkflowRunByID(t *testing.T) { runs, _, err := client.Actions.GetWorkflowRunByID(context.Background(), "o", "r", 29679449) if err != nil { - t.Errorf("Actions.ListWorkFlowRunsByFileName returned error: %v", err) + t.Errorf("Actions.GetWorkflowRunByID returned error: %v", err) } want := &WorkflowRun{ From f093974f9ffab9b8dc05dfd58f7dc5e2da49568f Mon Sep 17 00:00:00 2001 From: Michelangelo Morrillo Date: Thu, 21 May 2020 14:03:16 +0200 Subject: [PATCH 0182/1468] Enable BranchRestriction fields to be empty (#1530) --- github/repos.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/github/repos.go b/github/repos.go index 1014d91f44b..b8c8166b509 100644 --- a/github/repos.go +++ b/github/repos.go @@ -864,9 +864,9 @@ type BranchRestrictions struct { // different from the response structure. type BranchRestrictionsRequest struct { // The list of user logins with push access. (Required; use []string{} instead of nil for empty list.) - Users []string `json:"users"` + Users []string `json:"users,omitempty"` // The list of team slugs with push access. (Required; use []string{} instead of nil for empty list.) - Teams []string `json:"teams"` + Teams []string `json:"teams,omitempty"` // The list of app slugs with push access. Apps []string `json:"apps,omitempty"` } From a37dd2dda868c546506a0f99cb04ef3db65cf46f Mon Sep 17 00:00:00 2001 From: Joshua Bezaleel Abednego Date: Fri, 22 May 2020 08:49:04 +0700 Subject: [PATCH 0183/1468] Add support for workflow usage and workflow run usage API endpoints (#1527) Fixes: #1526. --- github/actions_workflow_runs.go | 39 +++++++++++ github/actions_workflow_runs_test.go | 37 +++++++++++ github/actions_workflows.go | 50 +++++++++++++++ github/actions_workflows_test.go | 64 +++++++++++++++++++ github/github-accessors.go | 96 ++++++++++++++++++++++++++++ 5 files changed, 286 insertions(+) diff --git a/github/actions_workflow_runs.go b/github/actions_workflow_runs.go index e118cedca9d..14d6cd34c47 100644 --- a/github/actions_workflow_runs.go +++ b/github/actions_workflow_runs.go @@ -54,6 +54,25 @@ type ListWorkflowRunsOptions struct { ListOptions } +// WorkflowRunUsage represents a usage of a specific workflow run. +type WorkflowRunUsage struct { + Billable *WorkflowRunEnvironment `json:"billable,omitempty"` + RunDurationMS *int64 `json:"run_duration_ms,omitempty"` +} + +// WorkflowRunEnvironment represents different runner environments available for a workflow run. +type WorkflowRunEnvironment struct { + Ubuntu *WorkflowRunBill `json:"UBUNTU,omitempty"` + MacOS *WorkflowRunBill `json:"MACOS,omitempty"` + Windows *WorkflowRunBill `json:"WINDOWS,omitempty"` +} + +// WorkflowRunBill specifies billable time for a specific environment in a workflow run. +type WorkflowRunBill struct { + TotalMS *int64 `json:"total_ms,omitempty"` + Jobs *int `json:"jobs,omitempty"` +} + func (s *ActionsService) listWorkflowRuns(ctx context.Context, endpoint string, opts *ListWorkflowRunsOptions) (*WorkflowRuns, *Response, error) { u, err := addOptions(endpoint, opts) if err != nil { @@ -193,3 +212,23 @@ func (s *ActionsService) DeleteWorkflowRunLogs(ctx context.Context, owner, repo return s.client.Do(ctx, req, nil) } + +// GetWorkflowRunUsageByID gets a specific workflow usage run by run ID in the unit of billable milliseconds. +// +// GitHub API docs: https://developer.github.com/v3/actions/workflow-runs/#get-workflow-run-usage +func (s *ActionsService) GetWorkflowRunUsageByID(ctx context.Context, owner, repo string, runID int64) (*WorkflowRunUsage, *Response, error) { + u := fmt.Sprintf("repos/%v/%v/actions/runs/%v/timing", owner, repo, runID) + + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + + workflowRunUsage := new(WorkflowRunUsage) + resp, err := s.client.Do(ctx, req, workflowRunUsage) + if err != nil { + return nil, resp, err + } + + return workflowRunUsage, resp, nil +} diff --git a/github/actions_workflow_runs_test.go b/github/actions_workflow_runs_test.go index c2e512ebd46..984babd1f7e 100644 --- a/github/actions_workflow_runs_test.go +++ b/github/actions_workflow_runs_test.go @@ -250,3 +250,40 @@ func TestActionService_DeleteWorkflowRunLogs(t *testing.T) { t.Errorf("DeleteWorkflowRunLogs returned error: %v", err) } } + +func TestActionsService_GetWorkflowRunUsageByID(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/repos/o/r/actions/runs/29679449/timing", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + fmt.Fprint(w, `{"billable":{"UBUNTU":{"total_ms":180000,"jobs":1},"MACOS":{"total_ms":240000,"jobs":4},"WINDOWS":{"total_ms":300000,"jobs":2}},"run_duration_ms":500000}`) + }) + + workflowRunUsage, _, err := client.Actions.GetWorkflowRunUsageByID(context.Background(), "o", "r", 29679449) + if err != nil { + t.Errorf("Actions.GetWorkflowRunUsageByID returned error: %v", err) + } + + want := &WorkflowRunUsage{ + Billable: &WorkflowRunEnvironment{ + Ubuntu: &WorkflowRunBill{ + TotalMS: Int64(180000), + Jobs: Int(1), + }, + MacOS: &WorkflowRunBill{ + TotalMS: Int64(240000), + Jobs: Int(4), + }, + Windows: &WorkflowRunBill{ + TotalMS: Int64(300000), + Jobs: Int(2), + }, + }, + RunDurationMS: Int64(500000), + } + + if !reflect.DeepEqual(workflowRunUsage, want) { + t.Errorf("Actions.GetWorkflowRunUsageByID returned %+v, want %+v", workflowRunUsage, want) + } +} diff --git a/github/actions_workflows.go b/github/actions_workflows.go index 9743f5072ba..6dd02feb67d 100644 --- a/github/actions_workflows.go +++ b/github/actions_workflows.go @@ -30,6 +30,23 @@ type Workflows struct { Workflows []*Workflow `json:"workflows,omitempty"` } +// WorkflowUsage represents a usage of a specific workflow. +type WorkflowUsage struct { + Billable *WorkflowEnvironment `json:"billable,omitempty"` +} + +// WorkflowEnvironment represents different runner environments available for a workflow. +type WorkflowEnvironment struct { + Ubuntu *WorkflowBill `json:"UBUNTU,omitempty"` + MacOS *WorkflowBill `json:"MACOS,omitempty"` + Windows *WorkflowBill `json:"WINDOWS,omitempty"` +} + +// WorkflowBill specifies billable time for a specific environment in a workflow. +type WorkflowBill struct { + TotalMS *int64 `json:"total_ms,omitempty"` +} + // ListWorkflows lists all workflows in a repository. // // GitHub API docs: https://developer.github.com/v3/actions/workflows/#list-repository-workflows @@ -86,3 +103,36 @@ func (s *ActionsService) getWorkflow(ctx context.Context, url string) (*Workflow return workflow, resp, nil } + +// GetWorkflowUsageByID gets a specific workflow usage by ID in the unit of billable milliseconds. +// +// GitHub API docs: https://developer.github.com/v3/actions/workflows/#get-workflow-usage +func (s *ActionsService) GetWorkflowUsageByID(ctx context.Context, owner, repo string, workflowID int64) (*WorkflowUsage, *Response, error) { + u := fmt.Sprintf("repos/%v/%v/actions/workflows/%v/timing", owner, repo, workflowID) + + return s.getWorkflowUsage(ctx, u) +} + +// GetWorkflowUsageByFileName gets a specific workflow usage by file name in the unit of billable milliseconds. +// +// GitHub API docs: https://developer.github.com/v3/actions/workflows/#get-workflow-usage +func (s *ActionsService) GetWorkflowUsageByFileName(ctx context.Context, owner, repo, workflowFileName string) (*WorkflowUsage, *Response, error) { + u := fmt.Sprintf("repos/%v/%v/actions/workflows/%v/timing", owner, repo, workflowFileName) + + return s.getWorkflowUsage(ctx, u) +} + +func (s *ActionsService) getWorkflowUsage(ctx context.Context, url string) (*WorkflowUsage, *Response, error) { + req, err := s.client.NewRequest("GET", url, nil) + if err != nil { + return nil, nil, err + } + + workflowUsage := new(WorkflowUsage) + resp, err := s.client.Do(ctx, req, workflowUsage) + if err != nil { + return nil, resp, err + } + + return workflowUsage, resp, nil +} diff --git a/github/actions_workflows_test.go b/github/actions_workflows_test.go index e9448645ecf..39b71491720 100644 --- a/github/actions_workflows_test.go +++ b/github/actions_workflows_test.go @@ -89,3 +89,67 @@ func TestActionsService_GetWorkflowByFileName(t *testing.T) { t.Errorf("Actions.GetWorkflowByFileName returned %+v, want %+v", workflow, want) } } + +func TestActionsService_GetWorkflowUsageByID(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/repos/o/r/actions/workflows/72844/timing", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + fmt.Fprint(w, `{"billable":{"UBUNTU":{"total_ms":180000},"MACOS":{"total_ms":240000},"WINDOWS":{"total_ms":300000}}}`) + }) + + workflowUsage, _, err := client.Actions.GetWorkflowUsageByID(context.Background(), "o", "r", 72844) + if err != nil { + t.Errorf("Actions.GetWorkflowUsageByID returned error: %v", err) + } + + want := &WorkflowUsage{ + Billable: &WorkflowEnvironment{ + Ubuntu: &WorkflowBill{ + TotalMS: Int64(180000), + }, + MacOS: &WorkflowBill{ + TotalMS: Int64(240000), + }, + Windows: &WorkflowBill{ + TotalMS: Int64(300000), + }, + }, + } + if !reflect.DeepEqual(workflowUsage, want) { + t.Errorf("Actions.GetWorkflowUsageByID returned %+v, want %+v", workflowUsage, want) + } +} + +func TestActionsService_GetWorkflowUsageByFileName(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/repos/o/r/actions/workflows/main.yml/timing", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + fmt.Fprint(w, `{"billable":{"UBUNTU":{"total_ms":180000},"MACOS":{"total_ms":240000},"WINDOWS":{"total_ms":300000}}}`) + }) + + workflowUsage, _, err := client.Actions.GetWorkflowUsageByFileName(context.Background(), "o", "r", "main.yml") + if err != nil { + t.Errorf("Actions.GetWorkflowUsageByFileName returned error: %v", err) + } + + want := &WorkflowUsage{ + Billable: &WorkflowEnvironment{ + Ubuntu: &WorkflowBill{ + TotalMS: Int64(180000), + }, + MacOS: &WorkflowBill{ + TotalMS: Int64(240000), + }, + Windows: &WorkflowBill{ + TotalMS: Int64(300000), + }, + }, + } + if !reflect.DeepEqual(workflowUsage, want) { + t.Errorf("Actions.GetWorkflowUsageByFileName returned %+v, want %+v", workflowUsage, want) + } +} diff --git a/github/github-accessors.go b/github/github-accessors.go index 884f1acc6de..a72cfa02dc8 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -14244,6 +14244,38 @@ func (w *Workflow) GetURL() string { return *w.URL } +// GetTotalMS returns the TotalMS field if it's non-nil, zero value otherwise. +func (w *WorkflowBill) GetTotalMS() int64 { + if w == nil || w.TotalMS == nil { + return 0 + } + return *w.TotalMS +} + +// GetMacOS returns the MacOS field. +func (w *WorkflowEnvironment) GetMacOS() *WorkflowBill { + if w == nil { + return nil + } + return w.MacOS +} + +// GetUbuntu returns the Ubuntu field. +func (w *WorkflowEnvironment) GetUbuntu() *WorkflowBill { + if w == nil { + return nil + } + return w.Ubuntu +} + +// GetWindows returns the Windows field. +func (w *WorkflowEnvironment) GetWindows() *WorkflowBill { + if w == nil { + return nil + } + return w.Windows +} + // GetCheckRunURL returns the CheckRunURL field if it's non-nil, zero value otherwise. func (w *WorkflowJob) GetCheckRunURL() string { if w == nil || w.CheckRunURL == nil { @@ -14524,6 +14556,46 @@ func (w *WorkflowRun) GetWorkflowURL() string { return *w.WorkflowURL } +// GetJobs returns the Jobs field if it's non-nil, zero value otherwise. +func (w *WorkflowRunBill) GetJobs() int { + if w == nil || w.Jobs == nil { + return 0 + } + return *w.Jobs +} + +// GetTotalMS returns the TotalMS field if it's non-nil, zero value otherwise. +func (w *WorkflowRunBill) GetTotalMS() int64 { + if w == nil || w.TotalMS == nil { + return 0 + } + return *w.TotalMS +} + +// GetMacOS returns the MacOS field. +func (w *WorkflowRunEnvironment) GetMacOS() *WorkflowRunBill { + if w == nil { + return nil + } + return w.MacOS +} + +// GetUbuntu returns the Ubuntu field. +func (w *WorkflowRunEnvironment) GetUbuntu() *WorkflowRunBill { + if w == nil { + return nil + } + return w.Ubuntu +} + +// GetWindows returns the Windows field. +func (w *WorkflowRunEnvironment) GetWindows() *WorkflowRunBill { + if w == nil { + return nil + } + return w.Windows +} + // GetTotalCount returns the TotalCount field if it's non-nil, zero value otherwise. func (w *WorkflowRuns) GetTotalCount() int { if w == nil || w.TotalCount == nil { @@ -14532,6 +14604,22 @@ func (w *WorkflowRuns) GetTotalCount() int { return *w.TotalCount } +// GetBillable returns the Billable field. +func (w *WorkflowRunUsage) GetBillable() *WorkflowRunEnvironment { + if w == nil { + return nil + } + return w.Billable +} + +// GetRunDurationMS returns the RunDurationMS field if it's non-nil, zero value otherwise. +func (w *WorkflowRunUsage) GetRunDurationMS() int64 { + if w == nil || w.RunDurationMS == nil { + return 0 + } + return *w.RunDurationMS +} + // GetTotalCount returns the TotalCount field if it's non-nil, zero value otherwise. func (w *Workflows) GetTotalCount() int { if w == nil || w.TotalCount == nil { @@ -14539,3 +14627,11 @@ func (w *Workflows) GetTotalCount() int { } return *w.TotalCount } + +// GetBillable returns the Billable field. +func (w *WorkflowUsage) GetBillable() *WorkflowEnvironment { + if w == nil { + return nil + } + return w.Billable +} From 2d9ff911d85584cb789ea8d9d1c736c97eca4035 Mon Sep 17 00:00:00 2001 From: boljen Date: Thu, 28 May 2020 03:49:01 +0200 Subject: [PATCH 0184/1468] Add ListArtifacts to ActionsService (#1538) Fixes: #1537. --- github/actions_artifacts.go | 24 ++++++++++++ github/actions_artifacts_test.go | 64 ++++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+) diff --git a/github/actions_artifacts.go b/github/actions_artifacts.go index 1735849584a..a236253e36d 100644 --- a/github/actions_artifacts.go +++ b/github/actions_artifacts.go @@ -36,6 +36,30 @@ type ArtifactList struct { Artifacts []*Artifact `json:"artifacts,omitempty"` } +// ListArtifacts lists all artifacts that belong to a repository. +// +// GitHub API docs: https://developer.github.com/v3/actions/artifacts/#list-artifacts-for-a-repository +func (s *ActionsService) ListArtifacts(ctx context.Context, owner, repo string, opts *ListOptions) (*ArtifactList, *Response, error) { + u := fmt.Sprintf("repos/%v/%v/actions/artifacts", owner, repo) + u, err := addOptions(u, opts) + if err != nil { + return nil, nil, err + } + + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + + artifactList := new(ArtifactList) + resp, err := s.client.Do(ctx, req, artifactList) + if err != nil { + return nil, resp, err + } + + return artifactList, resp, nil +} + // ListWorkflowRunArtifacts lists all artifacts that belong to a workflow run. // // GitHub API docs: https://developer.github.com/v3/actions/artifacts/#list-workflow-run-artifacts diff --git a/github/actions_artifacts_test.go b/github/actions_artifacts_test.go index 2d478e455a2..bdad8310274 100644 --- a/github/actions_artifacts_test.go +++ b/github/actions_artifacts_test.go @@ -14,6 +14,70 @@ import ( "testing" ) +func TestActionsService_ListArtifacts(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/repos/o/r/actions/artifacts", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + testFormValues(t, r, values{"page": "2"}) + fmt.Fprint(w, + `{ + "total_count":1, + "artifacts":[{"id":1}] + }`, + ) + }) + + opts := &ListOptions{Page: 2} + artifacts, _, err := client.Actions.ListArtifacts(context.Background(), "o", "r", opts) + if err != nil { + t.Errorf("Actions.ListArtifacts returned error: %v", err) + } + + want := &ArtifactList{TotalCount: Int64(1), Artifacts: []*Artifact{{ID: Int64(1)}}} + if !reflect.DeepEqual(artifacts, want) { + t.Errorf("Actions.ListArtifacts returned %+v, want %+v", artifacts, want) + } +} + +func TestActionsService_ListArtifacts_invalidOwner(t *testing.T) { + client, _, _, teardown := setup() + defer teardown() + + _, _, err := client.Actions.ListArtifacts(context.Background(), "%", "r", nil) + testURLParseError(t, err) +} + +func TestActionsService_ListArtifacts_invalidRepo(t *testing.T) { + client, _, _, teardown := setup() + defer teardown() + + _, _, err := client.Actions.ListArtifacts(context.Background(), "o", "%", nil) + testURLParseError(t, err) +} + +func TestActionsService_ListArtifacts_notFound(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/repos/o/r/actions/artifacts", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + w.WriteHeader(http.StatusNotFound) + }) + + artifacts, resp, err := client.Actions.ListArtifacts(context.Background(), "o", "r", nil) + if err == nil { + t.Errorf("Expected HTTP 404 response") + } + if got, want := resp.Response.StatusCode, http.StatusNotFound; got != want { + t.Errorf("Actions.ListArtifacts return status %d, want %d", got, want) + } + if artifacts != nil { + t.Errorf("Actions.ListArtifacts return %+v, want nil", artifacts) + } +} + func TestActionsService_ListWorkflowRunArtifacts(t *testing.T) { client, mux, _, teardown := setup() defer teardown() From 8d28b935a6241b54f572e999ac8bd710417879c2 Mon Sep 17 00:00:00 2001 From: Ryan Mast Date: Wed, 27 May 2020 18:51:02 -0700 Subject: [PATCH 0185/1468] Add organization secret API support (#1535) Fixes: #1525. --- github/actions_secrets.go | 211 +++++++++++++++++++++++++++---- github/actions_secrets_test.go | 220 ++++++++++++++++++++++++++++++--- github/github-accessors.go | 8 ++ 3 files changed, 399 insertions(+), 40 deletions(-) diff --git a/github/actions_secrets.go b/github/actions_secrets.go index 1640b5a02cc..695accfb67b 100644 --- a/github/actions_secrets.go +++ b/github/actions_secrets.go @@ -16,10 +16,10 @@ type PublicKey struct { Key *string `json:"key"` } -// GetPublicKey gets a public key that should be used for secret encryption. +// GetRepoPublicKey gets a public key that should be used for secret encryption. // -// GitHub API docs: https://developer.github.com/v3/actions/secrets/#get-your-public-key -func (s *ActionsService) GetPublicKey(ctx context.Context, owner, repo string) (*PublicKey, *Response, error) { +// GitHub API docs: https://developer.github.com/v3/actions/secrets/#get-a-repository-public-key +func (s *ActionsService) GetRepoPublicKey(ctx context.Context, owner, repo string) (*PublicKey, *Response, error) { u := fmt.Sprintf("repos/%v/%v/actions/secrets/public-key", owner, repo) req, err := s.client.NewRequest("GET", u, nil) if err != nil { @@ -35,11 +35,32 @@ func (s *ActionsService) GetPublicKey(ctx context.Context, owner, repo string) ( return pubKey, resp, nil } +// GetOrgPublicKey gets a public key that should be used for secret encryption. +// +// GitHub API docs: https://developer.github.com/v3/actions/secrets/#get-an-organization-public-key +func (s *ActionsService) GetOrgPublicKey(ctx context.Context, org string) (*PublicKey, *Response, error) { + u := fmt.Sprintf("orgs/%v/actions/secrets/public-key", org) + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + + pubKey := new(PublicKey) + resp, err := s.client.Do(ctx, req, pubKey) + if err != nil { + return nil, resp, err + } + + return pubKey, resp, nil +} + // Secret represents a repository action secret. type Secret struct { - Name string `json:"name"` - CreatedAt Timestamp `json:"created_at"` - UpdatedAt Timestamp `json:"updated_at"` + Name string `json:"name"` + CreatedAt Timestamp `json:"created_at"` + UpdatedAt Timestamp `json:"updated_at"` + Visibility string `json:"visibility,omitempty"` + SelectedRepositoriesURL string `json:"selected_repositories_url,omitempty"` } // Secrets represents one item from the ListSecrets response. @@ -48,12 +69,12 @@ type Secrets struct { Secrets []*Secret `json:"secrets"` } -// ListSecrets lists all secrets available in a repository +// ListRepoSecrets lists all secrets available in a repository // without revealing their encrypted values. // -// GitHub API docs: https://developer.github.com/v3/actions/secrets/#list-secrets-for-a-repository -func (s *ActionsService) ListSecrets(ctx context.Context, owner, repo string, opts *ListOptions) (*Secrets, *Response, error) { - u := fmt.Sprintf("repos/%s/%s/actions/secrets", owner, repo) +// GitHub API docs: https://developer.github.com/v3/actions/secrets/#list-repository-secrets +func (s *ActionsService) ListRepoSecrets(ctx context.Context, owner, repo string, opts *ListOptions) (*Secrets, *Response, error) { + u := fmt.Sprintf("repos/%v/%v/actions/secrets", owner, repo) u, err := addOptions(u, opts) if err != nil { return nil, nil, err @@ -73,10 +94,10 @@ func (s *ActionsService) ListSecrets(ctx context.Context, owner, repo string, op return secrets, resp, nil } -// GetSecret gets a single secret without revealing its encrypted value. +// GetRepoSecret gets a single repository secret without revealing its encrypted value. // -// GitHub API docs: https://developer.github.com/v3/actions/secrets/#get-a-secret -func (s *ActionsService) GetSecret(ctx context.Context, owner, repo, name string) (*Secret, *Response, error) { +// GitHub API docs: https://developer.github.com/v3/actions/secrets/#get-a-repository-secret +func (s *ActionsService) GetRepoSecret(ctx context.Context, owner, repo, name string) (*Secret, *Response, error) { u := fmt.Sprintf("repos/%v/%v/actions/secrets/%v", owner, repo, name) req, err := s.client.NewRequest("GET", u, nil) if err != nil { @@ -92,21 +113,26 @@ func (s *ActionsService) GetSecret(ctx context.Context, owner, repo, name string return secret, resp, nil } +// SelectedRepoIDs are the repository IDs that have access to the secret. +type SelectedRepoIDs []int64 + // EncryptedSecret represents a secret that is encrypted using a public key. // // The value of EncryptedValue must be your secret, encrypted with // LibSodium (see documentation here: https://libsodium.gitbook.io/doc/bindings_for_other_languages) // using the public key retrieved using the GetPublicKey method. type EncryptedSecret struct { - Name string `json:"-"` - KeyID string `json:"key_id"` - EncryptedValue string `json:"encrypted_value"` + Name string `json:"-"` + KeyID string `json:"key_id"` + EncryptedValue string `json:"encrypted_value"` + Visibility string `json:"visibility,omitempty"` + SelectedRepositoryIDs SelectedRepoIDs `json:"selected_repository_ids,omitempty"` } -// CreateOrUpdateSecret creates or updates a secret with an encrypted value. +// CreateOrUpdateRepoSecret creates or updates a repository secret with an encrypted value. // -// GitHub API docs: https://developer.github.com/v3/actions/secrets/#create-or-update-a-secret-for-a-repository -func (s *ActionsService) CreateOrUpdateSecret(ctx context.Context, owner, repo string, eSecret *EncryptedSecret) (*Response, error) { +// GitHub API docs: https://developer.github.com/v3/actions/secrets/#create-or-update-a-repository-secret +func (s *ActionsService) CreateOrUpdateRepoSecret(ctx context.Context, owner, repo string, eSecret *EncryptedSecret) (*Response, error) { u := fmt.Sprintf("repos/%v/%v/actions/secrets/%v", owner, repo, eSecret.Name) req, err := s.client.NewRequest("PUT", u, eSecret) @@ -117,10 +143,10 @@ func (s *ActionsService) CreateOrUpdateSecret(ctx context.Context, owner, repo s return s.client.Do(ctx, req, nil) } -// DeleteSecret deletes a secret in a repository using the secret name. +// DeleteRepoSecret deletes a secret in a repository using the secret name. // -// GitHub API docs: https://developer.github.com/v3/actions/secrets/#delete-a-secret-from-a-repository -func (s *ActionsService) DeleteSecret(ctx context.Context, owner, repo, name string) (*Response, error) { +// GitHub API docs: https://developer.github.com/v3/actions/secrets/#delete-a-repository-secret +func (s *ActionsService) DeleteRepoSecret(ctx context.Context, owner, repo, name string) (*Response, error) { u := fmt.Sprintf("repos/%v/%v/actions/secrets/%v", owner, repo, name) req, err := s.client.NewRequest("DELETE", u, nil) @@ -130,3 +156,144 @@ func (s *ActionsService) DeleteSecret(ctx context.Context, owner, repo, name str return s.client.Do(ctx, req, nil) } + +// ListOrgSecrets lists all secrets available in an organization +// without revealing their encrypted values. +// +// GitHub API docs: https://developer.github.com/v3/actions/secrets/#list-organization-secrets +func (s *ActionsService) ListOrgSecrets(ctx context.Context, org string, opts *ListOptions) (*Secrets, *Response, error) { + u := fmt.Sprintf("orgs/%v/actions/secrets", org) + u, err := addOptions(u, opts) + if err != nil { + return nil, nil, err + } + + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + + secrets := new(Secrets) + resp, err := s.client.Do(ctx, req, &secrets) + if err != nil { + return nil, resp, err + } + + return secrets, resp, nil +} + +// GetOrgSecret gets a single organization secret without revealing its encrypted value. +// +// GitHub API docs: https://developer.github.com/v3/actions/secrets/#get-an-organization-secret +func (s *ActionsService) GetOrgSecret(ctx context.Context, org, name string) (*Secret, *Response, error) { + u := fmt.Sprintf("orgs/%v/actions/secrets/%v", org, name) + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + + secret := new(Secret) + resp, err := s.client.Do(ctx, req, secret) + if err != nil { + return nil, resp, err + } + + return secret, resp, nil +} + +// CreateOrUpdateOrgSecret creates or updates an organization secret with an encrypted value. +// +// GitHub API docs: https://developer.github.com/v3/actions/secrets/#create-or-update-an-organization-secret +func (s *ActionsService) CreateOrUpdateOrgSecret(ctx context.Context, org string, eSecret *EncryptedSecret) (*Response, error) { + u := fmt.Sprintf("orgs/%v/actions/secrets/%v", org, eSecret.Name) + + req, err := s.client.NewRequest("PUT", u, eSecret) + if err != nil { + return nil, err + } + + return s.client.Do(ctx, req, nil) +} + +// SelectedReposList represents the list of repositories selected for an organization secret. +type SelectedReposList struct { + TotalCount *int `json:"total_count,omitempty"` + Repositories []*Repository `json:"repositories,omitempty"` +} + +// ListSelectedReposForOrgSecret lists all repositories that have access to a secret. +// +// GitHub API docs: https://developer.github.com/v3/actions/secrets/#list-selected-repositories-for-an-organization-secret +func (s *ActionsService) ListSelectedReposForOrgSecret(ctx context.Context, org, name string) (*SelectedReposList, *Response, error) { + u := fmt.Sprintf("orgs/%v/actions/secrets/%v/repositories", org, name) + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + + result := new(SelectedReposList) + resp, err := s.client.Do(ctx, req, result) + if err != nil { + return nil, resp, err + } + + return result, resp, nil +} + +// SetSelectedReposForOrgSecret sets the repositories that have access to a secret. +// +// GitHub API docs: https://developer.github.com/v3/actions/secrets/#set-selected-repositories-for-an-organization-secret +func (s *ActionsService) SetSelectedReposForOrgSecret(ctx context.Context, org, name string, ids SelectedRepoIDs) (*Response, error) { + u := fmt.Sprintf("orgs/%v/actions/secrets/%v/repositories", org, name) + + type repoIDs struct { + SelectedIDs SelectedRepoIDs `json:"selected_repository_ids,omitempty"` + } + + req, err := s.client.NewRequest("PUT", u, repoIDs{SelectedIDs: ids}) + if err != nil { + return nil, err + } + + return s.client.Do(ctx, req, nil) +} + +// AddSelectedRepoToOrgSecret adds a repository to an organization secret. +// +// GitHub API docs: https://developer.github.com/v3/actions/secrets/#add-selected-repository-to-an-organization-secret +func (s *ActionsService) AddSelectedRepoToOrgSecret(ctx context.Context, org, name string, repo *Repository) (*Response, error) { + u := fmt.Sprintf("orgs/%v/actions/secrets/%v/repositories/%v", org, name, *repo.ID) + req, err := s.client.NewRequest("PUT", u, nil) + if err != nil { + return nil, err + } + + return s.client.Do(ctx, req, nil) +} + +// RemoveSelectedRepoFromOrgSecret removes a repository from an organization secret. +// +// GitHub API docs: https://developer.github.com/v3/actions/secrets/#remove-selected-repository-from-an-organization-secret +func (s *ActionsService) RemoveSelectedRepoFromOrgSecret(ctx context.Context, org, name string, repo *Repository) (*Response, error) { + u := fmt.Sprintf("orgs/%v/actions/secrets/%v/repositories/%v", org, name, *repo.ID) + req, err := s.client.NewRequest("DELETE", u, nil) + if err != nil { + return nil, err + } + + return s.client.Do(ctx, req, nil) +} + +// DeleteOrgSecret deletes a secret in an organization using the secret name. +// +// GitHub API docs: https://developer.github.com/v3/actions/secrets/#delete-an-organization-secret +func (s *ActionsService) DeleteOrgSecret(ctx context.Context, org, name string) (*Response, error) { + u := fmt.Sprintf("orgs/%v/actions/secrets/%v", org, name) + + req, err := s.client.NewRequest("DELETE", u, nil) + if err != nil { + return nil, err + } + + return s.client.Do(ctx, req, nil) +} diff --git a/github/actions_secrets_test.go b/github/actions_secrets_test.go index 0a17e583512..61f051b5363 100644 --- a/github/actions_secrets_test.go +++ b/github/actions_secrets_test.go @@ -14,7 +14,7 @@ import ( "time" ) -func TestActionsService_GetPublicKey(t *testing.T) { +func TestActionsService_GetRepoPublicKey(t *testing.T) { client, mux, _, teardown := setup() defer teardown() @@ -23,18 +23,18 @@ func TestActionsService_GetPublicKey(t *testing.T) { fmt.Fprint(w, `{"key_id":"1234","key":"2Sg8iYjAxxmI2LvUXpJjkYrMxURPc8r+dB7TJyvv1234"}`) }) - key, _, err := client.Actions.GetPublicKey(context.Background(), "o", "r") + key, _, err := client.Actions.GetRepoPublicKey(context.Background(), "o", "r") if err != nil { - t.Errorf("Actions.GetPublicKey returned error: %v", err) + t.Errorf("Actions.GetRepoPublicKey returned error: %v", err) } want := &PublicKey{KeyID: String("1234"), Key: String("2Sg8iYjAxxmI2LvUXpJjkYrMxURPc8r+dB7TJyvv1234")} if !reflect.DeepEqual(key, want) { - t.Errorf("Actions.GetPublicKey returned %+v, want %+v", key, want) + t.Errorf("Actions.GetRepoPublicKey returned %+v, want %+v", key, want) } } -func TestActionsService_ListSecrets(t *testing.T) { +func TestActionsService_ListRepoSecrets(t *testing.T) { client, mux, _, teardown := setup() defer teardown() @@ -45,9 +45,9 @@ func TestActionsService_ListSecrets(t *testing.T) { }) opts := &ListOptions{Page: 2, PerPage: 2} - secrets, _, err := client.Actions.ListSecrets(context.Background(), "o", "r", opts) + secrets, _, err := client.Actions.ListRepoSecrets(context.Background(), "o", "r", opts) if err != nil { - t.Errorf("Actions.ListSecrets returned error: %v", err) + t.Errorf("Actions.ListRepoSecrets returned error: %v", err) } want := &Secrets{ @@ -58,11 +58,11 @@ func TestActionsService_ListSecrets(t *testing.T) { }, } if !reflect.DeepEqual(secrets, want) { - t.Errorf("Actions.ListSecrets returned %+v, want %+v", secrets, want) + t.Errorf("Actions.ListRepoSecrets returned %+v, want %+v", secrets, want) } } -func TestActionsService_GetSecret(t *testing.T) { +func TestActionsService_GetRepoSecret(t *testing.T) { client, mux, _, teardown := setup() defer teardown() @@ -71,9 +71,9 @@ func TestActionsService_GetSecret(t *testing.T) { fmt.Fprint(w, `{"name":"NAME","created_at":"2019-01-02T15:04:05Z","updated_at":"2020-01-02T15:04:05Z"}`) }) - secret, _, err := client.Actions.GetSecret(context.Background(), "o", "r", "NAME") + secret, _, err := client.Actions.GetRepoSecret(context.Background(), "o", "r", "NAME") if err != nil { - t.Errorf("Actions.GetSecret returned error: %v", err) + t.Errorf("Actions.GetRepoSecret returned error: %v", err) } want := &Secret{ @@ -82,11 +82,11 @@ func TestActionsService_GetSecret(t *testing.T) { UpdatedAt: Timestamp{time.Date(2020, time.January, 02, 15, 04, 05, 0, time.UTC)}, } if !reflect.DeepEqual(secret, want) { - t.Errorf("Actions.GetSecret returned %+v, want %+v", secret, want) + t.Errorf("Actions.GetRepoSecret returned %+v, want %+v", secret, want) } } -func TestActionsService_CreateOrUpdateSecret(t *testing.T) { +func TestActionsService_CreateOrUpdateRepoSecret(t *testing.T) { client, mux, _, teardown := setup() defer teardown() @@ -102,13 +102,13 @@ func TestActionsService_CreateOrUpdateSecret(t *testing.T) { EncryptedValue: "QIv=", KeyID: "1234", } - _, err := client.Actions.CreateOrUpdateSecret(context.Background(), "o", "r", input) + _, err := client.Actions.CreateOrUpdateRepoSecret(context.Background(), "o", "r", input) if err != nil { - t.Errorf("Actions.CreateOrUpdateSecret returned error: %v", err) + t.Errorf("Actions.CreateOrUpdateRepoSecret returned error: %v", err) } } -func TestActionsService_DeleteSecret(t *testing.T) { +func TestActionsService_DeleteRepoSecret(t *testing.T) { client, mux, _, teardown := setup() defer teardown() @@ -116,8 +116,192 @@ func TestActionsService_DeleteSecret(t *testing.T) { testMethod(t, r, "DELETE") }) - _, err := client.Actions.DeleteSecret(context.Background(), "o", "r", "NAME") + _, err := client.Actions.DeleteRepoSecret(context.Background(), "o", "r", "NAME") if err != nil { - t.Errorf("Actions.DeleteSecret returned error: %v", err) + t.Errorf("Actions.DeleteRepoSecret returned error: %v", err) + } +} + +func TestActionsService_GetOrgPublicKey(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/orgs/o/actions/secrets/public-key", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + fmt.Fprint(w, `{"key_id":"012345678","key":"2Sg8iYjAxxmI2LvUXpJjkYrMxURPc8r+dB7TJyvv1234"}`) + }) + + key, _, err := client.Actions.GetOrgPublicKey(context.Background(), "o") + if err != nil { + t.Errorf("Actions.GetOrgPublicKey returned error: %v", err) + } + + want := &PublicKey{KeyID: String("012345678"), Key: String("2Sg8iYjAxxmI2LvUXpJjkYrMxURPc8r+dB7TJyvv1234")} + if !reflect.DeepEqual(key, want) { + t.Errorf("Actions.GetOrgPublicKey returned %+v, want %+v", key, want) + } +} + +func TestActionsService_ListOrgSecrets(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/orgs/o/actions/secrets", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + testFormValues(t, r, values{"per_page": "2", "page": "2"}) + fmt.Fprint(w, `{"total_count":3,"secrets":[{"name":"GIST_ID","created_at":"2019-08-10T14:59:22Z","updated_at":"2020-01-10T14:59:22Z","visibility":"private"},{"name":"DEPLOY_TOKEN","created_at":"2019-08-10T14:59:22Z","updated_at":"2020-01-10T14:59:22Z","visibility":"all"},{"name":"GH_TOKEN","created_at":"2019-08-10T14:59:22Z","updated_at":"2020-01-10T14:59:22Z","visibility":"selected","selected_repositories_url":"https://api.github.com/orgs/octo-org/actions/secrets/SUPER_SECRET/repositories"}]}`) + }) + + opts := &ListOptions{Page: 2, PerPage: 2} + secrets, _, err := client.Actions.ListOrgSecrets(context.Background(), "o", opts) + if err != nil { + t.Errorf("Actions.ListOrgSecrets returned error: %v", err) + } + + want := &Secrets{ + TotalCount: 3, + Secrets: []*Secret{ + {Name: "GIST_ID", CreatedAt: Timestamp{time.Date(2019, time.August, 10, 14, 59, 22, 0, time.UTC)}, UpdatedAt: Timestamp{time.Date(2020, time.January, 10, 14, 59, 22, 0, time.UTC)}, Visibility: "private"}, + {Name: "DEPLOY_TOKEN", CreatedAt: Timestamp{time.Date(2019, time.August, 10, 14, 59, 22, 0, time.UTC)}, UpdatedAt: Timestamp{time.Date(2020, time.January, 10, 14, 59, 22, 0, time.UTC)}, Visibility: "all"}, + {Name: "GH_TOKEN", CreatedAt: Timestamp{time.Date(2019, time.August, 10, 14, 59, 22, 0, time.UTC)}, UpdatedAt: Timestamp{time.Date(2020, time.January, 10, 14, 59, 22, 0, time.UTC)}, Visibility: "selected", SelectedRepositoriesURL: "https://api.github.com/orgs/octo-org/actions/secrets/SUPER_SECRET/repositories"}, + }, + } + if !reflect.DeepEqual(secrets, want) { + t.Errorf("Actions.ListOrgSecrets returned %+v, want %+v", secrets, want) + } +} + +func TestActionsService_GetOrgSecret(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/orgs/o/actions/secrets/NAME", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + fmt.Fprint(w, `{"name":"NAME","created_at":"2019-01-02T15:04:05Z","updated_at":"2020-01-02T15:04:05Z","visibility":"selected","selected_repositories_url":"https://api.github.com/orgs/octo-org/actions/secrets/SUPER_SECRET/repositories"}`) + }) + + secret, _, err := client.Actions.GetOrgSecret(context.Background(), "o", "NAME") + if err != nil { + t.Errorf("Actions.GetOrgSecret returned error: %v", err) + } + + want := &Secret{ + Name: "NAME", + CreatedAt: Timestamp{time.Date(2019, time.January, 02, 15, 04, 05, 0, time.UTC)}, + UpdatedAt: Timestamp{time.Date(2020, time.January, 02, 15, 04, 05, 0, time.UTC)}, + Visibility: "selected", + SelectedRepositoriesURL: "https://api.github.com/orgs/octo-org/actions/secrets/SUPER_SECRET/repositories", + } + if !reflect.DeepEqual(secret, want) { + t.Errorf("Actions.GetOrgSecret returned %+v, want %+v", secret, want) + } +} + +func TestActionsService_CreateOrUpdateOrgSecret(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/orgs/o/actions/secrets/NAME", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "PUT") + testHeader(t, r, "Content-Type", "application/json") + testBody(t, r, `{"key_id":"1234","encrypted_value":"QIv=","visibility":"selected","selected_repository_ids":[1296269,1269280]}`+"\n") + w.WriteHeader(http.StatusCreated) + }) + + input := &EncryptedSecret{ + Name: "NAME", + EncryptedValue: "QIv=", + KeyID: "1234", + Visibility: "selected", + SelectedRepositoryIDs: SelectedRepoIDs{1296269, 1269280}, + } + _, err := client.Actions.CreateOrUpdateOrgSecret(context.Background(), "o", input) + if err != nil { + t.Errorf("Actions.CreateOrUpdateOrgSecret returned error: %v", err) + } +} + +func TestActionsService_ListSelectedReposForOrgSecret(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/orgs/o/actions/secrets/NAME/repositories", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + fmt.Fprintf(w, `{"total_count":1,"repositories":[{"id":1}]}`) + }) + + repos, _, err := client.Actions.ListSelectedReposForOrgSecret(context.Background(), "o", "NAME") + if err != nil { + t.Errorf("Actions.ListSelectedReposForOrgSecret returned error: %v", err) + } + + want := &SelectedReposList{ + TotalCount: Int(1), + Repositories: []*Repository{ + {ID: Int64(1)}, + }, + } + if !reflect.DeepEqual(repos, want) { + t.Errorf("Actions.ListSelectedReposForOrgSecret returned %+v, want %+v", repos, want) + } +} + +func TestActionsService_SetSelectedReposForOrgSecret(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/orgs/o/actions/secrets/NAME/repositories", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "PUT") + testHeader(t, r, "Content-Type", "application/json") + testBody(t, r, `{"selected_repository_ids":[64780797]}`+"\n") + }) + + _, err := client.Actions.SetSelectedReposForOrgSecret(context.Background(), "o", "NAME", SelectedRepoIDs{64780797}) + if err != nil { + t.Errorf("Actions.SetSelectedReposForOrgSecret returned error: %v", err) + } +} + +func TestActionsService_AddSelectedRepoToOrgSecret(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/orgs/o/actions/secrets/NAME/repositories/1234", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "PUT") + }) + + repo := &Repository{ID: Int64(1234)} + _, err := client.Actions.AddSelectedRepoToOrgSecret(context.Background(), "o", "NAME", repo) + if err != nil { + t.Errorf("Actions.AddSelectedRepoToOrgSecret returned error: %v", err) + } +} + +func TestActionsService_RemoveSelectedRepoFromOrgSecret(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/orgs/o/actions/secrets/NAME/repositories/1234", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "DELETE") + }) + + repo := &Repository{ID: Int64(1234)} + _, err := client.Actions.RemoveSelectedRepoFromOrgSecret(context.Background(), "o", "NAME", repo) + if err != nil { + t.Errorf("Actions.RemoveSelectedRepoFromOrgSecret returned error: %v", err) + } +} + +func TestActionsService_DeleteOrgSecret(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/orgs/o/actions/secrets/NAME", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "DELETE") + }) + + _, err := client.Actions.DeleteOrgSecret(context.Background(), "o", "NAME") + if err != nil { + t.Errorf("Actions.DeleteOrgSecret returned error: %v", err) } } diff --git a/github/github-accessors.go b/github/github-accessors.go index a72cfa02dc8..4489e4dcad2 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -11756,6 +11756,14 @@ func (r *RunnerApplicationDownload) GetOS() string { return *r.OS } +// GetTotalCount returns the TotalCount field if it's non-nil, zero value otherwise. +func (s *SelectedReposList) GetTotalCount() int { + if s == nil || s.TotalCount == nil { + return 0 + } + return *s.TotalCount +} + // GetName returns the Name field if it's non-nil, zero value otherwise. func (s *ServiceHook) GetName() string { if s == nil || s.Name == nil { From ec3758e15e32aeda217dbbbae89ff13acdbbed7c Mon Sep 17 00:00:00 2001 From: Glenn Lewis <6598971+gmlewis@users.noreply.github.com> Date: Thu, 28 May 2020 08:15:17 -0400 Subject: [PATCH 0186/1468] Export ArchiveFormat (#1534) Fixes: #1533. --- github/repos_contents.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/github/repos_contents.go b/github/repos_contents.go index 015d9471a5e..02d45a12ce0 100644 --- a/github/repos_contents.go +++ b/github/repos_contents.go @@ -228,15 +228,15 @@ func (s *RepositoriesService) DeleteFile(ctx context.Context, owner, repo, path return deleteResponse, resp, nil } -// archiveFormat is used to define the archive type when calling GetArchiveLink. -type archiveFormat string +// ArchiveFormat is used to define the archive type when calling GetArchiveLink. +type ArchiveFormat string const ( // Tarball specifies an archive in gzipped tar format. - Tarball archiveFormat = "tarball" + Tarball ArchiveFormat = "tarball" // Zipball specifies an archive in zip format. - Zipball archiveFormat = "zipball" + Zipball ArchiveFormat = "zipball" ) // GetArchiveLink returns an URL to download a tarball or zipball archive for a @@ -244,7 +244,7 @@ const ( // or github.Zipball constant. // // GitHub API docs: https://developer.github.com/v3/repos/contents/#get-archive-link -func (s *RepositoriesService) GetArchiveLink(ctx context.Context, owner, repo string, archiveformat archiveFormat, opts *RepositoryContentGetOptions, followRedirects bool) (*url.URL, *Response, error) { +func (s *RepositoriesService) GetArchiveLink(ctx context.Context, owner, repo string, archiveformat ArchiveFormat, opts *RepositoryContentGetOptions, followRedirects bool) (*url.URL, *Response, error) { u := fmt.Sprintf("repos/%s/%s/%s", owner, repo, archiveformat) if opts != nil && opts.Ref != "" { u += fmt.Sprintf("/%s", opts.Ref) From a86f060e61d0ec7318f2a2ce843a7b9dbdbdf615 Mon Sep 17 00:00:00 2001 From: Glenn Lewis <6598971+gmlewis@users.noreply.github.com> Date: Thu, 28 May 2020 08:31:19 -0400 Subject: [PATCH 0187/1468] Prepare for release v32 (#1541) --- README.md | 4 ++-- example/appengine/app.go | 2 +- example/basicauth/main.go | 2 +- example/commitpr/main.go | 2 +- example/migrations/main.go | 2 +- example/newrepo/main.go | 2 +- example/simple/main.go | 2 +- example/topics/main.go | 2 +- github/doc.go | 2 +- github/examples_test.go | 2 +- go.mod | 2 +- test/fields/fields.go | 2 +- test/integration/activity_test.go | 2 +- test/integration/authorizations_test.go | 2 +- test/integration/github_test.go | 2 +- test/integration/repos_test.go | 2 +- test/integration/users_test.go | 2 +- 17 files changed, 18 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 86bafb07151..eca69931bb2 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # go-github # -[![GoDoc](https://img.shields.io/static/v1?label=godoc&message=reference&color=blue)](https://pkg.go.dev/github.com/google/go-github/v31/github) +[![GoDoc](https://img.shields.io/static/v1?label=godoc&message=reference&color=blue)](https://pkg.go.dev/github.com/google/go-github/v32/github) [![Test Status](https://github.com/google/go-github/workflows/tests/badge.svg)](https://github.com/google/go-github/actions?query=workflow%3Atests) [![Test Coverage](https://codecov.io/gh/google/go-github/branch/master/graph/badge.svg)](https://codecov.io/gh/google/go-github) [![Discuss at go-github@googlegroups.com](https://img.shields.io/badge/discuss-go--github%40googlegroups.com-blue.svg)](https://groups.google.com/group/go-github) @@ -21,7 +21,7 @@ If you're interested in using the [GraphQL API v4][], the recommended library is ## Usage ## ```go -import "github.com/google/go-github/v31/github" // with go modules enabled (GO111MODULE=on or outside GOPATH) +import "github.com/google/go-github/v32/github" // with go modules enabled (GO111MODULE=on or outside GOPATH) import "github.com/google/go-github/github" // with go modules disabled ``` diff --git a/example/appengine/app.go b/example/appengine/app.go index 421d313be60..4ff98725bb6 100644 --- a/example/appengine/app.go +++ b/example/appengine/app.go @@ -12,7 +12,7 @@ import ( "net/http" "os" - "github.com/google/go-github/v31/github" + "github.com/google/go-github/v32/github" "golang.org/x/oauth2" "google.golang.org/appengine" "google.golang.org/appengine/log" diff --git a/example/basicauth/main.go b/example/basicauth/main.go index 627491afd15..021c1d20e54 100644 --- a/example/basicauth/main.go +++ b/example/basicauth/main.go @@ -16,7 +16,7 @@ import ( "strings" "syscall" - "github.com/google/go-github/v31/github" + "github.com/google/go-github/v32/github" "golang.org/x/crypto/ssh/terminal" ) diff --git a/example/commitpr/main.go b/example/commitpr/main.go index 2aeb5faadea..2c7ff213d9b 100644 --- a/example/commitpr/main.go +++ b/example/commitpr/main.go @@ -31,7 +31,7 @@ import ( "strings" "time" - "github.com/google/go-github/v31/github" + "github.com/google/go-github/v32/github" "golang.org/x/oauth2" ) diff --git a/example/migrations/main.go b/example/migrations/main.go index 6c36f2efebc..d95cdb2d683 100644 --- a/example/migrations/main.go +++ b/example/migrations/main.go @@ -12,7 +12,7 @@ import ( "context" "fmt" - "github.com/google/go-github/v31/github" + "github.com/google/go-github/v32/github" "golang.org/x/oauth2" ) diff --git a/example/newrepo/main.go b/example/newrepo/main.go index c8b3a4f76ee..1f105334012 100644 --- a/example/newrepo/main.go +++ b/example/newrepo/main.go @@ -16,7 +16,7 @@ import ( "log" "os" - "github.com/google/go-github/v31/github" + "github.com/google/go-github/v32/github" "golang.org/x/oauth2" ) diff --git a/example/simple/main.go b/example/simple/main.go index cec4fb8cd52..1e0fc8ea4e7 100644 --- a/example/simple/main.go +++ b/example/simple/main.go @@ -12,7 +12,7 @@ import ( "context" "fmt" - "github.com/google/go-github/v31/github" + "github.com/google/go-github/v32/github" ) // Fetch all the public organizations' membership of a user. diff --git a/example/topics/main.go b/example/topics/main.go index 41f53c1578d..54741c9fec6 100644 --- a/example/topics/main.go +++ b/example/topics/main.go @@ -12,7 +12,7 @@ import ( "context" "fmt" - "github.com/google/go-github/v31/github" + "github.com/google/go-github/v32/github" ) // Fetch all the public organizations' membership of a user. diff --git a/github/doc.go b/github/doc.go index c2f0b9cd830..d1aa009a1af 100644 --- a/github/doc.go +++ b/github/doc.go @@ -8,7 +8,7 @@ Package github provides a client for using the GitHub API. Usage: - import "github.com/google/go-github/v31/github" // with go modules enabled (GO111MODULE=on or outside GOPATH) + import "github.com/google/go-github/v32/github" // with go modules enabled (GO111MODULE=on or outside GOPATH) import "github.com/google/go-github/github" // with go modules disabled Construct a new GitHub client, then use the various services on the client to diff --git a/github/examples_test.go b/github/examples_test.go index 83b2ade7bfd..0acc0b2be97 100644 --- a/github/examples_test.go +++ b/github/examples_test.go @@ -12,7 +12,7 @@ import ( "fmt" "log" - "github.com/google/go-github/v31/github" + "github.com/google/go-github/v32/github" ) func ExampleClient_Markdown() { diff --git a/go.mod b/go.mod index a3eac102338..a47b74f6912 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module github.com/google/go-github/v31 +module github.com/google/go-github/v32 require ( github.com/golang/protobuf v1.3.2 // indirect diff --git a/test/fields/fields.go b/test/fields/fields.go index c4a6a7dae6a..49bfd823363 100644 --- a/test/fields/fields.go +++ b/test/fields/fields.go @@ -25,7 +25,7 @@ import ( "reflect" "strings" - "github.com/google/go-github/v31/github" + "github.com/google/go-github/v32/github" "golang.org/x/oauth2" ) diff --git a/test/integration/activity_test.go b/test/integration/activity_test.go index d3145c7f084..c4e6b56fda7 100644 --- a/test/integration/activity_test.go +++ b/test/integration/activity_test.go @@ -11,7 +11,7 @@ import ( "context" "testing" - "github.com/google/go-github/v31/github" + "github.com/google/go-github/v32/github" ) const ( diff --git a/test/integration/authorizations_test.go b/test/integration/authorizations_test.go index f244cd44e63..454b256501d 100644 --- a/test/integration/authorizations_test.go +++ b/test/integration/authorizations_test.go @@ -16,7 +16,7 @@ import ( "testing" "time" - "github.com/google/go-github/v31/github" + "github.com/google/go-github/v32/github" ) const msgEnvMissing = "Skipping test because the required environment variable (%v) is not present." diff --git a/test/integration/github_test.go b/test/integration/github_test.go index d54455d42d5..25f333194b1 100644 --- a/test/integration/github_test.go +++ b/test/integration/github_test.go @@ -14,7 +14,7 @@ import ( "net/http" "os" - "github.com/google/go-github/v31/github" + "github.com/google/go-github/v32/github" "golang.org/x/oauth2" ) diff --git a/test/integration/repos_test.go b/test/integration/repos_test.go index 8d452b79bf2..594dbb33aaf 100644 --- a/test/integration/repos_test.go +++ b/test/integration/repos_test.go @@ -15,7 +15,7 @@ import ( "reflect" "testing" - "github.com/google/go-github/v31/github" + "github.com/google/go-github/v32/github" ) func TestRepositories_CRUD(t *testing.T) { diff --git a/test/integration/users_test.go b/test/integration/users_test.go index df834e9999c..05ec2a41aab 100644 --- a/test/integration/users_test.go +++ b/test/integration/users_test.go @@ -13,7 +13,7 @@ import ( "math/rand" "testing" - "github.com/google/go-github/v31/github" + "github.com/google/go-github/v32/github" ) func TestUsers_Get(t *testing.T) { From 407d73650d4bff607beaf8fb7a69eb9e9987af02 Mon Sep 17 00:00:00 2001 From: Anurag Goel <59905+anurag@users.noreply.github.com> Date: Sat, 30 May 2020 02:24:48 -0700 Subject: [PATCH 0188/1468] Handle github_app_authorization webhook (#1544) Fixes: #1543. --- github/messages.go | 1 + github/messages_test.go | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/github/messages.go b/github/messages.go index 759f9e81809..8ae80452184 100644 --- a/github/messages.go +++ b/github/messages.go @@ -50,6 +50,7 @@ var ( "deployment": "DeploymentEvent", "deployment_status": "DeploymentStatusEvent", "fork": "ForkEvent", + "github_app_authorization": "GitHubAppAuthorizationEvent", "gollum": "GollumEvent", "installation": "InstallationEvent", "installation_repositories": "InstallationRepositoriesEvent", diff --git a/github/messages_test.go b/github/messages_test.go index 2dad247399b..e0650048efc 100644 --- a/github/messages_test.go +++ b/github/messages_test.go @@ -219,6 +219,10 @@ func TestParseWebHook(t *testing.T) { payload: &ForkEvent{}, messageType: "fork", }, + { + payload: &GitHubAppAuthorizationEvent{}, + messageType: "github_app_authorization", + }, { payload: &GollumEvent{}, messageType: "gollum", From 2c8de6514410354ad2137e8f129ca672f1caf4af Mon Sep 17 00:00:00 2001 From: Ryan Mast Date: Sun, 31 May 2020 13:04:47 -0700 Subject: [PATCH 0189/1468] Add missing fields to user and org types (#1548) --- github/github-accessors.go | 40 +++++++++++++++++++++++++++++++++ github/github-stringify_test.go | 9 ++++++-- github/orgs.go | 4 ++++ github/orgs_test.go | 8 +++++++ github/users.go | 1 + github/users_test.go | 36 ++++++++++++++++------------- 6 files changed, 80 insertions(+), 18 deletions(-) diff --git a/github/github-accessors.go b/github/github-accessors.go index 4489e4dcad2..a344a557f06 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -6692,6 +6692,22 @@ func (o *Organization) GetFollowing() int { return *o.Following } +// GetHasOrganizationProjects returns the HasOrganizationProjects field if it's non-nil, zero value otherwise. +func (o *Organization) GetHasOrganizationProjects() bool { + if o == nil || o.HasOrganizationProjects == nil { + return false + } + return *o.HasOrganizationProjects +} + +// GetHasRepositoryProjects returns the HasRepositoryProjects field if it's non-nil, zero value otherwise. +func (o *Organization) GetHasRepositoryProjects() bool { + if o == nil || o.HasRepositoryProjects == nil { + return false + } + return *o.HasRepositoryProjects +} + // GetHooksURL returns the HooksURL field if it's non-nil, zero value otherwise. func (o *Organization) GetHooksURL() string { if o == nil || o.HooksURL == nil { @@ -6724,6 +6740,14 @@ func (o *Organization) GetIssuesURL() string { return *o.IssuesURL } +// GetIsVerified returns the IsVerified field if it's non-nil, zero value otherwise. +func (o *Organization) GetIsVerified() bool { + if o == nil || o.IsVerified == nil { + return false + } + return *o.IsVerified +} + // GetLocation returns the Location field if it's non-nil, zero value otherwise. func (o *Organization) GetLocation() string { if o == nil || o.Location == nil { @@ -6868,6 +6892,14 @@ func (o *Organization) GetTotalPrivateRepos() int { return *o.TotalPrivateRepos } +// GetTwitterUsername returns the TwitterUsername field if it's non-nil, zero value otherwise. +func (o *Organization) GetTwitterUsername() string { + if o == nil || o.TwitterUsername == nil { + return "" + } + return *o.TwitterUsername +} + // GetTwoFactorRequirementEnabled returns the TwoFactorRequirementEnabled field if it's non-nil, zero value otherwise. func (o *Organization) GetTwoFactorRequirementEnabled() bool { if o == nil || o.TwoFactorRequirementEnabled == nil { @@ -13484,6 +13516,14 @@ func (u *User) GetTotalPrivateRepos() int { return *u.TotalPrivateRepos } +// GetTwitterUsername returns the TwitterUsername field if it's non-nil, zero value otherwise. +func (u *User) GetTwitterUsername() string { + if u == nil || u.TwitterUsername == nil { + return "" + } + return *u.TwitterUsername +} + // GetTwoFactorAuthentication returns the TwoFactorAuthentication field if it's non-nil, zero value otherwise. func (u *User) GetTwoFactorAuthentication() bool { if u == nil || u.TwoFactorAuthentication == nil { diff --git a/github/github-stringify_test.go b/github/github-stringify_test.go index df474203300..96d2baf285b 100644 --- a/github/github-stringify_test.go +++ b/github/github-stringify_test.go @@ -854,6 +854,7 @@ func TestOrganization_String(t *testing.T) { Blog: String(""), Location: String(""), Email: String(""), + TwitterUsername: String(""), Description: String(""), PublicRepos: Int(0), PublicGists: Int(0), @@ -868,6 +869,9 @@ func TestOrganization_String(t *testing.T) { Type: String(""), Plan: &Plan{}, TwoFactorRequirementEnabled: Bool(false), + IsVerified: Bool(false), + HasOrganizationProjects: Bool(false), + HasRepositoryProjects: Bool(false), DefaultRepoPermission: String(""), DefaultRepoSettings: String(""), MembersCanCreateRepos: Bool(false), @@ -883,7 +887,7 @@ func TestOrganization_String(t *testing.T) { PublicMembersURL: String(""), ReposURL: String(""), } - want := `github.Organization{Login:"", ID:0, NodeID:"", AvatarURL:"", HTMLURL:"", Name:"", Company:"", Blog:"", Location:"", Email:"", Description:"", PublicRepos:0, PublicGists:0, Followers:0, Following:0, TotalPrivateRepos:0, OwnedPrivateRepos:0, PrivateGists:0, DiskUsage:0, Collaborators:0, BillingEmail:"", Type:"", Plan:github.Plan{}, TwoFactorRequirementEnabled:false, DefaultRepoPermission:"", DefaultRepoSettings:"", MembersCanCreateRepos:false, MembersCanCreatePublicRepos:false, MembersCanCreatePrivateRepos:false, MembersCanCreateInternalRepos:false, MembersAllowedRepositoryCreationType:"", URL:"", EventsURL:"", HooksURL:"", IssuesURL:"", MembersURL:"", PublicMembersURL:"", ReposURL:""}` + want := `github.Organization{Login:"", ID:0, NodeID:"", AvatarURL:"", HTMLURL:"", Name:"", Company:"", Blog:"", Location:"", Email:"", TwitterUsername:"", Description:"", PublicRepos:0, PublicGists:0, Followers:0, Following:0, TotalPrivateRepos:0, OwnedPrivateRepos:0, PrivateGists:0, DiskUsage:0, Collaborators:0, BillingEmail:"", Type:"", Plan:github.Plan{}, TwoFactorRequirementEnabled:false, IsVerified:false, HasOrganizationProjects:false, HasRepositoryProjects:false, DefaultRepoPermission:"", DefaultRepoSettings:"", MembersCanCreateRepos:false, MembersCanCreatePublicRepos:false, MembersCanCreatePrivateRepos:false, MembersCanCreateInternalRepos:false, MembersAllowedRepositoryCreationType:"", URL:"", EventsURL:"", HooksURL:"", IssuesURL:"", MembersURL:"", PublicMembersURL:"", ReposURL:""}` if got := v.String(); got != want { t.Errorf("Organization.String = %v, want %v", got, want) } @@ -1555,6 +1559,7 @@ func TestUser_String(t *testing.T) { Email: String(""), Hireable: Bool(false), Bio: String(""), + TwitterUsername: String(""), PublicRepos: Int(0), PublicGists: Int(0), Followers: Int(0), @@ -1583,7 +1588,7 @@ func TestUser_String(t *testing.T) { StarredURL: String(""), SubscriptionsURL: String(""), } - want := `github.User{Login:"", ID:0, NodeID:"", AvatarURL:"", HTMLURL:"", GravatarID:"", Name:"", Company:"", Blog:"", Location:"", Email:"", Hireable:false, Bio:"", PublicRepos:0, PublicGists:0, Followers:0, Following:0, CreatedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, UpdatedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, SuspendedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, Type:"", SiteAdmin:false, TotalPrivateRepos:0, OwnedPrivateRepos:0, PrivateGists:0, DiskUsage:0, Collaborators:0, TwoFactorAuthentication:false, Plan:github.Plan{}, LdapDn:"", URL:"", EventsURL:"", FollowingURL:"", FollowersURL:"", GistsURL:"", OrganizationsURL:"", ReceivedEventsURL:"", ReposURL:"", StarredURL:"", SubscriptionsURL:""}` + want := `github.User{Login:"", ID:0, NodeID:"", AvatarURL:"", HTMLURL:"", GravatarID:"", Name:"", Company:"", Blog:"", Location:"", Email:"", Hireable:false, Bio:"", TwitterUsername:"", PublicRepos:0, PublicGists:0, Followers:0, Following:0, CreatedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, UpdatedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, SuspendedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, Type:"", SiteAdmin:false, TotalPrivateRepos:0, OwnedPrivateRepos:0, PrivateGists:0, DiskUsage:0, Collaborators:0, TwoFactorAuthentication:false, Plan:github.Plan{}, LdapDn:"", URL:"", EventsURL:"", FollowingURL:"", FollowersURL:"", GistsURL:"", OrganizationsURL:"", ReceivedEventsURL:"", ReposURL:"", StarredURL:"", SubscriptionsURL:""}` if got := v.String(); got != want { t.Errorf("User.String = %v, want %v", got, want) } diff --git a/github/orgs.go b/github/orgs.go index 564231bc418..4065b0148d6 100644 --- a/github/orgs.go +++ b/github/orgs.go @@ -29,6 +29,7 @@ type Organization struct { Blog *string `json:"blog,omitempty"` Location *string `json:"location,omitempty"` Email *string `json:"email,omitempty"` + TwitterUsername *string `json:"twitter_username,omitempty"` Description *string `json:"description,omitempty"` PublicRepos *int `json:"public_repos,omitempty"` PublicGists *int `json:"public_gists,omitempty"` @@ -45,6 +46,9 @@ type Organization struct { Type *string `json:"type,omitempty"` Plan *Plan `json:"plan,omitempty"` TwoFactorRequirementEnabled *bool `json:"two_factor_requirement_enabled,omitempty"` + IsVerified *bool `json:"is_verified,omitempty"` + HasOrganizationProjects *bool `json:"has_organization_projects,omitempty"` + HasRepositoryProjects *bool `json:"has_repository_projects,omitempty"` // DefaultRepoPermission can be one of: "read", "write", "admin", or "none". (Default: "read"). // It is only used in OrganizationsService.Edit. diff --git a/github/orgs_test.go b/github/orgs_test.go index cf69453c33f..e60a01f69fd 100644 --- a/github/orgs_test.go +++ b/github/orgs_test.go @@ -22,9 +22,13 @@ func TestOrganization_marshal(t *testing.T) { Blog: String("https://github.com/blog"), Company: String("GitHub"), Email: String("support@github.com"), + TwitterUsername: String("github"), Location: String("San Francisco"), Name: String("github"), Description: String("GitHub, the company."), + IsVerified: Bool(true), + HasOrganizationProjects: Bool(true), + HasRepositoryProjects: Bool(true), DefaultRepoPermission: String("read"), MembersCanCreateRepos: Bool(true), MembersCanCreateInternalRepos: Bool(true), @@ -38,9 +42,13 @@ func TestOrganization_marshal(t *testing.T) { "blog": "https://github.com/blog", "company": "GitHub", "email": "support@github.com", + "twitter_username": "github", "location": "San Francisco", "name": "github", "description": "GitHub, the company.", + "is_verified": true, + "has_organization_projects": true, + "has_repository_projects": true, "default_repository_permission": "read", "members_can_create_repositories": true, "members_can_create_public_repositories": false, diff --git a/github/users.go b/github/users.go index 97747f713c6..1db2d3230f8 100644 --- a/github/users.go +++ b/github/users.go @@ -31,6 +31,7 @@ type User struct { Email *string `json:"email,omitempty"` Hireable *bool `json:"hireable,omitempty"` Bio *string `json:"bio,omitempty"` + TwitterUsername *string `json:"twitter_username,omitempty"` PublicRepos *int `json:"public_repos,omitempty"` PublicGists *int `json:"public_gists,omitempty"` Followers *int `json:"followers,omitempty"` diff --git a/github/users_test.go b/github/users_test.go index d1ce7e39da3..e97e8e1b8aa 100644 --- a/github/users_test.go +++ b/github/users_test.go @@ -18,22 +18,24 @@ func TestUser_marshall(t *testing.T) { testJSONMarshal(t, &User{}, "{}") u := &User{ - Login: String("l"), - ID: Int64(1), - URL: String("u"), - AvatarURL: String("a"), - GravatarID: String("g"), - Name: String("n"), - Company: String("c"), - Blog: String("b"), - Location: String("l"), - Email: String("e"), - Hireable: Bool(true), - PublicRepos: Int(1), - Followers: Int(1), - Following: Int(1), - CreatedAt: &Timestamp{referenceTime}, - SuspendedAt: &Timestamp{referenceTime}, + Login: String("l"), + ID: Int64(1), + URL: String("u"), + AvatarURL: String("a"), + GravatarID: String("g"), + Name: String("n"), + Company: String("c"), + Blog: String("b"), + Location: String("l"), + Email: String("e"), + Hireable: Bool(true), + Bio: String("b"), + TwitterUsername: String("t"), + PublicRepos: Int(1), + Followers: Int(1), + Following: Int(1), + CreatedAt: &Timestamp{referenceTime}, + SuspendedAt: &Timestamp{referenceTime}, } want := `{ "login": "l", @@ -46,6 +48,8 @@ func TestUser_marshall(t *testing.T) { "location": "l", "email": "e", "hireable": true, + "bio": "b", + "twitter_username": "t", "public_repos": 1, "followers": 1, "following": 1, From dbeb049409f0ee601f5bb1d4d33d0df86b64003b Mon Sep 17 00:00:00 2001 From: Alex Unger Date: Sun, 7 Jun 2020 19:01:18 +0200 Subject: [PATCH 0190/1468] Update function name (#1553) --- example/commitpr/main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example/commitpr/main.go b/example/commitpr/main.go index 2c7ff213d9b..13f9dc35311 100644 --- a/example/commitpr/main.go +++ b/example/commitpr/main.go @@ -122,7 +122,7 @@ func getFileContent(fileArg string) (targetName string, b []byte, err error) { return targetName, b, err } -// createCommit creates the commit in the given reference using the given tree. +// pushCommit creates the commit in the given reference using the given tree. func pushCommit(ref *github.Reference, tree *github.Tree) (err error) { // Get the parent commit to attach the commit to. parent, _, err := client.Repositories.GetCommit(ctx, *sourceOwner, *sourceRepo, *ref.Object.SHA) From f9a2213f7b1a1a6f33426e929b7954fa542fe5cd Mon Sep 17 00:00:00 2001 From: Patrick Marabeas Date: Tue, 16 Jun 2020 11:41:25 +1000 Subject: [PATCH 0191/1468] Add missing workflow_id field from workflow run (#1556) --- github/actions_workflow_runs.go | 1 + github/github-accessors.go | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/github/actions_workflow_runs.go b/github/actions_workflow_runs.go index 14d6cd34c47..47305797f12 100644 --- a/github/actions_workflow_runs.go +++ b/github/actions_workflow_runs.go @@ -22,6 +22,7 @@ type WorkflowRun struct { Event *string `json:"event,omitempty"` Status *string `json:"status,omitempty"` Conclusion *string `json:"conclusion,omitempty"` + WorkflowID *int64 `json:"workflow_id,omitempty"` URL *string `json:"url,omitempty"` HTMLURL *string `json:"html_url,omitempty"` PullRequests []*PullRequest `json:"pull_requests,omitempty"` diff --git a/github/github-accessors.go b/github/github-accessors.go index a344a557f06..336beecc7f8 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -14596,6 +14596,14 @@ func (w *WorkflowRun) GetURL() string { return *w.URL } +// GetWorkflowID returns the WorkflowID field if it's non-nil, zero value otherwise. +func (w *WorkflowRun) GetWorkflowID() int64 { + if w == nil || w.WorkflowID == nil { + return 0 + } + return *w.WorkflowID +} + // GetWorkflowURL returns the WorkflowURL field if it's non-nil, zero value otherwise. func (w *WorkflowRun) GetWorkflowURL() string { if w == nil || w.WorkflowURL == nil { From ecafd129f01b50e5699771b7943f5e5ca695021a Mon Sep 17 00:00:00 2001 From: Taketoshi Fujiwara Date: Tue, 16 Jun 2020 21:43:31 +0900 Subject: [PATCH 0192/1468] Swap documentation for commitMessage and commitTitle of func (*PullRequestsService) Merge (#1557) --- github/pulls.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/github/pulls.go b/github/pulls.go index 685493f118a..ad372d453f8 100644 --- a/github/pulls.go +++ b/github/pulls.go @@ -439,7 +439,7 @@ type PullRequestMergeResult struct { // PullRequestOptions lets you define how a pull request will be merged. type PullRequestOptions struct { - CommitTitle string // Extra detail to append to automatic commit message. (Optional.) + CommitTitle string // Title for the automatic commit message. (Optional.) SHA string // SHA that pull request head must match to allow merge. (Optional.) // The merge method to use. Possible values include: "merge", "squash", and "rebase" with the default being merge. (Optional.) @@ -453,10 +453,10 @@ type pullRequestMergeRequest struct { SHA string `json:"sha,omitempty"` } -// Merge a pull request (Merge Button™). -// commitMessage is the title for the automatic commit message. +// Merge a pull request. +// commitMessage is an extra detail to append to automatic commit message. // -// GitHub API docs: https://developer.github.com/v3/pulls/#merge-a-pull-request-merge-button +// GitHub API docs: https://developer.github.com/v3/pulls/#merge-a-pull-request func (s *PullRequestsService) Merge(ctx context.Context, owner string, repo string, number int, commitMessage string, options *PullRequestOptions) (*PullRequestMergeResult, *Response, error) { u := fmt.Sprintf("repos/%v/%v/pulls/%d/merge", owner, repo, number) From 33126621c3e84fdea9931067bfa75c8df82e7284 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pablo=20P=C3=A9rez=20Schr=C3=B6der?= Date: Wed, 17 Jun 2020 03:11:25 +0200 Subject: [PATCH 0193/1468] Add DeleteDeployment for Repositories (#1555) Fixes: #1554. --- github/repos_deployments.go | 12 ++++++++++++ github/repos_deployments_test.go | 26 ++++++++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/github/repos_deployments.go b/github/repos_deployments.go index 57de0a22692..3caa9730e8a 100644 --- a/github/repos_deployments.go +++ b/github/repos_deployments.go @@ -129,6 +129,18 @@ func (s *RepositoriesService) CreateDeployment(ctx context.Context, owner, repo return d, resp, nil } +// DeleteDeployment deletes an existing deployment for a repository. +// +// GitHub API docs: https://developer.github.com/v3/repos/deployments/#delete-a-deployment +func (s *RepositoriesService) DeleteDeployment(ctx context.Context, owner, repo string, deploymentID int64) (*Response, error) { + u := fmt.Sprintf("repos/%v/%v/deployments/%v", owner, repo, deploymentID) + req, err := s.client.NewRequest("DELETE", u, nil) + if err != nil { + return nil, err + } + return s.client.Do(ctx, req, nil) +} + // DeploymentStatus represents the status of a // particular deployment. type DeploymentStatus struct { diff --git a/github/repos_deployments_test.go b/github/repos_deployments_test.go index fdbfdd3a9f8..53f8cec56b9 100644 --- a/github/repos_deployments_test.go +++ b/github/repos_deployments_test.go @@ -89,6 +89,32 @@ func TestRepositoriesService_CreateDeployment(t *testing.T) { } } +func TestRepositoriesService_DeleteDeployment(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/repos/o/r/deployments/1", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "DELETE") + w.WriteHeader(http.StatusNoContent) + }) + + resp, err := client.Repositories.DeleteDeployment(context.Background(), "o", "r", 1) + if err != nil { + t.Errorf("Repositories.DeleteDeployment returned error: %v", err) + } + if resp.StatusCode != http.StatusNoContent { + t.Error("Repositories.DeleteDeployment should return a 204 status") + } + + resp, err = client.Repositories.DeleteDeployment(context.Background(), "o", "r", 2) + if err == nil { + t.Error("Repositories.DeleteDeployment should return an error") + } + if resp.StatusCode != http.StatusNotFound { + t.Error("Repositories.DeleteDeployment should return a 404 status") + } +} + func TestRepositoriesService_ListDeploymentStatuses(t *testing.T) { client, mux, _, teardown := setup() defer teardown() From 57406a8410f5aeeac948cc4ee01b964c966774ea Mon Sep 17 00:00:00 2001 From: Theo Henson Date: Tue, 16 Jun 2020 21:12:46 -0400 Subject: [PATCH 0194/1468] Add tokenauth example (#1551) --- example/basicauth/main.go | 6 ++++++ example/tokenauth/main.go | 40 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 example/tokenauth/main.go diff --git a/example/basicauth/main.go b/example/basicauth/main.go index 021c1d20e54..0bf7e674079 100644 --- a/example/basicauth/main.go +++ b/example/basicauth/main.go @@ -6,6 +6,12 @@ // The basicauth command demonstrates using the github.BasicAuthTransport, // including handling two-factor authentication. This won't currently work for // accounts that use SMS to receive one-time passwords. +// +// Deprecation Notice: GitHub will discontinue password authentication to the API. +// You must now authenticate to the GitHub API with an API token, such as an OAuth access token, +// GitHub App installation access token, or personal access token, depending on what you need to do with the token. +// Password authentication to the API will be removed on November 13, 2020. +// See the tokenauth example for details. package main import ( diff --git a/example/tokenauth/main.go b/example/tokenauth/main.go new file mode 100644 index 00000000000..92280262509 --- /dev/null +++ b/example/tokenauth/main.go @@ -0,0 +1,40 @@ +// Copyright 2020 The go-github AUTHORS. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// The tokenauth command demonstrates using the oauth2.StaticTokenSource. +package main + +import ( + "context" + "fmt" + "syscall" + + "github.com/google/go-github/v32/github" + "golang.org/x/crypto/ssh/terminal" + "golang.org/x/oauth2" +) + +func main() { + fmt.Print("GitHub Token: ") + byteToken, _ := terminal.ReadPassword(int(syscall.Stdin)) + token := string(byteToken) + + ctx := context.Background() + ts := oauth2.StaticTokenSource( + &oauth2.Token{AccessToken: token}, + ) + tc := oauth2.NewClient(ctx, ts) + + client := github.NewClient(tc) + + user, _, err := client.Users.Get(ctx, "") + + if err != nil { + fmt.Printf("\nerror: %v\n", err) + return + } + + fmt.Printf("\n%v\n", github.Stringify(user)) +} From 2fe941a427178144c599fae1edfc954de6214ca9 Mon Sep 17 00:00:00 2001 From: Ryan Mast Date: Tue, 16 Jun 2020 18:20:22 -0700 Subject: [PATCH 0195/1468] Add support for Code Scanning API (#1545) --- github/authorizations.go | 1 + github/code-scanning.go | 117 +++++++++++++++++++++++++ github/code-scanning_test.go | 165 +++++++++++++++++++++++++++++++++++ github/github-accessors.go | 80 +++++++++++++++++ github/github.go | 2 + 5 files changed, 365 insertions(+) create mode 100644 github/code-scanning.go create mode 100644 github/code-scanning_test.go diff --git a/github/authorizations.go b/github/authorizations.go index 7447e2fbf73..ad31ebf2082 100644 --- a/github/authorizations.go +++ b/github/authorizations.go @@ -41,6 +41,7 @@ const ( ScopeReadGPGKey Scope = "read:gpg_key" ScopeWriteGPGKey Scope = "write:gpg_key" ScopeAdminGPGKey Scope = "admin:gpg_key" + ScopeSecurityEvents Scope = "security_events" ) // AuthorizationsService handles communication with the authorization related diff --git a/github/code-scanning.go b/github/code-scanning.go new file mode 100644 index 00000000000..dc57a890250 --- /dev/null +++ b/github/code-scanning.go @@ -0,0 +1,117 @@ +// Copyright 2020 The go-github AUTHORS. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package github + +import ( + "context" + "fmt" + "strconv" + "strings" +) + +// CodeScanningService handles communication with the code scanning related +// methods of the GitHub API. +// +// GitHub API docs: https://developer.github.com/v3/code-scanning/ +type CodeScanningService service + +type Alert struct { + RuleID *string `json:"rule_id,omitempty"` + RuleSeverity *string `json:"rule_severity,omitempty"` + RuleDescription *string `json:"rule_description,omitempty"` + Tool *string `json:"tool,omitempty"` + CreatedAt *Timestamp `json:"created_at,omitempty"` + Open *bool `json:"open,omitempty"` + ClosedBy *User `json:"closed_by,omitempty"` + ClosedAt *Timestamp `json:"closed_at,omitempty"` + URL *string `json:"url,omitempty"` + HTMLURL *string `json:"html_url,omitempty"` +} + +// ID returns the ID associated with an alert. It is the number at the end of the security alert's URL. +func (a *Alert) ID() int64 { + if a == nil { + return 0 + } + + s := a.GetHTMLURL() + + // Check for an ID to parse at the end of the url + if i := strings.LastIndex(s, "/"); i >= 0 { + s = s[i+1:] + } + + // Return the alert ID as a 64-bit integer. Unable to convert or out of range returns 0. + id, err := strconv.ParseInt(s, 10, 64) + if err != nil { + return 0 + } + + return id +} + +// AlertListOptions specifies optional parameters to the CodeScanningService.ListAlerts +// method. +type AlertListOptions struct { + // State of the code scanning alerts to list. Set to closed to list only closed code scanning alerts. Default: open + State string `url:"state,omitempty"` + + // Return code scanning alerts for a specific branch reference. The ref must be formatted as heads/. + Ref string `url:"ref,omitempty"` +} + +// ListAlertsForRepo lists code scanning alerts for a repository. +// +// Lists all open code scanning alerts for the default branch (usually master) and protected branches in a repository. +// You must use an access token with the security_events scope to use this endpoint. GitHub Apps must have the security_events +// read permission to use this endpoint. +// +// GitHub API docs: https://developer.github.com/v3/code-scanning/#list-code-scanning-alerts-for-a-repository +func (s *CodeScanningService) ListAlertsForRepo(ctx context.Context, owner, repo string, opts *AlertListOptions) ([]*Alert, *Response, error) { + u := fmt.Sprintf("repos/%v/%v/code-scanning/alerts", owner, repo) + u, err := addOptions(u, opts) + if err != nil { + return nil, nil, err + } + + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + + var alerts []*Alert + resp, err := s.client.Do(ctx, req, &alerts) + if err != nil { + return nil, resp, err + } + + return alerts, resp, nil +} + +// GetAlert gets a single code scanning alert for a repository. +// +// You must use an access token with the security_events scope to use this endpoint. +// GitHub Apps must have the security_events read permission to use this endpoint. +// +// The security alert_id is the number at the end of the security alert's URL. +// +// GitHub API docs: https://developer.github.com/v3/code-scanning/#get-a-code-scanning-alert +func (s *CodeScanningService) GetAlert(ctx context.Context, owner, repo string, id int64) (*Alert, *Response, error) { + u := fmt.Sprintf("repos/%v/%v/code-scanning/alerts/%v", owner, repo, id) + + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + + a := new(Alert) + resp, err := s.client.Do(ctx, req, a) + if err != nil { + return nil, resp, err + } + + return a, resp, nil +} diff --git a/github/code-scanning_test.go b/github/code-scanning_test.go new file mode 100644 index 00000000000..2e0c2282c45 --- /dev/null +++ b/github/code-scanning_test.go @@ -0,0 +1,165 @@ +// Copyright 2020 The go-github AUTHORS. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package github + +import ( + "context" + "fmt" + "net/http" + "reflect" + "testing" + "time" +) + +func TestActionsService_Alert_ID(t *testing.T) { + // Test: nil Alert ID == 0 + var a *Alert + id := a.ID() + var want int64 + if id != want { + t.Errorf("Alert.ID error returned %+v, want %+v", id, want) + } + + // Test: Valid HTMLURL + a = &Alert{ + HTMLURL: String("https://github.com/o/r/security/code-scanning/88"), + } + id = a.ID() + want = 88 + if !reflect.DeepEqual(id, want) { + t.Errorf("Alert.ID error returned %+v, want %+v", id, want) + } + + // Test: HTMLURL is nil + a = &Alert{} + id = a.ID() + want = 0 + if !reflect.DeepEqual(id, want) { + t.Errorf("Alert.ID error returned %+v, want %+v", id, want) + } + + // Test: ID can't be parsed as an int + a = &Alert{ + HTMLURL: String("https://github.com/o/r/security/code-scanning/bad88"), + } + id = a.ID() + want = 0 + if !reflect.DeepEqual(id, want) { + t.Errorf("Alert.ID error returned %+v, want %+v", id, want) + } +} + +func TestActionsService_ListAlertsForRepo(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/repos/o/r/code-scanning/alerts", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + testFormValues(t, r, values{"state": "open", "ref": "heads/master"}) + fmt.Fprint(w, `[{ + "rule_id":"js/trivial-conditional", + "rule_severity":"warning", + "rule_description":"Useless conditional", + "tool":"CodeQL", + "created_at":"2020-05-06T12:00:00Z", + "open":true, + "closed_by":null, + "closed_at":null, + "url":"https://api.github.com/repos/o/r/code-scanning/alerts/25", + "html_url":"https://github.com/o/r/security/code-scanning/25" + }, + { + "rule_id":"js/useless-expression", + "rule_severity":"warning", + "rule_description":"Expression has no effect", + "tool":"CodeQL", + "created_at":"2020-05-06T12:00:00Z", + "open":true, + "closed_by":null, + "closed_at":null, + "url":"https://api.github.com/repos/o/r/code-scanning/alerts/88", + "html_url":"https://github.com/o/r/security/code-scanning/88" + }]`) + }) + + opts := &AlertListOptions{State: "open", Ref: "heads/master"} + alerts, _, err := client.CodeScanning.ListAlertsForRepo(context.Background(), "o", "r", opts) + if err != nil { + t.Errorf("CodeScanning.ListAlertsForRepo returned error: %v", err) + } + + date := Timestamp{time.Date(2020, time.May, 06, 12, 00, 00, 0, time.UTC)} + want := []*Alert{ + { + RuleID: String("js/trivial-conditional"), + RuleSeverity: String("warning"), + RuleDescription: String("Useless conditional"), + Tool: String("CodeQL"), + CreatedAt: &date, + Open: Bool(true), + ClosedBy: nil, + ClosedAt: nil, + URL: String("https://api.github.com/repos/o/r/code-scanning/alerts/25"), + HTMLURL: String("https://github.com/o/r/security/code-scanning/25"), + }, + { + RuleID: String("js/useless-expression"), + RuleSeverity: String("warning"), + RuleDescription: String("Expression has no effect"), + Tool: String("CodeQL"), + CreatedAt: &date, + Open: Bool(true), + ClosedBy: nil, + ClosedAt: nil, + URL: String("https://api.github.com/repos/o/r/code-scanning/alerts/88"), + HTMLURL: String("https://github.com/o/r/security/code-scanning/88"), + }, + } + if !reflect.DeepEqual(alerts, want) { + t.Errorf("CodeScanning.ListAlertsForRepo returned %+v, want %+v", alerts, want) + } +} + +func TestActionsService_GetAlert(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/repos/o/r/code-scanning/alerts/88", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + fmt.Fprint(w, `{"rule_id":"js/useless-expression", + "rule_severity":"warning", + "rule_description":"Expression has no effect", + "tool":"CodeQL", + "created_at":"2019-01-02T15:04:05Z", + "open":true, + "closed_by":null, + "closed_at":null, + "url":"https://api.github.com/repos/o/r/code-scanning/alerts/88", + "html_url":"https://github.com/o/r/security/code-scanning/88"}`) + }) + + alert, _, err := client.CodeScanning.GetAlert(context.Background(), "o", "r", 88) + if err != nil { + t.Errorf("CodeScanning.GetAlert returned error: %v", err) + } + + date := Timestamp{time.Date(2019, time.January, 02, 15, 04, 05, 0, time.UTC)} + want := &Alert{ + RuleID: String("js/useless-expression"), + RuleSeverity: String("warning"), + RuleDescription: String("Expression has no effect"), + Tool: String("CodeQL"), + CreatedAt: &date, + Open: Bool(true), + ClosedBy: nil, + ClosedAt: nil, + URL: String("https://api.github.com/repos/o/r/code-scanning/alerts/88"), + HTMLURL: String("https://github.com/o/r/security/code-scanning/88"), + } + if !reflect.DeepEqual(alert, want) { + t.Errorf("CodeScanning.GetAlert returned %+v, want %+v", alert, want) + } +} diff --git a/github/github-accessors.go b/github/github-accessors.go index 336beecc7f8..c2a158f1199 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -108,6 +108,86 @@ func (a *AdminStats) GetUsers() *UserStats { return a.Users } +// GetClosedAt returns the ClosedAt field if it's non-nil, zero value otherwise. +func (a *Alert) GetClosedAt() Timestamp { + if a == nil || a.ClosedAt == nil { + return Timestamp{} + } + return *a.ClosedAt +} + +// GetClosedBy returns the ClosedBy field. +func (a *Alert) GetClosedBy() *User { + if a == nil { + return nil + } + return a.ClosedBy +} + +// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise. +func (a *Alert) GetCreatedAt() Timestamp { + if a == nil || a.CreatedAt == nil { + return Timestamp{} + } + return *a.CreatedAt +} + +// GetHTMLURL returns the HTMLURL field if it's non-nil, zero value otherwise. +func (a *Alert) GetHTMLURL() string { + if a == nil || a.HTMLURL == nil { + return "" + } + return *a.HTMLURL +} + +// GetOpen returns the Open field if it's non-nil, zero value otherwise. +func (a *Alert) GetOpen() bool { + if a == nil || a.Open == nil { + return false + } + return *a.Open +} + +// GetRuleDescription returns the RuleDescription field if it's non-nil, zero value otherwise. +func (a *Alert) GetRuleDescription() string { + if a == nil || a.RuleDescription == nil { + return "" + } + return *a.RuleDescription +} + +// GetRuleID returns the RuleID field if it's non-nil, zero value otherwise. +func (a *Alert) GetRuleID() string { + if a == nil || a.RuleID == nil { + return "" + } + return *a.RuleID +} + +// GetRuleSeverity returns the RuleSeverity field if it's non-nil, zero value otherwise. +func (a *Alert) GetRuleSeverity() string { + if a == nil || a.RuleSeverity == nil { + return "" + } + return *a.RuleSeverity +} + +// GetTool returns the Tool field if it's non-nil, zero value otherwise. +func (a *Alert) GetTool() string { + if a == nil || a.Tool == nil { + return "" + } + return *a.Tool +} + +// GetURL returns the URL field if it's non-nil, zero value otherwise. +func (a *Alert) GetURL() string { + if a == nil || a.URL == nil { + return "" + } + return *a.URL +} + // GetVerifiablePasswordAuthentication returns the VerifiablePasswordAuthentication field if it's non-nil, zero value otherwise. func (a *APIMeta) GetVerifiablePasswordAuthentication() bool { if a == nil || a.VerifiablePasswordAuthentication == nil { diff --git a/github/github.go b/github/github.go index 888da212746..d876e98bbd4 100644 --- a/github/github.go +++ b/github/github.go @@ -165,6 +165,7 @@ type Client struct { Apps *AppsService Authorizations *AuthorizationsService Checks *ChecksService + CodeScanning *CodeScanningService Gists *GistsService Git *GitService Gitignores *GitignoresService @@ -271,6 +272,7 @@ func NewClient(httpClient *http.Client) *Client { c.Apps = (*AppsService)(&c.common) c.Authorizations = (*AuthorizationsService)(&c.common) c.Checks = (*ChecksService)(&c.common) + c.CodeScanning = (*CodeScanningService)(&c.common) c.Gists = (*GistsService)(&c.common) c.Git = (*GitService)(&c.common) c.Gitignores = (*GitignoresService)(&c.common) From 4bd210ef693e4ac094514bef5fa911ad9693258a Mon Sep 17 00:00:00 2001 From: Will Norris Date: Fri, 19 Jun 2020 14:35:55 -0700 Subject: [PATCH 0196/1468] remove use of the term 'blacklist' --- github/gen-accessors.go | 20 ++++++++++---------- github/gen-stringify-test.go | 20 ++++++++++---------- update-urls/main.go | 8 ++++---- 3 files changed, 24 insertions(+), 24 deletions(-) diff --git a/github/gen-accessors.go b/github/gen-accessors.go index 4c5e8eec7e7..3a0243f1aba 100644 --- a/github/gen-accessors.go +++ b/github/gen-accessors.go @@ -37,8 +37,8 @@ var ( sourceTmpl = template.Must(template.New("source").Parse(source)) - // blacklistStructMethod lists "struct.method" combos to skip. - blacklistStructMethod = map[string]bool{ + // skipStructMethods lists "struct.method" combos to skip. + skipStructMethods = map[string]bool{ "RepositoryContent.GetContent": true, "Client.GetBaseURL": true, "Client.GetUploadURL": true, @@ -46,8 +46,8 @@ var ( "RateLimitError.GetResponse": true, "AbuseRateLimitError.GetResponse": true, } - // blacklistStruct lists structs to skip. - blacklistStruct = map[string]bool{ + // skipStructs lists structs to skip. + skipStructs = map[string]bool{ "Client": true, } ) @@ -104,9 +104,9 @@ func (t *templateData) processAST(f *ast.File) error { logf("Struct %v is unexported; skipping.", ts.Name) continue } - // Check if the struct is blacklisted. - if blacklistStruct[ts.Name.Name] { - logf("Struct %v is blacklisted; skipping.", ts.Name) + // Check if the struct should be skipped. + if skipStructs[ts.Name.Name] { + logf("Struct %v is in skip list; skipping.", ts.Name) continue } st, ok := ts.Type.(*ast.StructType) @@ -125,9 +125,9 @@ func (t *templateData) processAST(f *ast.File) error { logf("Field %v is unexported; skipping.", fieldName) continue } - // Check if "struct.method" is blacklisted. - if key := fmt.Sprintf("%v.Get%v", ts.Name, fieldName); blacklistStructMethod[key] { - logf("Method %v is blacklisted; skipping.", key) + // Check if "struct.method" should be skipped. + if key := fmt.Sprintf("%v.Get%v", ts.Name, fieldName); skipStructMethods[key] { + logf("Method %v is skip list; skipping.", key) continue } diff --git a/github/gen-stringify-test.go b/github/gen-stringify-test.go index 7803801e632..5474114bf98 100644 --- a/github/gen-stringify-test.go +++ b/github/gen-stringify-test.go @@ -39,10 +39,10 @@ const ( var ( verbose = flag.Bool("v", false, "Print verbose log messages") - // blacklistStructMethod lists "struct.method" combos to skip. - blacklistStructMethod = map[string]bool{} - // blacklistStruct lists structs to skip. - blacklistStruct = map[string]bool{ + // skipStructMethods lists "struct.method" combos to skip. + skipStructMethods = map[string]bool{} + // skipStructs lists structs to skip. + skipStructs = map[string]bool{ "RateLimits": true, } @@ -166,9 +166,9 @@ func (t *templateData) processAST(f *ast.File) error { logf("Struct %v is unexported; skipping.", ts.Name) continue } - // Check if the struct is blacklisted. - if blacklistStruct[ts.Name.Name] { - logf("Struct %v is blacklisted; skipping.", ts.Name) + // Check if the struct should be skipped. + if skipStructs[ts.Name.Name] { + logf("Struct %v is in skip list; skipping.", ts.Name) continue } st, ok := ts.Type.(*ast.StructType) @@ -203,9 +203,9 @@ func (t *templateData) processAST(f *ast.File) error { logf("Field %v is unexported; skipping.", fieldName) continue } - // Check if "struct.method" is blacklisted. - if key := fmt.Sprintf("%v.Get%v", ts.Name, fieldName); blacklistStructMethod[key] { - logf("Method %v is blacklisted; skipping.", key) + // Check if "struct.method" should be skipped. + if key := fmt.Sprintf("%v.Get%v", ts.Name, fieldName); skipStructMethods[key] { + logf("Method %v is in skip list; skipping.", key) continue } diff --git a/update-urls/main.go b/update-urls/main.go index 3c07812467d..5309178f5fa 100644 --- a/update-urls/main.go +++ b/update-urls/main.go @@ -45,9 +45,9 @@ var ( verbose = flag.Bool("v", false, "Print verbose log messages") debugFile = flag.String("d", "", "Debug named file only") - // methodBlacklist holds methods that do not have GitHub v3 API URLs - // or are otherwise problematic in parsing, discovering, and/or fixing. - methodBlacklist = map[string]bool{ + // skipMethods holds methods which are skipped because they do not have GitHub v3 + // API URLs or are otherwise problematic in parsing, discovering, and/or fixing. + skipMethods = map[string]bool{ "ActionsService.DownloadArtifact": true, "AdminService.CreateOrg": true, "AdminService.CreateUser": true, @@ -679,7 +679,7 @@ func processAST(filename string, f *ast.File, services servicesMap, endpoints en } endpointName := decl.Name.Name fullName := fmt.Sprintf("%v.%v", serviceName, endpointName) - if methodBlacklist[fullName] { + if skipMethods[fullName] { logf("skipping %v", fullName) continue } From be9fac62b9268b22ffcf0ea430ddd5736fb499e7 Mon Sep 17 00:00:00 2001 From: Reetuparna Mukherjee Date: Sun, 21 Jun 2020 21:12:40 +0530 Subject: [PATCH 0197/1468] Add link to documentation (#1565) Fixes: #1561. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index eca69931bb2..380b12ad716 100644 --- a/README.md +++ b/README.md @@ -221,7 +221,7 @@ For complete usage of go-github, see the full [package docs][]. [oauth2]: https://github.com/golang/oauth2 [oauth2 docs]: https://godoc.org/golang.org/x/oauth2 [personal API token]: https://github.com/blog/1509-personal-api-tokens -[package docs]: https://godoc.org/github.com/google/go-github/github +[package docs]: https://pkg.go.dev/github.com/google/go-github/v32/github [GraphQL API v4]: https://developer.github.com/v4/ [shurcooL/githubv4]: https://github.com/shurcooL/githubv4 From 6aeb5643c02dce6ae50a9bfad9c3ca215d1ef95d Mon Sep 17 00:00:00 2001 From: Ali Farooq Date: Wed, 24 Jun 2020 19:14:49 -0400 Subject: [PATCH 0198/1468] Fix documentation for addOptions func (#1568) --- github/github.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/github/github.go b/github/github.go index d876e98bbd4..c68a80c7b99 100644 --- a/github/github.go +++ b/github/github.go @@ -231,7 +231,7 @@ type RawOptions struct { Type RawType } -// addOptions adds the parameters in opt as URL query parameters to s. opt +// addOptions adds the parameters in opts as URL query parameters to s. opts // must be a struct whose fields may contain "url" tags. func addOptions(s string, opts interface{}) (string, error) { v := reflect.ValueOf(opts) From 3d244d3d496ecd4a39bece2f8657d4ddf3ccadf4 Mon Sep 17 00:00:00 2001 From: Matt Moore Date: Wed, 24 Jun 2020 16:19:06 -0700 Subject: [PATCH 0199/1468] Add support for multi-line comments (#1566) --- github/github-accessors.go | 32 +++++++++ github/github-stringify_test.go | 12 ++-- github/pulls_reviews.go | 76 +++++++++++++++++++++ github/pulls_reviews_test.go | 117 +++++++++++++++++++++++++++++++- 4 files changed, 232 insertions(+), 5 deletions(-) diff --git a/github/github-accessors.go b/github/github-accessors.go index c2a158f1199..3e2e03400af 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -2972,6 +2972,14 @@ func (d *DraftReviewComment) GetBody() string { return *d.Body } +// GetLine returns the Line field if it's non-nil, zero value otherwise. +func (d *DraftReviewComment) GetLine() int { + if d == nil || d.Line == nil { + return 0 + } + return *d.Line +} + // GetPath returns the Path field if it's non-nil, zero value otherwise. func (d *DraftReviewComment) GetPath() string { if d == nil || d.Path == nil { @@ -2988,6 +2996,30 @@ func (d *DraftReviewComment) GetPosition() int { return *d.Position } +// GetSide returns the Side field if it's non-nil, zero value otherwise. +func (d *DraftReviewComment) GetSide() string { + if d == nil || d.Side == nil { + return "" + } + return *d.Side +} + +// GetStartLine returns the StartLine field if it's non-nil, zero value otherwise. +func (d *DraftReviewComment) GetStartLine() int { + if d == nil || d.StartLine == nil { + return 0 + } + return *d.StartLine +} + +// GetStartSide returns the StartSide field if it's non-nil, zero value otherwise. +func (d *DraftReviewComment) GetStartSide() string { + if d == nil || d.StartSide == nil { + return "" + } + return *d.StartSide +} + // GetAvatarURL returns the AvatarURL field if it's non-nil, zero value otherwise. func (e *Enterprise) GetAvatarURL() string { if e == nil || e.AvatarURL == nil { diff --git a/github/github-stringify_test.go b/github/github-stringify_test.go index 96d2baf285b..0d64461b5e1 100644 --- a/github/github-stringify_test.go +++ b/github/github-stringify_test.go @@ -297,11 +297,15 @@ func TestDiscussionComment_String(t *testing.T) { func TestDraftReviewComment_String(t *testing.T) { v := DraftReviewComment{ - Path: String(""), - Position: Int(0), - Body: String(""), + Path: String(""), + Position: Int(0), + Body: String(""), + StartSide: String(""), + Side: String(""), + StartLine: Int(0), + Line: Int(0), } - want := `github.DraftReviewComment{Path:"", Position:0, Body:""}` + want := `github.DraftReviewComment{Path:"", Position:0, Body:"", StartSide:"", Side:"", StartLine:0, Line:0}` if got := v.String(); got != want { t.Errorf("DraftReviewComment.String = %v, want %v", got, want) } diff --git a/github/pulls_reviews.go b/github/pulls_reviews.go index 5bceb61c4c3..42af0a0b8a3 100644 --- a/github/pulls_reviews.go +++ b/github/pulls_reviews.go @@ -7,10 +7,13 @@ package github import ( "context" + "errors" "fmt" "time" ) +var ErrMixedCommentStyles = errors.New("cannot use both position and side/line form comments") + // PullRequestReview represents a review of a pull request. type PullRequestReview struct { ID *int64 `json:"id,omitempty"` @@ -36,6 +39,12 @@ type DraftReviewComment struct { Path *string `json:"path,omitempty"` Position *int `json:"position,omitempty"` Body *string `json:"body,omitempty"` + + // The new comfort-fade-preview fields + StartSide *string `json:"start_side,omitempty"` + Side *string `json:"side,omitempty"` + StartLine *int `json:"start_line,omitempty"` + Line *int `json:"line,omitempty"` } func (c DraftReviewComment) String() string { @@ -55,6 +64,32 @@ func (r PullRequestReviewRequest) String() string { return Stringify(r) } +func (r PullRequestReviewRequest) isComfortFadePreview() (bool, error) { + var isCF *bool + for _, comment := range r.Comments { + if comment == nil { + continue + } + hasPos := comment.Position != nil + hasComfortFade := (comment.StartSide != nil) || (comment.Side != nil) || + (comment.StartLine != nil) || (comment.Line != nil) + + switch { + case hasPos && hasComfortFade: + return false, ErrMixedCommentStyles + case hasPos && isCF != nil && *isCF: + return false, ErrMixedCommentStyles + case hasComfortFade && isCF != nil && !*isCF: + return false, ErrMixedCommentStyles + } + isCF = &hasComfortFade + } + if isCF != nil { + return *isCF, nil + } + return false, nil +} + // PullRequestReviewDismissalRequest represents a request to dismiss a review. type PullRequestReviewDismissalRequest struct { Message *string `json:"message,omitempty"` @@ -175,6 +210,38 @@ func (s *PullRequestsService) ListReviewComments(ctx context.Context, owner, rep // Read more about it here - https://github.com/google/go-github/issues/540 // // GitHub API docs: https://developer.github.com/v3/pulls/reviews/#create-a-pull-request-review +// +// In order to use multi-line comments, you must use the "comfort fade" preview. +// This replaces the use of the "Position" field in comments with 4 new fields: +// [Start]Side, and [Start]Line. +// These new fields must be used for ALL comments (including single-line), +// with the following restrictions (empirically observed, so subject to change). +// +// For single-line "comfort fade" comments, you must use: +// +// Path: &path, // as before +// Body: &body, // as before +// Side: &"RIGHT" (or "LEFT") +// Line: &123, // NOT THE SAME AS POSITION, this is an actual line number. +// +// If StartSide or StartLine is used with single-line comments, a 422 is returned. +// +// For multi-line "comfort fade" comments, you must use: +// +// Path: &path, // as before +// Body: &body, // as before +// StartSide: &"RIGHT" (or "LEFT") +// Side: &"RIGHT" (or "LEFT") +// StartLine: &120, +// Line: &125, +// +// Suggested edits are made by commenting on the lines to replace, and including the +// suggested edit in a block like this (it may be surrounded in non-suggestion markdown): +// +// ```suggestion +// Use this instead. +// It is waaaaaay better. +// ``` func (s *PullRequestsService) CreateReview(ctx context.Context, owner, repo string, number int, review *PullRequestReviewRequest) (*PullRequestReview, *Response, error) { u := fmt.Sprintf("repos/%v/%v/pulls/%d/reviews", owner, repo, number) @@ -183,6 +250,15 @@ func (s *PullRequestsService) CreateReview(ctx context.Context, owner, repo stri return nil, nil, err } + // Detect which style of review comment is being used. + if isCF, err := review.isComfortFadePreview(); err != nil { + return nil, nil, err + } else if isCF { + // If the review comments are using the comfort fade preview fields, + // then pass the comfort fade header. + req.Header.Set("Accept", mediaTypeMultiLineCommentsPreview) + } + r := new(PullRequestReview) resp, err := s.client.Do(ctx, req, r) if err != nil { diff --git a/github/pulls_reviews_test.go b/github/pulls_reviews_test.go index 25aaca1c013..ae3fb7c57ff 100644 --- a/github/pulls_reviews_test.go +++ b/github/pulls_reviews_test.go @@ -73,7 +73,7 @@ func TestReviewers_marshall(t *testing.T) { "created_at": ` + referenceTimeStr + `, "url": "u" } - ], + ], "teams" : [ { "id": 1, @@ -228,6 +228,121 @@ func TestPullRequestsService_ListReviewComments_withOptions(t *testing.T) { } } +func TestPullRequestReviewRequest_isComfortFadePreview(t *testing.T) { + path := "path/to/file.go" + body := "this is a comment body" + left, right := "LEFT", "RIGHT" + pos1, pos2, pos3 := 1, 2, 3 + line1, line2, line3 := 11, 22, 33 + + tests := []struct { + name string + review *PullRequestReviewRequest + wantErr error + wantBool bool + }{{ + name: "empty review", + review: &PullRequestReviewRequest{}, + wantBool: false, + }, { + name: "old-style review", + review: &PullRequestReviewRequest{ + Comments: []*DraftReviewComment{{ + Path: &path, + Body: &body, + Position: &pos1, + }, { + Path: &path, + Body: &body, + Position: &pos2, + }, { + Path: &path, + Body: &body, + Position: &pos3, + }}, + }, + wantBool: false, + }, { + name: "new-style review", + review: &PullRequestReviewRequest{ + Comments: []*DraftReviewComment{{ + Path: &path, + Body: &body, + Side: &right, + Line: &line1, + }, { + Path: &path, + Body: &body, + Side: &left, + Line: &line2, + }, { + Path: &path, + Body: &body, + Side: &right, + Line: &line3, + }}, + }, + wantBool: true, + }, { + name: "blended comment", + review: &PullRequestReviewRequest{ + Comments: []*DraftReviewComment{{ + Path: &path, + Body: &body, + Position: &pos1, // can't have both styles. + Side: &right, + Line: &line1, + }}, + }, + wantErr: ErrMixedCommentStyles, + }, { + name: "position then line", + review: &PullRequestReviewRequest{ + Comments: []*DraftReviewComment{{ + Path: &path, + Body: &body, + Position: &pos1, + }, { + Path: &path, + Body: &body, + Side: &right, + Line: &line1, + }}, + }, + wantErr: ErrMixedCommentStyles, + }, { + name: "line then position", + review: &PullRequestReviewRequest{ + Comments: []*DraftReviewComment{{ + Path: &path, + Body: &body, + Side: &right, + Line: &line1, + }, { + Path: &path, + Body: &body, + Position: &pos1, + }}, + }, + wantErr: ErrMixedCommentStyles, + }} + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + gotBool, gotErr := tc.review.isComfortFadePreview() + if tc.wantErr != nil { + if gotErr != tc.wantErr { + t.Errorf("isComfortFadePreview() = %v, wanted %v", gotErr, tc.wantErr) + } + } else { + if gotBool != tc.wantBool { + t.Errorf("isComfortFadePreview() = %v, wanted %v", gotBool, tc.wantBool) + } + } + }) + } +} + func TestPullRequestsService_ListReviewComments_invalidOwner(t *testing.T) { client, _, _, teardown := setup() defer teardown() From 0683ca03b4e9f6cfab67a0f95f8c42bcacd57f6c Mon Sep 17 00:00:00 2001 From: Glenn Lewis <6598971+gmlewis@users.noreply.github.com> Date: Wed, 24 Jun 2020 19:27:03 -0400 Subject: [PATCH 0200/1468] Update URLs (#1558) --- github/actions_workflow_jobs.go | 4 +-- github/actions_workflow_runs.go | 4 +-- github/activity_events.go | 2 +- github/apps.go | 24 ++++++------- github/apps_installation.go | 10 +++--- github/gists.go | 2 +- github/gists_comments.go | 10 +++--- github/git_refs.go | 2 +- github/gitignore.go | 2 +- github/interactions_orgs.go | 2 +- github/interactions_repos.go | 2 +- github/issues_assignees.go | 2 +- github/issues_comments.go | 12 +++---- github/issues_events.go | 6 ++-- github/issues_labels.go | 10 +++--- github/issues_milestones.go | 4 +-- github/issues_timeline.go | 2 +- github/licenses.go | 2 +- github/migrations.go | 2 +- github/migrations_source_import.go | 6 ++-- github/migrations_user.go | 2 +- github/orgs.go | 6 ++-- github/orgs_hooks.go | 12 +++---- github/orgs_members.go | 28 ++++++++-------- github/orgs_outside_collaborators.go | 6 ++-- github/orgs_users_blocking.go | 8 ++--- github/projects.go | 8 ++--- github/pulls.go | 8 ++--- github/pulls_comments.go | 14 ++++---- github/pulls_reviewers.go | 6 ++-- github/pulls_reviews.go | 16 ++++----- github/repos.go | 50 ++++++++++++++-------------- github/repos_collaborators.go | 10 +++--- github/repos_comments.go | 4 +-- github/repos_commits.go | 8 ++--- github/repos_community_health.go | 2 +- github/repos_contents.go | 8 ++--- github/repos_deployments.go | 4 +-- github/repos_hooks.go | 14 ++++---- github/repos_invitations.go | 2 +- github/repos_keys.go | 4 +-- github/repos_merging.go | 2 +- github/repos_pages.go | 14 ++++---- github/repos_releases.go | 14 ++++---- github/repos_stats.go | 10 +++--- github/repos_statuses.go | 6 ++-- github/repos_traffic.go | 8 ++--- github/teams.go | 46 ++++++++++++------------- github/teams_discussion_comments.go | 20 +++++------ github/teams_discussions.go | 8 ++--- github/teams_members.go | 12 +++---- github/users.go | 8 ++--- github/users_blocking.go | 4 +-- github/users_emails.go | 6 ++-- github/users_followers.go | 8 ++--- github/users_gpg_keys.go | 6 ++-- github/users_keys.go | 8 ++--- update-urls/main.go | 2 ++ 58 files changed, 257 insertions(+), 255 deletions(-) diff --git a/github/actions_workflow_jobs.go b/github/actions_workflow_jobs.go index 2d7973fbc5d..f1506ffecfd 100644 --- a/github/actions_workflow_jobs.go +++ b/github/actions_workflow_jobs.go @@ -84,7 +84,7 @@ func (s *ActionsService) ListWorkflowJobs(ctx context.Context, owner, repo strin // GetWorkflowJobByID gets a specific job in a workflow run by ID. // -// GitHub API docs: https://developer.github.com/v3/actions/workflow-jobs/#get-a-workflow-job +// GitHub API docs: https://developer.github.com/v3/actions/workflow-jobs/#get-a-job-for-a-workflow-run func (s *ActionsService) GetWorkflowJobByID(ctx context.Context, owner, repo string, jobID int64) (*WorkflowJob, *Response, error) { u := fmt.Sprintf("repos/%v/%v/actions/jobs/%v", owner, repo, jobID) @@ -104,7 +104,7 @@ func (s *ActionsService) GetWorkflowJobByID(ctx context.Context, owner, repo str // GetWorkflowJobLogs gets a redirect URL to download a plain text file of logs for a workflow job. // -// GitHub API docs: https://developer.github.com/v3/actions/workflow-jobs/#list-workflow-job-logs +// GitHub API docs: https://developer.github.com/v3/actions/workflow-jobs/#download-job-logs-for-a-workflow-run func (s *ActionsService) GetWorkflowJobLogs(ctx context.Context, owner, repo string, jobID int64, followRedirects bool) (*url.URL, *Response, error) { u := fmt.Sprintf("repos/%v/%v/actions/jobs/%v/logs", owner, repo, jobID) diff --git a/github/actions_workflow_runs.go b/github/actions_workflow_runs.go index 47305797f12..4213c6b15f0 100644 --- a/github/actions_workflow_runs.go +++ b/github/actions_workflow_runs.go @@ -112,7 +112,7 @@ func (s *ActionsService) ListWorkflowRunsByFileName(ctx context.Context, owner, // ListRepositoryWorkflowRuns lists all workflow runs for a repository. // -// GitHub API docs: https://developer.github.com/v3/actions/workflow-runs/#list-repository-workflow-runs +// GitHub API docs: https://developer.github.com/v3/actions/workflow-runs/#list-workflow-runs-for-a-repository func (s *ActionsService) ListRepositoryWorkflowRuns(ctx context.Context, owner, repo string, opts *ListWorkflowRunsOptions) (*WorkflowRuns, *Response, error) { u := fmt.Sprintf("repos/%s/%s/actions/runs", owner, repo) u, err := addOptions(u, opts) @@ -184,7 +184,7 @@ func (s *ActionsService) CancelWorkflowRunByID(ctx context.Context, owner, repo // GetWorkflowRunLogs gets a redirect URL to download a plain text file of logs for a workflow run. // -// GitHub API docs: https://developer.github.com/v3/actions/workflow-runs/#list-workflow-run-logs +// GitHub API docs: https://developer.github.com/v3/actions/workflow-runs/#download-workflow-run-logs func (s *ActionsService) GetWorkflowRunLogs(ctx context.Context, owner, repo string, runID int64, followRedirects bool) (*url.URL, *Response, error) { u := fmt.Sprintf("repos/%v/%v/actions/runs/%v/logs", owner, repo, runID) diff --git a/github/activity_events.go b/github/activity_events.go index d45b26ddcd8..e795b9f0ae2 100644 --- a/github/activity_events.go +++ b/github/activity_events.go @@ -59,7 +59,7 @@ func (s *ActivityService) ListRepositoryEvents(ctx context.Context, owner, repo // ListIssueEventsForRepository lists issue events for a repository. // -// GitHub API docs: https://developer.github.com/v3/issues/events/#list-events-for-a-repository +// GitHub API docs: https://developer.github.com/v3/issues/events/#list-issue-events-for-a-repository func (s *ActivityService) ListIssueEventsForRepository(ctx context.Context, owner, repo string, opts *ListOptions) ([]*IssueEvent, *Response, error) { u := fmt.Sprintf("repos/%v/%v/issues/events", owner, repo) u, err := addOptions(u, opts) diff --git a/github/apps.go b/github/apps.go index ffec99d7b51..45262c41a0f 100644 --- a/github/apps.go +++ b/github/apps.go @@ -123,8 +123,8 @@ func (i Installation) String() string { // You can find this on the settings page for your GitHub App // (e.g., https://github.com/settings/apps/:app_slug). // -// GitHub API docs: https://developer.github.com/v3/apps/#get-a-single-github-app -// GitHub API docs: https://developer.github.com/v3/apps/#get-the-authenticated-github-app +// GitHub API docs: https://developer.github.com/v3/apps/#get-the-authenticated-app +// GitHub API docs: https://developer.github.com/v3/apps/#get-an-app func (s *AppsService) Get(ctx context.Context, appSlug string) (*App, *Response, error) { var u string if appSlug != "" { @@ -152,7 +152,7 @@ func (s *AppsService) Get(ctx context.Context, appSlug string) (*App, *Response, // ListInstallations lists the installations that the current GitHub App has. // -// GitHub API docs: https://developer.github.com/v3/apps/#list-installations +// GitHub API docs: https://developer.github.com/v3/apps/#list-installations-for-the-authenticated-app func (s *AppsService) ListInstallations(ctx context.Context, opts *ListOptions) ([]*Installation, *Response, error) { u, err := addOptions("app/installations", opts) if err != nil { @@ -178,14 +178,14 @@ func (s *AppsService) ListInstallations(ctx context.Context, opts *ListOptions) // GetInstallation returns the specified installation. // -// GitHub API docs: https://developer.github.com/v3/apps/#get-an-installation +// GitHub API docs: https://developer.github.com/v3/apps/#get-an-installation-for-the-authenticated-app func (s *AppsService) GetInstallation(ctx context.Context, id int64) (*Installation, *Response, error) { return s.getInstallation(ctx, fmt.Sprintf("app/installations/%v", id)) } // ListUserInstallations lists installations that are accessible to the authenticated user. // -// GitHub API docs: https://developer.github.com/v3/apps/installations/#list-installations-for-a-user +// GitHub API docs: https://developer.github.com/v3/apps/installations/#list-app-installations-accessible-to-the-user-access-token func (s *AppsService) ListUserInstallations(ctx context.Context, opts *ListOptions) ([]*Installation, *Response, error) { u, err := addOptions("user/installations", opts) if err != nil { @@ -213,7 +213,7 @@ func (s *AppsService) ListUserInstallations(ctx context.Context, opts *ListOptio // SuspendInstallation suspends the specified installation. // -// GitHub API docs: https://developer.github.com/v3/apps/#suspend-an-installation +// GitHub API docs: https://developer.github.com/v3/apps/#suspend-an-app-installation func (s *AppsService) SuspendInstallation(ctx context.Context, id int64) (*Response, error) { u := fmt.Sprintf("app/installations/%v/suspended", id) @@ -227,7 +227,7 @@ func (s *AppsService) SuspendInstallation(ctx context.Context, id int64) (*Respo // UnsuspendInstallation unsuspends the specified installation. // -// GitHub API docs: https://developer.github.com/v3/apps/#unsuspend-an-installation +// GitHub API docs: https://developer.github.com/v3/apps/#unsuspend-an-app-installation func (s *AppsService) UnsuspendInstallation(ctx context.Context, id int64) (*Response, error) { u := fmt.Sprintf("app/installations/%v/suspended", id) @@ -241,7 +241,7 @@ func (s *AppsService) UnsuspendInstallation(ctx context.Context, id int64) (*Res // DeleteInstallation deletes the specified installation. // -// GitHub API docs: https://developer.github.com/v3/apps/#delete-an-installation +// GitHub API docs: https://developer.github.com/v3/apps/#delete-an-installation-for-the-authenticated-app func (s *AppsService) DeleteInstallation(ctx context.Context, id int64) (*Response, error) { u := fmt.Sprintf("app/installations/%v", id) @@ -258,7 +258,7 @@ func (s *AppsService) DeleteInstallation(ctx context.Context, id int64) (*Respon // CreateInstallationToken creates a new installation token. // -// GitHub API docs: https://developer.github.com/v3/apps/#create-a-new-installation-token +// GitHub API docs: https://developer.github.com/v3/apps/#create-an-installation-access-token-for-an-app func (s *AppsService) CreateInstallationToken(ctx context.Context, id int64, opts *InstallationTokenOptions) (*InstallationToken, *Response, error) { u := fmt.Sprintf("app/installations/%v/access_tokens", id) @@ -304,14 +304,14 @@ func (s *AppsService) CreateAttachment(ctx context.Context, contentReferenceID i // FindOrganizationInstallation finds the organization's installation information. // -// GitHub API docs: https://developer.github.com/v3/apps/#get-an-organization-installation +// GitHub API docs: https://developer.github.com/v3/apps/#get-an-organization-installation-for-the-authenticated-app func (s *AppsService) FindOrganizationInstallation(ctx context.Context, org string) (*Installation, *Response, error) { return s.getInstallation(ctx, fmt.Sprintf("orgs/%v/installation", org)) } // FindRepositoryInstallation finds the repository's installation information. // -// GitHub API docs: https://developer.github.com/v3/apps/#get-a-repository-installation +// GitHub API docs: https://developer.github.com/v3/apps/#get-a-repository-installation-for-the-authenticated-app func (s *AppsService) FindRepositoryInstallation(ctx context.Context, owner, repo string) (*Installation, *Response, error) { return s.getInstallation(ctx, fmt.Sprintf("repos/%v/%v/installation", owner, repo)) } @@ -325,7 +325,7 @@ func (s *AppsService) FindRepositoryInstallationByID(ctx context.Context, id int // FindUserInstallation finds the user's installation information. // -// GitHub API docs: https://developer.github.com/v3/apps/#get-a-user-installation +// GitHub API docs: https://developer.github.com/v3/apps/#get-a-user-installation-for-the-authenticated-app func (s *AppsService) FindUserInstallation(ctx context.Context, user string) (*Installation, *Response, error) { return s.getInstallation(ctx, fmt.Sprintf("users/%v/installation", user)) } diff --git a/github/apps_installation.go b/github/apps_installation.go index 914afeaa61b..b6864e0381b 100644 --- a/github/apps_installation.go +++ b/github/apps_installation.go @@ -12,7 +12,7 @@ import ( // ListRepos lists the repositories that are accessible to the authenticated installation. // -// GitHub API docs: https://developer.github.com/v3/apps/installations/#list-repositories +// GitHub API docs: https://developer.github.com/v3/apps/installations/#list-repositories-accessible-to-the-app-installation func (s *AppsService) ListRepos(ctx context.Context, opts *ListOptions) ([]*Repository, *Response, error) { u, err := addOptions("installation/repositories", opts) if err != nil { @@ -41,7 +41,7 @@ func (s *AppsService) ListRepos(ctx context.Context, opts *ListOptions) ([]*Repo // ListUserRepos lists repositories that are accessible // to the authenticated user for an installation. // -// GitHub API docs: https://developer.github.com/v3/apps/installations/#list-repositories-accessible-to-the-user-for-an-installation +// GitHub API docs: https://developer.github.com/v3/apps/installations/#list-repositories-accessible-to-the-user-access-token func (s *AppsService) ListUserRepos(ctx context.Context, id int64, opts *ListOptions) ([]*Repository, *Response, error) { u := fmt.Sprintf("user/installations/%v/repositories", id) u, err := addOptions(u, opts) @@ -70,7 +70,7 @@ func (s *AppsService) ListUserRepos(ctx context.Context, id int64, opts *ListOpt // AddRepository adds a single repository to an installation. // -// GitHub API docs: https://developer.github.com/v3/apps/installations/#add-repository-to-installation +// GitHub API docs: https://developer.github.com/v3/apps/installations/#add-a-repository-to-an-app-installation func (s *AppsService) AddRepository(ctx context.Context, instID, repoID int64) (*Repository, *Response, error) { u := fmt.Sprintf("user/installations/%v/repositories/%v", instID, repoID) req, err := s.client.NewRequest("PUT", u, nil) @@ -90,7 +90,7 @@ func (s *AppsService) AddRepository(ctx context.Context, instID, repoID int64) ( // RemoveRepository removes a single repository from an installation. // -// GitHub API docs: https://developer.github.com/v3/apps/installations/#remove-repository-from-installation +// GitHub API docs: https://developer.github.com/v3/apps/installations/#remove-a-repository-from-an-app-installation func (s *AppsService) RemoveRepository(ctx context.Context, instID, repoID int64) (*Response, error) { u := fmt.Sprintf("user/installations/%v/repositories/%v", instID, repoID) req, err := s.client.NewRequest("DELETE", u, nil) @@ -104,7 +104,7 @@ func (s *AppsService) RemoveRepository(ctx context.Context, instID, repoID int64 // RevokeInstallationToken revokes an installation token. // -// GitHub API docs: https://developer.github.com/v3/apps/installations/#revoke-an-installation-token +// GitHub API docs: https://developer.github.com/v3/apps/installations/#revoke-an-installation-access-token func (s *AppsService) RevokeInstallationToken(ctx context.Context) (*Response, error) { u := "installation/token" req, err := s.client.NewRequest("DELETE", u, nil) diff --git a/github/gists.go b/github/gists.go index 026b5d15ee1..af6084f9c41 100644 --- a/github/gists.go +++ b/github/gists.go @@ -191,7 +191,7 @@ func (s *GistsService) Get(ctx context.Context, id string) (*Gist, *Response, er // GetRevision gets a specific revision of a gist. // -// GitHub API docs: https://developer.github.com/v3/gists/#get-a-specific-revision-of-a-gist +// GitHub API docs: https://developer.github.com/v3/gists/#get-a-gist-revision func (s *GistsService) GetRevision(ctx context.Context, id, sha string) (*Gist, *Response, error) { u := fmt.Sprintf("gists/%v/%v", id, sha) req, err := s.client.NewRequest("GET", u, nil) diff --git a/github/gists_comments.go b/github/gists_comments.go index 33913e22fd7..35406a9c3eb 100644 --- a/github/gists_comments.go +++ b/github/gists_comments.go @@ -26,7 +26,7 @@ func (g GistComment) String() string { // ListComments lists all comments for a gist. // -// GitHub API docs: https://developer.github.com/v3/gists/comments/#list-comments-on-a-gist +// GitHub API docs: https://developer.github.com/v3/gists/comments/#list-gist-comments func (s *GistsService) ListComments(ctx context.Context, gistID string, opts *ListOptions) ([]*GistComment, *Response, error) { u := fmt.Sprintf("gists/%v/comments", gistID) u, err := addOptions(u, opts) @@ -50,7 +50,7 @@ func (s *GistsService) ListComments(ctx context.Context, gistID string, opts *Li // GetComment retrieves a single comment from a gist. // -// GitHub API docs: https://developer.github.com/v3/gists/comments/#get-a-single-comment +// GitHub API docs: https://developer.github.com/v3/gists/comments/#get-a-gist-comment func (s *GistsService) GetComment(ctx context.Context, gistID string, commentID int64) (*GistComment, *Response, error) { u := fmt.Sprintf("gists/%v/comments/%v", gistID, commentID) req, err := s.client.NewRequest("GET", u, nil) @@ -69,7 +69,7 @@ func (s *GistsService) GetComment(ctx context.Context, gistID string, commentID // CreateComment creates a comment for a gist. // -// GitHub API docs: https://developer.github.com/v3/gists/comments/#create-a-comment +// GitHub API docs: https://developer.github.com/v3/gists/comments/#create-a-gist-comment func (s *GistsService) CreateComment(ctx context.Context, gistID string, comment *GistComment) (*GistComment, *Response, error) { u := fmt.Sprintf("gists/%v/comments", gistID) req, err := s.client.NewRequest("POST", u, comment) @@ -88,7 +88,7 @@ func (s *GistsService) CreateComment(ctx context.Context, gistID string, comment // EditComment edits an existing gist comment. // -// GitHub API docs: https://developer.github.com/v3/gists/comments/#edit-a-comment +// GitHub API docs: https://developer.github.com/v3/gists/comments/#update-a-gist-comment func (s *GistsService) EditComment(ctx context.Context, gistID string, commentID int64, comment *GistComment) (*GistComment, *Response, error) { u := fmt.Sprintf("gists/%v/comments/%v", gistID, commentID) req, err := s.client.NewRequest("PATCH", u, comment) @@ -107,7 +107,7 @@ func (s *GistsService) EditComment(ctx context.Context, gistID string, commentID // DeleteComment deletes a gist comment. // -// GitHub API docs: https://developer.github.com/v3/gists/comments/#delete-a-comment +// GitHub API docs: https://developer.github.com/v3/gists/comments/#delete-a-gist-comment func (s *GistsService) DeleteComment(ctx context.Context, gistID string, commentID int64) (*Response, error) { u := fmt.Sprintf("gists/%v/comments/%v", gistID, commentID) req, err := s.client.NewRequest("DELETE", u, nil) diff --git a/github/git_refs.go b/github/git_refs.go index 94053aaea1c..ef1d0264165 100644 --- a/github/git_refs.go +++ b/github/git_refs.go @@ -49,7 +49,7 @@ type updateRefRequest struct { // GetRef fetches a single reference in a repository. // -// GitHub API docs: https://developer.github.com/v3/git/refs/#get-a-single-reference +// GitHub API docs: https://developer.github.com/v3/git/refs/#get-a-reference func (s *GitService) GetRef(ctx context.Context, owner string, repo string, ref string) (*Reference, *Response, error) { ref = strings.TrimPrefix(ref, "refs/") u := fmt.Sprintf("repos/%v/%v/git/ref/%v", owner, repo, refURLEscape(ref)) diff --git a/github/gitignore.go b/github/gitignore.go index dc2eab757ae..5d03f055722 100644 --- a/github/gitignore.go +++ b/github/gitignore.go @@ -46,7 +46,7 @@ func (s *GitignoresService) List(ctx context.Context) ([]string, *Response, erro // Get a Gitignore by name. // -// GitHub API docs: https://developer.github.com/v3/gitignore/#get-a-single-template +// GitHub API docs: https://developer.github.com/v3/gitignore/#get-a-gitignore-template func (s *GitignoresService) Get(ctx context.Context, name string) (*Gitignore, *Response, error) { u := fmt.Sprintf("gitignore/templates/%v", name) req, err := s.client.NewRequest("GET", u, nil) diff --git a/github/interactions_orgs.go b/github/interactions_orgs.go index af25f6567db..e2fcabbc901 100644 --- a/github/interactions_orgs.go +++ b/github/interactions_orgs.go @@ -39,7 +39,7 @@ func (s *InteractionsService) GetRestrictionsForOrg(ctx context.Context, organiz // in public repositories for the given organization. // Possible values are: "existing_users", "contributors_only", "collaborators_only". // -// GitHub API docs: https://developer.github.com/v3/interactions/orgs/#add-or-update-interaction-restrictions-for-an-organization +// GitHub API docs: https://developer.github.com/v3/interactions/orgs/#set-interaction-restrictions-for-an-organization func (s *InteractionsService) UpdateRestrictionsForOrg(ctx context.Context, organization, limit string) (*InteractionRestriction, *Response, error) { u := fmt.Sprintf("orgs/%v/interaction-limits", organization) diff --git a/github/interactions_repos.go b/github/interactions_repos.go index 58234822fdd..74f4ec4d6d5 100644 --- a/github/interactions_repos.go +++ b/github/interactions_repos.go @@ -39,7 +39,7 @@ func (s *InteractionsService) GetRestrictionsForRepo(ctx context.Context, owner, // for the given repository. // Possible values are: "existing_users", "contributors_only", "collaborators_only". // -// GitHub API docs: https://developer.github.com/v3/interactions/repos/#add-or-update-interaction-restrictions-for-a-repository +// GitHub API docs: https://developer.github.com/v3/interactions/repos/#set-interaction-restrictions-for-a-repository func (s *InteractionsService) UpdateRestrictionsForRepo(ctx context.Context, owner, repo, limit string) (*InteractionRestriction, *Response, error) { u := fmt.Sprintf("repos/%v/%v/interaction-limits", owner, repo) diff --git a/github/issues_assignees.go b/github/issues_assignees.go index c09806fd62e..fedb3510615 100644 --- a/github/issues_assignees.go +++ b/github/issues_assignees.go @@ -36,7 +36,7 @@ func (s *IssuesService) ListAssignees(ctx context.Context, owner, repo string, o // IsAssignee checks if a user is an assignee for the specified repository. // -// GitHub API docs: https://developer.github.com/v3/issues/assignees/#check-assignee +// GitHub API docs: https://developer.github.com/v3/issues/assignees/#check-if-a-user-can-be-assigned func (s *IssuesService) IsAssignee(ctx context.Context, owner, repo, user string) (bool, *Response, error) { u := fmt.Sprintf("repos/%v/%v/assignees/%v", owner, repo, user) req, err := s.client.NewRequest("GET", u, nil) diff --git a/github/issues_comments.go b/github/issues_comments.go index 5e5a754744e..fc67511bf6d 100644 --- a/github/issues_comments.go +++ b/github/issues_comments.go @@ -50,8 +50,8 @@ type IssueListCommentsOptions struct { // ListComments lists all comments on the specified issue. Specifying an issue // number of 0 will return all comments on all issues for the repository. // -// GitHub API docs: https://developer.github.com/v3/issues/comments/#list-comments-in-a-repository -// GitHub API docs: https://developer.github.com/v3/issues/comments/#list-comments-on-an-issue +// GitHub API docs: https://developer.github.com/v3/issues/comments/#list-issue-comments +// GitHub API docs: https://developer.github.com/v3/issues/comments/#list-issue-comments-for-a-repository func (s *IssuesService) ListComments(ctx context.Context, owner string, repo string, number int, opts *IssueListCommentsOptions) ([]*IssueComment, *Response, error) { var u string if number == 0 { @@ -83,7 +83,7 @@ func (s *IssuesService) ListComments(ctx context.Context, owner string, repo str // GetComment fetches the specified issue comment. // -// GitHub API docs: https://developer.github.com/v3/issues/comments/#get-a-single-comment +// GitHub API docs: https://developer.github.com/v3/issues/comments/#get-an-issue-comment func (s *IssuesService) GetComment(ctx context.Context, owner string, repo string, commentID int64) (*IssueComment, *Response, error) { u := fmt.Sprintf("repos/%v/%v/issues/comments/%d", owner, repo, commentID) @@ -106,7 +106,7 @@ func (s *IssuesService) GetComment(ctx context.Context, owner string, repo strin // CreateComment creates a new comment on the specified issue. // -// GitHub API docs: https://developer.github.com/v3/issues/comments/#create-a-comment +// GitHub API docs: https://developer.github.com/v3/issues/comments/#create-an-issue-comment func (s *IssuesService) CreateComment(ctx context.Context, owner string, repo string, number int, comment *IssueComment) (*IssueComment, *Response, error) { u := fmt.Sprintf("repos/%v/%v/issues/%d/comments", owner, repo, number) req, err := s.client.NewRequest("POST", u, comment) @@ -125,7 +125,7 @@ func (s *IssuesService) CreateComment(ctx context.Context, owner string, repo st // EditComment updates an issue comment. // A non-nil comment.Body must be provided. Other comment fields should be left nil. // -// GitHub API docs: https://developer.github.com/v3/issues/comments/#edit-a-comment +// GitHub API docs: https://developer.github.com/v3/issues/comments/#update-an-issue-comment func (s *IssuesService) EditComment(ctx context.Context, owner string, repo string, commentID int64, comment *IssueComment) (*IssueComment, *Response, error) { u := fmt.Sprintf("repos/%v/%v/issues/comments/%d", owner, repo, commentID) req, err := s.client.NewRequest("PATCH", u, comment) @@ -143,7 +143,7 @@ func (s *IssuesService) EditComment(ctx context.Context, owner string, repo stri // DeleteComment deletes an issue comment. // -// GitHub API docs: https://developer.github.com/v3/issues/comments/#delete-a-comment +// GitHub API docs: https://developer.github.com/v3/issues/comments/#delete-an-issue-comment func (s *IssuesService) DeleteComment(ctx context.Context, owner string, repo string, commentID int64) (*Response, error) { u := fmt.Sprintf("repos/%v/%v/issues/comments/%d", owner, repo, commentID) req, err := s.client.NewRequest("DELETE", u, nil) diff --git a/github/issues_events.go b/github/issues_events.go index fa948596a31..8d3dd864cd1 100644 --- a/github/issues_events.go +++ b/github/issues_events.go @@ -95,7 +95,7 @@ type DismissedReview struct { // ListIssueEvents lists events for the specified issue. // -// GitHub API docs: https://developer.github.com/v3/issues/events/#list-events-for-an-issue +// GitHub API docs: https://developer.github.com/v3/issues/events/#list-issue-events func (s *IssuesService) ListIssueEvents(ctx context.Context, owner, repo string, number int, opts *ListOptions) ([]*IssueEvent, *Response, error) { u := fmt.Sprintf("repos/%v/%v/issues/%v/events", owner, repo, number) u, err := addOptions(u, opts) @@ -122,7 +122,7 @@ func (s *IssuesService) ListIssueEvents(ctx context.Context, owner, repo string, // ListRepositoryEvents lists events for the specified repository. // -// GitHub API docs: https://developer.github.com/v3/issues/events/#list-events-for-a-repository +// GitHub API docs: https://developer.github.com/v3/issues/events/#list-issue-events-for-a-repository func (s *IssuesService) ListRepositoryEvents(ctx context.Context, owner, repo string, opts *ListOptions) ([]*IssueEvent, *Response, error) { u := fmt.Sprintf("repos/%v/%v/issues/events", owner, repo) u, err := addOptions(u, opts) @@ -146,7 +146,7 @@ func (s *IssuesService) ListRepositoryEvents(ctx context.Context, owner, repo st // GetEvent returns the specified issue event. // -// GitHub API docs: https://developer.github.com/v3/issues/events/#get-a-single-event +// GitHub API docs: https://developer.github.com/v3/issues/events/#get-an-issue-event func (s *IssuesService) GetEvent(ctx context.Context, owner, repo string, id int64) (*IssueEvent, *Response, error) { u := fmt.Sprintf("repos/%v/%v/issues/events/%v", owner, repo, id) diff --git a/github/issues_labels.go b/github/issues_labels.go index fa3002599a8..12a87415547 100644 --- a/github/issues_labels.go +++ b/github/issues_labels.go @@ -27,7 +27,7 @@ func (l Label) String() string { // ListLabels lists all labels for a repository. // -// GitHub API docs: https://developer.github.com/v3/issues/labels/#list-all-labels-for-this-repository +// GitHub API docs: https://developer.github.com/v3/issues/labels/#list-labels-for-a-repository func (s *IssuesService) ListLabels(ctx context.Context, owner string, repo string, opts *ListOptions) ([]*Label, *Response, error) { u := fmt.Sprintf("repos/%v/%v/labels", owner, repo) u, err := addOptions(u, opts) @@ -51,7 +51,7 @@ func (s *IssuesService) ListLabels(ctx context.Context, owner string, repo strin // GetLabel gets a single label. // -// GitHub API docs: https://developer.github.com/v3/issues/labels/#get-a-single-label +// GitHub API docs: https://developer.github.com/v3/issues/labels/#get-a-label func (s *IssuesService) GetLabel(ctx context.Context, owner string, repo string, name string) (*Label, *Response, error) { u := fmt.Sprintf("repos/%v/%v/labels/%v", owner, repo, name) req, err := s.client.NewRequest("GET", u, nil) @@ -120,7 +120,7 @@ func (s *IssuesService) DeleteLabel(ctx context.Context, owner string, repo stri // ListLabelsByIssue lists all labels for an issue. // -// GitHub API docs: https://developer.github.com/v3/issues/labels/#list-labels-on-an-issue +// GitHub API docs: https://developer.github.com/v3/issues/labels/#list-labels-for-an-issue func (s *IssuesService) ListLabelsByIssue(ctx context.Context, owner string, repo string, number int, opts *ListOptions) ([]*Label, *Response, error) { u := fmt.Sprintf("repos/%v/%v/issues/%d/labels", owner, repo, number) u, err := addOptions(u, opts) @@ -176,7 +176,7 @@ func (s *IssuesService) RemoveLabelForIssue(ctx context.Context, owner string, r // ReplaceLabelsForIssue replaces all labels for an issue. // -// GitHub API docs: https://developer.github.com/v3/issues/labels/#replace-all-labels-for-an-issue +// GitHub API docs: https://developer.github.com/v3/issues/labels/#set-labels-for-an-issue func (s *IssuesService) ReplaceLabelsForIssue(ctx context.Context, owner string, repo string, number int, labels []string) ([]*Label, *Response, error) { u := fmt.Sprintf("repos/%v/%v/issues/%d/labels", owner, repo, number) req, err := s.client.NewRequest("PUT", u, labels) @@ -208,7 +208,7 @@ func (s *IssuesService) RemoveLabelsForIssue(ctx context.Context, owner string, // ListLabelsForMilestone lists labels for every issue in a milestone. // -// GitHub API docs: https://developer.github.com/v3/issues/labels/#get-labels-for-every-issue-in-a-milestone +// GitHub API docs: https://developer.github.com/v3/issues/labels/#list-labels-for-issues-in-a-milestone func (s *IssuesService) ListLabelsForMilestone(ctx context.Context, owner string, repo string, number int, opts *ListOptions) ([]*Label, *Response, error) { u := fmt.Sprintf("repos/%v/%v/milestones/%d/labels", owner, repo, number) u, err := addOptions(u, opts) diff --git a/github/issues_milestones.go b/github/issues_milestones.go index 4e44350722f..ed3a7c54f2d 100644 --- a/github/issues_milestones.go +++ b/github/issues_milestones.go @@ -55,7 +55,7 @@ type MilestoneListOptions struct { // ListMilestones lists all milestones for a repository. // -// GitHub API docs: https://developer.github.com/v3/issues/milestones/#list-milestones-for-a-repository +// GitHub API docs: https://developer.github.com/v3/issues/milestones/#list-milestones func (s *IssuesService) ListMilestones(ctx context.Context, owner string, repo string, opts *MilestoneListOptions) ([]*Milestone, *Response, error) { u := fmt.Sprintf("repos/%v/%v/milestones", owner, repo) u, err := addOptions(u, opts) @@ -79,7 +79,7 @@ func (s *IssuesService) ListMilestones(ctx context.Context, owner string, repo s // GetMilestone gets a single milestone. // -// GitHub API docs: https://developer.github.com/v3/issues/milestones/#get-a-single-milestone +// GitHub API docs: https://developer.github.com/v3/issues/milestones/#get-a-milestone func (s *IssuesService) GetMilestone(ctx context.Context, owner string, repo string, number int) (*Milestone, *Response, error) { u := fmt.Sprintf("repos/%v/%v/milestones/%d", owner, repo, number) req, err := s.client.NewRequest("GET", u, nil) diff --git a/github/issues_timeline.go b/github/issues_timeline.go index 58465e22285..6a88af8ca49 100644 --- a/github/issues_timeline.go +++ b/github/issues_timeline.go @@ -131,7 +131,7 @@ type Source struct { // ListIssueTimeline lists events for the specified issue. // -// GitHub API docs: https://developer.github.com/v3/issues/timeline/#list-events-for-an-issue +// GitHub API docs: https://developer.github.com/v3/issues/timeline/#list-timeline-events-for-an-issue func (s *IssuesService) ListIssueTimeline(ctx context.Context, owner, repo string, number int, opts *ListOptions) ([]*Timeline, *Response, error) { u := fmt.Sprintf("repos/%v/%v/issues/%v/timeline", owner, repo, number) u, err := addOptions(u, opts) diff --git a/github/licenses.go b/github/licenses.go index 1176d3a8bf7..55885f27046 100644 --- a/github/licenses.go +++ b/github/licenses.go @@ -78,7 +78,7 @@ func (s *LicensesService) List(ctx context.Context) ([]*License, *Response, erro // Get extended metadata for one license. // -// GitHub API docs: https://developer.github.com/v3/licenses/#get-an-individual-license +// GitHub API docs: https://developer.github.com/v3/licenses/#get-a-license func (s *LicensesService) Get(ctx context.Context, licenseName string) (*License, *Response, error) { u := fmt.Sprintf("licenses/%s", licenseName) diff --git a/github/migrations.go b/github/migrations.go index 86b7c2789e0..fae0c6e17db 100644 --- a/github/migrations.go +++ b/github/migrations.go @@ -131,7 +131,7 @@ func (s *MigrationService) ListMigrations(ctx context.Context, org string, opts // MigrationStatus gets the status of a specific migration archive. // id is the migration ID. // -// GitHub API docs: https://developer.github.com/v3/migrations/orgs/#get-the-status-of-an-organization-migration +// GitHub API docs: https://developer.github.com/v3/migrations/orgs/#get-an-organization-migration-status func (s *MigrationService) MigrationStatus(ctx context.Context, org string, id int64) (*Migration, *Response, error) { u := fmt.Sprintf("orgs/%v/migrations/%v", org, id) diff --git a/github/migrations_source_import.go b/github/migrations_source_import.go index 3980dc902c1..7a46d0edfff 100644 --- a/github/migrations_source_import.go +++ b/github/migrations_source_import.go @@ -165,7 +165,7 @@ func (s *MigrationService) StartImport(ctx context.Context, owner, repo string, // ImportProgress queries for the status and progress of an ongoing repository import. // -// GitHub API docs: https://developer.github.com/v3/migrations/source_imports/#get-import-progress +// GitHub API docs: https://developer.github.com/v3/migrations/source_imports/#get-an-import-status func (s *MigrationService) ImportProgress(ctx context.Context, owner, repo string) (*Import, *Response, error) { u := fmt.Sprintf("repos/%v/%v/import", owner, repo) req, err := s.client.NewRequest("GET", u, nil) @@ -184,7 +184,7 @@ func (s *MigrationService) ImportProgress(ctx context.Context, owner, repo strin // UpdateImport initiates a repository import. // -// GitHub API docs: https://developer.github.com/v3/migrations/source_imports/#update-existing-import +// GitHub API docs: https://developer.github.com/v3/migrations/source_imports/#update-an-import func (s *MigrationService) UpdateImport(ctx context.Context, owner, repo string, in *Import) (*Import, *Response, error) { u := fmt.Sprintf("repos/%v/%v/import", owner, repo) req, err := s.client.NewRequest("PATCH", u, in) @@ -255,7 +255,7 @@ func (s *MigrationService) MapCommitAuthor(ctx context.Context, owner, repo stri // files larger than 100MB. Only the UseLFS field on the provided Import is // used. // -// GitHub API docs: https://developer.github.com/v3/migrations/source_imports/#set-git-lfs-preference +// GitHub API docs: https://developer.github.com/v3/migrations/source_imports/#update-git-lfs-preference func (s *MigrationService) SetLFSPreference(ctx context.Context, owner, repo string, in *Import) (*Import, *Response, error) { u := fmt.Sprintf("repos/%v/%v/import/lfs", owner, repo) req, err := s.client.NewRequest("PATCH", u, in) diff --git a/github/migrations_user.go b/github/migrations_user.go index 5224d7b844c..d03bfe7ef2f 100644 --- a/github/migrations_user.go +++ b/github/migrations_user.go @@ -120,7 +120,7 @@ func (s *MigrationService) ListUserMigrations(ctx context.Context) ([]*UserMigra // UserMigrationStatus gets the status of a specific migration archive. // id is the migration ID. // -// GitHub API docs: https://developer.github.com/v3/migrations/users/#get-the-status-of-a-user-migration +// GitHub API docs: https://developer.github.com/v3/migrations/users/#get-a-user-migration-status func (s *MigrationService) UserMigrationStatus(ctx context.Context, id int64) (*UserMigration, *Response, error) { u := fmt.Sprintf("user/migrations/%v", id) diff --git a/github/orgs.go b/github/orgs.go index 4065b0148d6..4fd6bbd5097 100644 --- a/github/orgs.go +++ b/github/orgs.go @@ -125,7 +125,7 @@ type OrganizationsListOptions struct { // listing the next set of organizations, use the ID of the last-returned organization // as the opts.Since parameter for the next call. // -// GitHub API docs: https://developer.github.com/v3/orgs/#list-all-organizations +// GitHub API docs: https://developer.github.com/v3/orgs/#list-organizations func (s *OrganizationsService) ListAll(ctx context.Context, opts *OrganizationsListOptions) ([]*Organization, *Response, error) { u, err := addOptions("organizations", opts) if err != nil { @@ -148,8 +148,8 @@ func (s *OrganizationsService) ListAll(ctx context.Context, opts *OrganizationsL // List the organizations for a user. Passing the empty string will list // organizations for the authenticated user. // -// GitHub API docs: https://developer.github.com/v3/orgs/#list-user-organizations // GitHub API docs: https://developer.github.com/v3/orgs/#oauth-scope-requirements +// GitHub API docs: https://developer.github.com/v3/orgs/#list-organizations-for-a-user func (s *OrganizationsService) List(ctx context.Context, user string, opts *ListOptions) ([]*Organization, *Response, error) { var u string if user != "" { @@ -241,7 +241,7 @@ func (s *OrganizationsService) Edit(ctx context.Context, name string, org *Organ // ListInstallations lists installations for an organization. // -// GitHub API docs: https://developer.github.com/v3/orgs/#list-installations-for-an-organization +// GitHub API docs: https://developer.github.com/v3/orgs/#list-app-installations-for-an-organization func (s *OrganizationsService) ListInstallations(ctx context.Context, org string, opts *ListOptions) (*OrganizationInstallations, *Response, error) { u := fmt.Sprintf("orgs/%v/installations", org) diff --git a/github/orgs_hooks.go b/github/orgs_hooks.go index 0913fb83dac..a3a5f8df46c 100644 --- a/github/orgs_hooks.go +++ b/github/orgs_hooks.go @@ -12,7 +12,7 @@ import ( // ListHooks lists all Hooks for the specified organization. // -// GitHub API docs: https://developer.github.com/v3/orgs/hooks/#list-hooks +// GitHub API docs: https://developer.github.com/v3/orgs/hooks/#list-organization-webhooks func (s *OrganizationsService) ListHooks(ctx context.Context, org string, opts *ListOptions) ([]*Hook, *Response, error) { u := fmt.Sprintf("orgs/%v/hooks", org) u, err := addOptions(u, opts) @@ -36,7 +36,7 @@ func (s *OrganizationsService) ListHooks(ctx context.Context, org string, opts * // GetHook returns a single specified Hook. // -// GitHub API docs: https://developer.github.com/v3/orgs/hooks/#get-single-hook +// GitHub API docs: https://developer.github.com/v3/orgs/hooks/#get-an-organization-webhook func (s *OrganizationsService) GetHook(ctx context.Context, org string, id int64) (*Hook, *Response, error) { u := fmt.Sprintf("orgs/%v/hooks/%d", org, id) req, err := s.client.NewRequest("GET", u, nil) @@ -54,7 +54,7 @@ func (s *OrganizationsService) GetHook(ctx context.Context, org string, id int64 // Note that only a subset of the hook fields are used and hook must // not be nil. // -// GitHub API docs: https://developer.github.com/v3/orgs/hooks/#create-a-hook +// GitHub API docs: https://developer.github.com/v3/orgs/hooks/#create-an-organization-webhook func (s *OrganizationsService) CreateHook(ctx context.Context, org string, hook *Hook) (*Hook, *Response, error) { u := fmt.Sprintf("orgs/%v/hooks", org) @@ -81,7 +81,7 @@ func (s *OrganizationsService) CreateHook(ctx context.Context, org string, hook // EditHook updates a specified Hook. // -// GitHub API docs: https://developer.github.com/v3/orgs/hooks/#edit-a-hook +// GitHub API docs: https://developer.github.com/v3/orgs/hooks/#update-an-organization-webhook func (s *OrganizationsService) EditHook(ctx context.Context, org string, id int64, hook *Hook) (*Hook, *Response, error) { u := fmt.Sprintf("orgs/%v/hooks/%d", org, id) req, err := s.client.NewRequest("PATCH", u, hook) @@ -95,7 +95,7 @@ func (s *OrganizationsService) EditHook(ctx context.Context, org string, id int6 // PingHook triggers a 'ping' event to be sent to the Hook. // -// GitHub API docs: https://developer.github.com/v3/orgs/hooks/#ping-a-hook +// GitHub API docs: https://developer.github.com/v3/orgs/hooks/#ping-an-organization-webhook func (s *OrganizationsService) PingHook(ctx context.Context, org string, id int64) (*Response, error) { u := fmt.Sprintf("orgs/%v/hooks/%d/pings", org, id) req, err := s.client.NewRequest("POST", u, nil) @@ -107,7 +107,7 @@ func (s *OrganizationsService) PingHook(ctx context.Context, org string, id int6 // DeleteHook deletes a specified Hook. // -// GitHub API docs: https://developer.github.com/v3/orgs/hooks/#delete-a-hook +// GitHub API docs: https://developer.github.com/v3/orgs/hooks/#delete-an-organization-webhook func (s *OrganizationsService) DeleteHook(ctx context.Context, org string, id int64) (*Response, error) { u := fmt.Sprintf("orgs/%v/hooks/%d", org, id) req, err := s.client.NewRequest("DELETE", u, nil) diff --git a/github/orgs_members.go b/github/orgs_members.go index 0dfa92070d5..e388a4c6ede 100644 --- a/github/orgs_members.go +++ b/github/orgs_members.go @@ -71,8 +71,8 @@ type ListMembersOptions struct { // user is an owner of the organization, this will return both concealed and // public members, otherwise it will only return public members. // -// GitHub API docs: https://developer.github.com/v3/orgs/members/#members-list -// GitHub API docs: https://developer.github.com/v3/orgs/members/#public-members-list +// GitHub API docs: https://developer.github.com/v3/orgs/members/#list-organization-members +// GitHub API docs: https://developer.github.com/v3/orgs/members/#list-public-organization-members func (s *OrganizationsService) ListMembers(ctx context.Context, org string, opts *ListMembersOptions) ([]*User, *Response, error) { var u string if opts != nil && opts.PublicOnly { @@ -101,7 +101,7 @@ func (s *OrganizationsService) ListMembers(ctx context.Context, org string, opts // IsMember checks if a user is a member of an organization. // -// GitHub API docs: https://developer.github.com/v3/orgs/members/#check-membership +// GitHub API docs: https://developer.github.com/v3/orgs/members/#check-organization-membership-for-a-user func (s *OrganizationsService) IsMember(ctx context.Context, org, user string) (bool, *Response, error) { u := fmt.Sprintf("orgs/%v/members/%v", org, user) req, err := s.client.NewRequest("GET", u, nil) @@ -116,7 +116,7 @@ func (s *OrganizationsService) IsMember(ctx context.Context, org, user string) ( // IsPublicMember checks if a user is a public member of an organization. // -// GitHub API docs: https://developer.github.com/v3/orgs/members/#check-public-membership +// GitHub API docs: https://developer.github.com/v3/orgs/members/#check-public-organization-membership-for-a-user func (s *OrganizationsService) IsPublicMember(ctx context.Context, org, user string) (bool, *Response, error) { u := fmt.Sprintf("orgs/%v/public_members/%v", org, user) req, err := s.client.NewRequest("GET", u, nil) @@ -131,7 +131,7 @@ func (s *OrganizationsService) IsPublicMember(ctx context.Context, org, user str // RemoveMember removes a user from all teams of an organization. // -// GitHub API docs: https://developer.github.com/v3/orgs/members/#remove-a-member +// GitHub API docs: https://developer.github.com/v3/orgs/members/#remove-an-organization-member func (s *OrganizationsService) RemoveMember(ctx context.Context, org, user string) (*Response, error) { u := fmt.Sprintf("orgs/%v/members/%v", org, user) req, err := s.client.NewRequest("DELETE", u, nil) @@ -145,7 +145,7 @@ func (s *OrganizationsService) RemoveMember(ctx context.Context, org, user strin // PublicizeMembership publicizes a user's membership in an organization. (A // user cannot publicize the membership for another user.) // -// GitHub API docs: https://developer.github.com/v3/orgs/members/#publicize-a-users-membership +// GitHub API docs: https://developer.github.com/v3/orgs/members/#set-public-organization-membership-for-the-authenticated-user func (s *OrganizationsService) PublicizeMembership(ctx context.Context, org, user string) (*Response, error) { u := fmt.Sprintf("orgs/%v/public_members/%v", org, user) req, err := s.client.NewRequest("PUT", u, nil) @@ -158,7 +158,7 @@ func (s *OrganizationsService) PublicizeMembership(ctx context.Context, org, use // ConcealMembership conceals a user's membership in an organization. // -// GitHub API docs: https://developer.github.com/v3/orgs/members/#conceal-a-users-membership +// GitHub API docs: https://developer.github.com/v3/orgs/members/#remove-public-organization-membership-for-the-authenticated-user func (s *OrganizationsService) ConcealMembership(ctx context.Context, org, user string) (*Response, error) { u := fmt.Sprintf("orgs/%v/public_members/%v", org, user) req, err := s.client.NewRequest("DELETE", u, nil) @@ -181,7 +181,7 @@ type ListOrgMembershipsOptions struct { // ListOrgMemberships lists the organization memberships for the authenticated user. // -// GitHub API docs: https://developer.github.com/v3/orgs/members/#list-your-organization-memberships +// GitHub API docs: https://developer.github.com/v3/orgs/members/#list-organization-memberships-for-the-authenticated-user func (s *OrganizationsService) ListOrgMemberships(ctx context.Context, opts *ListOrgMembershipsOptions) ([]*Membership, *Response, error) { u := "user/memberships/orgs" u, err := addOptions(u, opts) @@ -207,8 +207,8 @@ func (s *OrganizationsService) ListOrgMemberships(ctx context.Context, opts *Lis // Passing an empty string for user will get the membership for the // authenticated user. // -// GitHub API docs: https://developer.github.com/v3/orgs/members/#get-organization-membership -// GitHub API docs: https://developer.github.com/v3/orgs/members/#get-your-organization-membership +// GitHub API docs: https://developer.github.com/v3/orgs/members/#get-an-organization-membership-for-the-authenticated-user +// GitHub API docs: https://developer.github.com/v3/orgs/members/#get-organization-membership-for-a-user func (s *OrganizationsService) GetOrgMembership(ctx context.Context, user, org string) (*Membership, *Response, error) { var u string if user != "" { @@ -235,8 +235,8 @@ func (s *OrganizationsService) GetOrgMembership(ctx context.Context, user, org s // Passing an empty string for user will edit the membership for the // authenticated user. // -// GitHub API docs: https://developer.github.com/v3/orgs/members/#add-or-update-organization-membership -// GitHub API docs: https://developer.github.com/v3/orgs/members/#edit-your-organization-membership +// GitHub API docs: https://developer.github.com/v3/orgs/members/#update-an-organization-membership-for-the-authenticated-user +// GitHub API docs: https://developer.github.com/v3/orgs/members/#set-organization-membership-for-a-user func (s *OrganizationsService) EditOrgMembership(ctx context.Context, user, org string, membership *Membership) (*Membership, *Response, error) { var u, method string if user != "" { @@ -264,7 +264,7 @@ func (s *OrganizationsService) EditOrgMembership(ctx context.Context, user, org // RemoveOrgMembership removes user from the specified organization. If the // user has been invited to the organization, this will cancel their invitation. // -// GitHub API docs: https://developer.github.com/v3/orgs/members/#remove-organization-membership +// GitHub API docs: https://developer.github.com/v3/orgs/members/#remove-organization-membership-for-a-user func (s *OrganizationsService) RemoveOrgMembership(ctx context.Context, user, org string) (*Response, error) { u := fmt.Sprintf("orgs/%v/memberships/%v", org, user) req, err := s.client.NewRequest("DELETE", u, nil) @@ -322,7 +322,7 @@ type CreateOrgInvitationOptions struct { // In order to create invitations in an organization, // the authenticated user must be an organization owner. // -// GitHub API docs: https://developer.github.com/v3/orgs/members/#create-organization-invitation +// GitHub API docs: https://developer.github.com/v3/orgs/members/#create-an-organization-invitation func (s *OrganizationsService) CreateOrgInvitation(ctx context.Context, org string, opts *CreateOrgInvitationOptions) (*Invitation, *Response, error) { u := fmt.Sprintf("orgs/%v/invitations", org) diff --git a/github/orgs_outside_collaborators.go b/github/orgs_outside_collaborators.go index dde8e0b03ab..4dc3912ac71 100644 --- a/github/orgs_outside_collaborators.go +++ b/github/orgs_outside_collaborators.go @@ -27,7 +27,7 @@ type ListOutsideCollaboratorsOptions struct { // Warning: The API may change without advance notice during the preview period. // Preview features are not supported for production use. // -// GitHub API docs: https://developer.github.com/v3/orgs/outside_collaborators/#list-outside-collaborators +// GitHub API docs: https://developer.github.com/v3/orgs/outside_collaborators/#list-outside-collaborators-for-an-organization func (s *OrganizationsService) ListOutsideCollaborators(ctx context.Context, org string, opts *ListOutsideCollaboratorsOptions) ([]*User, *Response, error) { u := fmt.Sprintf("orgs/%v/outside_collaborators", org) u, err := addOptions(u, opts) @@ -52,7 +52,7 @@ func (s *OrganizationsService) ListOutsideCollaborators(ctx context.Context, org // RemoveOutsideCollaborator removes a user from the list of outside collaborators; // consequently, removing them from all the organization's repositories. // -// GitHub API docs: https://developer.github.com/v3/orgs/outside_collaborators/#remove-outside-collaborator +// GitHub API docs: https://developer.github.com/v3/orgs/outside_collaborators/#remove-outside-collaborator-from-an-organization func (s *OrganizationsService) RemoveOutsideCollaborator(ctx context.Context, org string, user string) (*Response, error) { u := fmt.Sprintf("orgs/%v/outside_collaborators/%v", org, user) req, err := s.client.NewRequest("DELETE", u, nil) @@ -69,7 +69,7 @@ func (s *OrganizationsService) RemoveOutsideCollaborator(ctx context.Context, or // Responses for converting a non-member or the last owner to an outside collaborator // are listed in GitHub API docs. // -// GitHub API docs: https://developer.github.com/v3/orgs/outside_collaborators/#convert-member-to-outside-collaborator +// GitHub API docs: https://developer.github.com/v3/orgs/outside_collaborators/#convert-an-organization-member-to-outside-collaborator func (s *OrganizationsService) ConvertMemberToOutsideCollaborator(ctx context.Context, org string, user string) (*Response, error) { u := fmt.Sprintf("orgs/%v/outside_collaborators/%v", org, user) req, err := s.client.NewRequest("PUT", u, nil) diff --git a/github/orgs_users_blocking.go b/github/orgs_users_blocking.go index bf48716d731..7795d781ad9 100644 --- a/github/orgs_users_blocking.go +++ b/github/orgs_users_blocking.go @@ -12,7 +12,7 @@ import ( // ListBlockedUsers lists all the users blocked by an organization. // -// GitHub API docs: https://developer.github.com/v3/orgs/blocking/#list-blocked-users +// GitHub API docs: https://developer.github.com/v3/orgs/blocking/#list-users-blocked-by-an-organization func (s *OrganizationsService) ListBlockedUsers(ctx context.Context, org string, opts *ListOptions) ([]*User, *Response, error) { u := fmt.Sprintf("orgs/%v/blocks", org) u, err := addOptions(u, opts) @@ -39,7 +39,7 @@ func (s *OrganizationsService) ListBlockedUsers(ctx context.Context, org string, // IsBlocked reports whether specified user is blocked from an organization. // -// GitHub API docs: https://developer.github.com/v3/orgs/blocking/#check-whether-a-user-is-blocked-from-an-organization +// GitHub API docs: https://developer.github.com/v3/orgs/blocking/#check-if-a-user-is-blocked-by-an-organization func (s *OrganizationsService) IsBlocked(ctx context.Context, org string, user string) (bool, *Response, error) { u := fmt.Sprintf("orgs/%v/blocks/%v", org, user) @@ -58,7 +58,7 @@ func (s *OrganizationsService) IsBlocked(ctx context.Context, org string, user s // BlockUser blocks specified user from an organization. // -// GitHub API docs: https://developer.github.com/v3/orgs/blocking/#block-a-user +// GitHub API docs: https://developer.github.com/v3/orgs/blocking/#block-a-user-from-an-organization func (s *OrganizationsService) BlockUser(ctx context.Context, org string, user string) (*Response, error) { u := fmt.Sprintf("orgs/%v/blocks/%v", org, user) @@ -75,7 +75,7 @@ func (s *OrganizationsService) BlockUser(ctx context.Context, org string, user s // UnblockUser unblocks specified user from an organization. // -// GitHub API docs: https://developer.github.com/v3/orgs/blocking/#unblock-a-user +// GitHub API docs: https://developer.github.com/v3/orgs/blocking/#unblock-a-user-from-an-organization func (s *OrganizationsService) UnblockUser(ctx context.Context, org string, user string) (*Response, error) { u := fmt.Sprintf("orgs/%v/blocks/%v", org, user) diff --git a/github/projects.go b/github/projects.go index e11d74a559a..1a4d8443cd3 100644 --- a/github/projects.go +++ b/github/projects.go @@ -483,7 +483,7 @@ type ProjectCollaboratorOptions struct { // AddProjectCollaborator adds a collaborator to an organization project and sets // their permission level. You must be an organization owner or a project admin to add a collaborator. // -// GitHub API docs: https://developer.github.com/v3/projects/collaborators/#add-user-as-a-collaborator +// GitHub API docs: https://developer.github.com/v3/projects/collaborators/#add-project-collaborator func (s *ProjectsService) AddProjectCollaborator(ctx context.Context, id int64, username string, opts *ProjectCollaboratorOptions) (*Response, error) { u := fmt.Sprintf("projects/%v/collaborators/%v", id, username) req, err := s.client.NewRequest("PUT", u, opts) @@ -500,7 +500,7 @@ func (s *ProjectsService) AddProjectCollaborator(ctx context.Context, id int64, // RemoveProjectCollaborator removes a collaborator from an organization project. // You must be an organization owner or a project admin to remove a collaborator. // -// GitHub API docs: https://developer.github.com/v3/projects/collaborators/#remove-user-as-a-collaborator +// GitHub API docs: https://developer.github.com/v3/projects/collaborators/#remove-project-collaborator func (s *ProjectsService) RemoveProjectCollaborator(ctx context.Context, id int64, username string) (*Response, error) { u := fmt.Sprintf("projects/%v/collaborators/%v", id, username) req, err := s.client.NewRequest("DELETE", u, nil) @@ -536,7 +536,7 @@ type ListCollaboratorOptions struct { // with access through default organization permissions, and organization owners. You must be an // organization owner or a project admin to list collaborators. // -// GitHub API docs: https://developer.github.com/v3/projects/collaborators/#list-collaborators +// GitHub API docs: https://developer.github.com/v3/projects/collaborators/#list-project-collaborators func (s *ProjectsService) ListProjectCollaborators(ctx context.Context, id int64, opts *ListCollaboratorOptions) ([]*User, *Response, error) { u := fmt.Sprintf("projects/%v/collaborators", id) u, err := addOptions(u, opts) @@ -574,7 +574,7 @@ type ProjectPermissionLevel struct { // project. Possible values for the permission key: "admin", "write", "read", "none". // You must be an organization owner or a project admin to review a user's permission level. // -// GitHub API docs: https://developer.github.com/v3/projects/collaborators/#review-a-users-permission-level +// GitHub API docs: https://developer.github.com/v3/projects/collaborators/#get-project-permission-for-a-user func (s *ProjectsService) ReviewProjectCollaboratorPermission(ctx context.Context, id int64, username string) (*ProjectPermissionLevel, *Response, error) { u := fmt.Sprintf("projects/%v/collaborators/%v/permission", id, username) req, err := s.client.NewRequest("GET", u, nil) diff --git a/github/pulls.go b/github/pulls.go index ad372d453f8..4ac62a83739 100644 --- a/github/pulls.go +++ b/github/pulls.go @@ -165,7 +165,7 @@ func (s *PullRequestsService) List(ctx context.Context, owner string, repo strin // // 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 +// GitHub API docs: https://developer.github.com/v3/repos/commits/#list-pull-requests-associated-with-a-commit func (s *PullRequestsService) ListPullRequestsWithCommit(ctx context.Context, owner, repo, sha string, opts *PullRequestListOptions) ([]*PullRequest, *Response, error) { u := fmt.Sprintf("repos/%v/%v/commits/%v/pulls", owner, repo, sha) u, err := addOptions(u, opts) @@ -192,7 +192,7 @@ func (s *PullRequestsService) ListPullRequestsWithCommit(ctx context.Context, ow // Get a single pull request. // -// GitHub API docs: https://developer.github.com/v3/pulls/#get-a-single-pull-request +// GitHub API docs: https://developer.github.com/v3/pulls/#get-a-pull-request func (s *PullRequestsService) Get(ctx context.Context, owner string, repo string, number int) (*PullRequest, *Response, error) { u := fmt.Sprintf("repos/%v/%v/pulls/%d", owner, repo, number) req, err := s.client.NewRequest("GET", u, nil) @@ -215,7 +215,7 @@ func (s *PullRequestsService) Get(ctx context.Context, owner string, repo string // GetRaw gets a single pull request in raw (diff or patch) format. // -// GitHub API docs: https://developer.github.com/v3/pulls/#get-a-single-pull-request +// GitHub API docs: https://developer.github.com/v3/pulls/#get-a-pull-request func (s *PullRequestsService) GetRaw(ctx context.Context, owner string, repo string, number int, opts RawOptions) (string, *Response, error) { u := fmt.Sprintf("repos/%v/%v/pulls/%d", owner, repo, number) req, err := s.client.NewRequest("GET", u, nil) @@ -417,7 +417,7 @@ func (s *PullRequestsService) ListFiles(ctx context.Context, owner string, repo // IsMerged checks if a pull request has been merged. // -// GitHub API docs: https://developer.github.com/v3/pulls/#get-if-a-pull-request-has-been-merged +// GitHub API docs: https://developer.github.com/v3/pulls/#check-if-a-pull-request-has-been-merged func (s *PullRequestsService) IsMerged(ctx context.Context, owner string, repo string, number int) (bool, *Response, error) { u := fmt.Sprintf("repos/%v/%v/pulls/%d/merge", owner, repo, number) req, err := s.client.NewRequest("GET", u, nil) diff --git a/github/pulls_comments.go b/github/pulls_comments.go index 741454aeefb..13de971b4a1 100644 --- a/github/pulls_comments.go +++ b/github/pulls_comments.go @@ -66,8 +66,8 @@ type PullRequestListCommentsOptions struct { // pull request number of 0 will return all comments on all pull requests for // the repository. // -// GitHub API docs: https://developer.github.com/v3/pulls/comments/#list-comments-in-a-repository -// GitHub API docs: https://developer.github.com/v3/pulls/comments/#list-comments-on-a-pull-request +// GitHub API docs: https://developer.github.com/v3/pulls/comments/#list-review-comments-on-a-pull-request +// GitHub API docs: https://developer.github.com/v3/pulls/comments/#list-review-comments-in-a-repository func (s *PullRequestsService) ListComments(ctx context.Context, owner string, repo string, number int, opts *PullRequestListCommentsOptions) ([]*PullRequestComment, *Response, error) { var u string if number == 0 { @@ -100,7 +100,7 @@ func (s *PullRequestsService) ListComments(ctx context.Context, owner string, re // GetComment fetches the specified pull request comment. // -// GitHub API docs: https://developer.github.com/v3/pulls/comments/#get-a-single-comment +// GitHub API docs: https://developer.github.com/v3/pulls/comments/#get-a-review-comment-for-a-pull-request func (s *PullRequestsService) GetComment(ctx context.Context, owner string, repo string, commentID int64) (*PullRequestComment, *Response, error) { u := fmt.Sprintf("repos/%v/%v/pulls/comments/%d", owner, repo, commentID) req, err := s.client.NewRequest("GET", u, nil) @@ -123,7 +123,7 @@ func (s *PullRequestsService) GetComment(ctx context.Context, owner string, repo // CreateComment creates a new comment on the specified pull request. // -// GitHub API docs: https://developer.github.com/v3/pulls/comments/#create-a-comment +// GitHub API docs: https://developer.github.com/v3/pulls/comments/#create-a-review-comment-for-a-pull-request func (s *PullRequestsService) CreateComment(ctx context.Context, owner string, repo string, number int, comment *PullRequestComment) (*PullRequestComment, *Response, error) { u := fmt.Sprintf("repos/%v/%v/pulls/%d/comments", owner, repo, number) req, err := s.client.NewRequest("POST", u, comment) @@ -145,7 +145,7 @@ func (s *PullRequestsService) CreateComment(ctx context.Context, owner string, r // CreateCommentInReplyTo creates a new comment as a reply to an existing pull request comment. // -// GitHub API docs: https://developer.github.com/v3/pulls/comments/#create-a-comment +// GitHub API docs: https://developer.github.com/v3/pulls/comments/#create-a-review-comment-for-a-pull-request func (s *PullRequestsService) CreateCommentInReplyTo(ctx context.Context, owner string, repo string, number int, body string, commentID int64) (*PullRequestComment, *Response, error) { comment := &struct { Body string `json:"body,omitempty"` @@ -172,7 +172,7 @@ func (s *PullRequestsService) CreateCommentInReplyTo(ctx context.Context, owner // EditComment updates a pull request comment. // A non-nil comment.Body must be provided. Other comment fields should be left nil. // -// GitHub API docs: https://developer.github.com/v3/pulls/comments/#edit-a-comment +// GitHub API docs: https://developer.github.com/v3/pulls/comments/#update-a-review-comment-for-a-pull-request func (s *PullRequestsService) EditComment(ctx context.Context, owner string, repo string, commentID int64, comment *PullRequestComment) (*PullRequestComment, *Response, error) { u := fmt.Sprintf("repos/%v/%v/pulls/comments/%d", owner, repo, commentID) req, err := s.client.NewRequest("PATCH", u, comment) @@ -191,7 +191,7 @@ func (s *PullRequestsService) EditComment(ctx context.Context, owner string, rep // DeleteComment deletes a pull request comment. // -// GitHub API docs: https://developer.github.com/v3/pulls/comments/#delete-a-comment +// GitHub API docs: https://developer.github.com/v3/pulls/comments/#delete-a-review-comment-for-a-pull-request func (s *PullRequestsService) DeleteComment(ctx context.Context, owner string, repo string, commentID int64) (*Response, error) { u := fmt.Sprintf("repos/%v/%v/pulls/comments/%d", owner, repo, commentID) req, err := s.client.NewRequest("DELETE", u, nil) diff --git a/github/pulls_reviewers.go b/github/pulls_reviewers.go index 368f9680a8b..510dfb83000 100644 --- a/github/pulls_reviewers.go +++ b/github/pulls_reviewers.go @@ -25,7 +25,7 @@ type Reviewers struct { // RequestReviewers creates a review request for the provided reviewers for the specified pull request. // -// GitHub API docs: https://developer.github.com/v3/pulls/review_requests/#create-a-review-request +// GitHub API docs: https://developer.github.com/v3/pulls/review_requests/#request-reviewers-for-a-pull-request func (s *PullRequestsService) RequestReviewers(ctx context.Context, owner, repo string, number int, reviewers ReviewersRequest) (*PullRequest, *Response, error) { u := fmt.Sprintf("repos/%s/%s/pulls/%d/requested_reviewers", owner, repo, number) req, err := s.client.NewRequest("POST", u, &reviewers) @@ -44,7 +44,7 @@ func (s *PullRequestsService) RequestReviewers(ctx context.Context, owner, repo // ListReviewers lists reviewers whose reviews have been requested on the specified pull request. // -// GitHub API docs: https://developer.github.com/v3/pulls/review_requests/#list-review-requests +// GitHub API docs: https://developer.github.com/v3/pulls/review_requests/#list-requested-reviewers-for-a-pull-request func (s *PullRequestsService) ListReviewers(ctx context.Context, owner, repo string, number int, opts *ListOptions) (*Reviewers, *Response, error) { u := fmt.Sprintf("repos/%v/%v/pulls/%d/requested_reviewers", owner, repo, number) u, err := addOptions(u, opts) @@ -68,7 +68,7 @@ func (s *PullRequestsService) ListReviewers(ctx context.Context, owner, repo str // RemoveReviewers removes the review request for the provided reviewers for the specified pull request. // -// GitHub API docs: https://developer.github.com/v3/pulls/review_requests/#delete-a-review-request +// GitHub API docs: https://developer.github.com/v3/pulls/review_requests/#remove-requested-reviewers-from-a-pull-request func (s *PullRequestsService) RemoveReviewers(ctx context.Context, owner, repo string, number int, reviewers ReviewersRequest) (*Response, error) { u := fmt.Sprintf("repos/%s/%s/pulls/%d/requested_reviewers", owner, repo, number) req, err := s.client.NewRequest("DELETE", u, &reviewers) diff --git a/github/pulls_reviews.go b/github/pulls_reviews.go index 42af0a0b8a3..30a4585cbb5 100644 --- a/github/pulls_reviews.go +++ b/github/pulls_reviews.go @@ -105,7 +105,7 @@ func (r PullRequestReviewDismissalRequest) String() string { // returned error format and remove this comment once it's fixed. // Read more about it here - https://github.com/google/go-github/issues/540 // -// GitHub API docs: https://developer.github.com/v3/pulls/reviews/#list-reviews-on-a-pull-request +// GitHub API docs: https://developer.github.com/v3/pulls/reviews/#list-reviews-for-a-pull-request func (s *PullRequestsService) ListReviews(ctx context.Context, owner, repo string, number int, opts *ListOptions) ([]*PullRequestReview, *Response, error) { u := fmt.Sprintf("repos/%v/%v/pulls/%d/reviews", owner, repo, number) u, err := addOptions(u, opts) @@ -133,7 +133,7 @@ func (s *PullRequestsService) ListReviews(ctx context.Context, owner, repo strin // returned error format and remove this comment once it's fixed. // Read more about it here - https://github.com/google/go-github/issues/540 // -// GitHub API docs: https://developer.github.com/v3/pulls/reviews/#get-a-single-review +// GitHub API docs: https://developer.github.com/v3/pulls/reviews/#get-a-review-for-a-pull-request func (s *PullRequestsService) GetReview(ctx context.Context, owner, repo string, number int, reviewID int64) (*PullRequestReview, *Response, error) { u := fmt.Sprintf("repos/%v/%v/pulls/%d/reviews/%d", owner, repo, number, reviewID) @@ -157,7 +157,7 @@ func (s *PullRequestsService) GetReview(ctx context.Context, owner, repo string, // returned error format and remove this comment once it's fixed. // Read more about it here - https://github.com/google/go-github/issues/540 // -// GitHub API docs: https://developer.github.com/v3/pulls/reviews/#delete-a-pending-review +// GitHub API docs: https://developer.github.com/v3/pulls/reviews/#delete-a-pending-review-for-a-pull-request func (s *PullRequestsService) DeletePendingReview(ctx context.Context, owner, repo string, number int, reviewID int64) (*PullRequestReview, *Response, error) { u := fmt.Sprintf("repos/%v/%v/pulls/%d/reviews/%d", owner, repo, number, reviewID) @@ -181,7 +181,7 @@ func (s *PullRequestsService) DeletePendingReview(ctx context.Context, owner, re // returned error format and remove this comment once it's fixed. // Read more about it here - https://github.com/google/go-github/issues/540 // -// GitHub API docs: https://developer.github.com/v3/pulls/reviews/#get-comments-for-a-single-review +// GitHub API docs: https://developer.github.com/v3/pulls/reviews/#list-comments-for-a-pull-request-review func (s *PullRequestsService) ListReviewComments(ctx context.Context, owner, repo string, number int, reviewID int64, opts *ListOptions) ([]*PullRequestComment, *Response, error) { u := fmt.Sprintf("repos/%v/%v/pulls/%d/reviews/%d/comments", owner, repo, number, reviewID) u, err := addOptions(u, opts) @@ -209,7 +209,7 @@ func (s *PullRequestsService) ListReviewComments(ctx context.Context, owner, rep // returned error format and remove this comment once it's fixed. // Read more about it here - https://github.com/google/go-github/issues/540 // -// GitHub API docs: https://developer.github.com/v3/pulls/reviews/#create-a-pull-request-review +// GitHub API docs: https://developer.github.com/v3/pulls/reviews/#create-a-review-for-a-pull-request // // In order to use multi-line comments, you must use the "comfort fade" preview. // This replaces the use of the "Position" field in comments with 4 new fields: @@ -270,7 +270,7 @@ func (s *PullRequestsService) CreateReview(ctx context.Context, owner, repo stri // UpdateReview updates the review summary on the specified pull request. // -// GitHub API docs: https://developer.github.com/v3/pulls/reviews/#update-a-pull-request-review +// GitHub API docs: https://developer.github.com/v3/pulls/reviews/#update-a-review-for-a-pull-request func (s *PullRequestsService) UpdateReview(ctx context.Context, owner, repo string, number int, reviewID int64, body string) (*PullRequestReview, *Response, error) { opts := &struct { Body string `json:"body"` @@ -297,7 +297,7 @@ func (s *PullRequestsService) UpdateReview(ctx context.Context, owner, repo stri // returned error format and remove this comment once it's fixed. // Read more about it here - https://github.com/google/go-github/issues/540 // -// GitHub API docs: https://developer.github.com/v3/pulls/reviews/#submit-a-pull-request-review +// GitHub API docs: https://developer.github.com/v3/pulls/reviews/#submit-a-review-for-a-pull-request func (s *PullRequestsService) SubmitReview(ctx context.Context, owner, repo string, number int, reviewID int64, review *PullRequestReviewRequest) (*PullRequestReview, *Response, error) { u := fmt.Sprintf("repos/%v/%v/pulls/%d/reviews/%d/events", owner, repo, number, reviewID) @@ -321,7 +321,7 @@ func (s *PullRequestsService) SubmitReview(ctx context.Context, owner, repo stri // returned error format and remove this comment once it's fixed. // Read more about it here - https://github.com/google/go-github/issues/540 // -// GitHub API docs: https://developer.github.com/v3/pulls/reviews/#dismiss-a-pull-request-review +// GitHub API docs: https://developer.github.com/v3/pulls/reviews/#dismiss-a-review-for-a-pull-request func (s *PullRequestsService) DismissReview(ctx context.Context, owner, repo string, number int, reviewID int64, review *PullRequestReviewDismissalRequest) (*PullRequestReview, *Response, error) { u := fmt.Sprintf("repos/%v/%v/pulls/%d/reviews/%d/dismissals", owner, repo, number, reviewID) diff --git a/github/repos.go b/github/repos.go index b8c8166b509..156e6e3ec44 100644 --- a/github/repos.go +++ b/github/repos.go @@ -435,7 +435,7 @@ func (s *RepositoriesService) Get(ctx context.Context, owner, repo string) (*Rep // GetCodeOfConduct gets the contents of a repository's code of conduct. // -// GitHub API docs: https://developer.github.com/v3/codes_of_conduct/#get-the-contents-of-a-repositorys-code-of-conduct +// GitHub API docs: https://developer.github.com/v3/codes_of_conduct/#get-the-code-of-conduct-for-a-repository func (s *RepositoriesService) GetCodeOfConduct(ctx context.Context, owner, repo string) (*CodeOfConduct, *Response, error) { u := fmt.Sprintf("repos/%v/%v/community/code_of_conduct", owner, repo) req, err := s.client.NewRequest("GET", u, nil) @@ -630,7 +630,7 @@ func (s *RepositoriesService) DisableAutomatedSecurityFixes(ctx context.Context, // ListContributors lists contributors for a repository. // -// GitHub API docs: https://developer.github.com/v3/repos/#list-contributors +// GitHub API docs: https://developer.github.com/v3/repos/#list-repository-contributors func (s *RepositoriesService) ListContributors(ctx context.Context, owner string, repository string, opts *ListContributorsOptions) ([]*Contributor, *Response, error) { u := fmt.Sprintf("repos/%v/%v/contributors", owner, repository) u, err := addOptions(u, opts) @@ -661,7 +661,7 @@ func (s *RepositoriesService) ListContributors(ctx context.Context, owner string // "Python": 7769 // } // -// GitHub API docs: https://developer.github.com/v3/repos/#list-languages +// GitHub API docs: https://developer.github.com/v3/repos/#list-repository-languages func (s *RepositoriesService) ListLanguages(ctx context.Context, owner string, repo string) (map[string]int, *Response, error) { u := fmt.Sprintf("repos/%v/%v/languages", owner, repo) req, err := s.client.NewRequest("GET", u, nil) @@ -680,7 +680,7 @@ func (s *RepositoriesService) ListLanguages(ctx context.Context, owner string, r // ListTeams lists the teams for the specified repository. // -// GitHub API docs: https://developer.github.com/v3/repos/#list-teams +// GitHub API docs: https://developer.github.com/v3/repos/#list-repository-teams func (s *RepositoriesService) ListTeams(ctx context.Context, owner string, repo string, opts *ListOptions) ([]*Team, *Response, error) { u := fmt.Sprintf("repos/%v/%v/teams", owner, repo) u, err := addOptions(u, opts) @@ -712,7 +712,7 @@ type RepositoryTag struct { // ListTags lists tags for the specified repository. // -// GitHub API docs: https://developer.github.com/v3/repos/#list-tags +// GitHub API docs: https://developer.github.com/v3/repos/#list-repository-tags func (s *RepositoriesService) ListTags(ctx context.Context, owner string, repo string, opts *ListOptions) ([]*RepositoryTag, *Response, error) { u := fmt.Sprintf("repos/%v/%v/tags", owner, repo) u, err := addOptions(u, opts) @@ -927,7 +927,7 @@ func (s *RepositoriesService) ListBranches(ctx context.Context, owner string, re // GetBranch gets the specified branch for a repository. // -// GitHub API docs: https://developer.github.com/v3/repos/branches/#get-branch +// GitHub API docs: https://developer.github.com/v3/repos/branches/#get-a-branch func (s *RepositoriesService) GetBranch(ctx context.Context, owner, repo, branch string) (*Branch, *Response, error) { u := fmt.Sprintf("repos/%v/%v/branches/%v", owner, repo, branch) req, err := s.client.NewRequest("GET", u, nil) @@ -971,7 +971,7 @@ func (s *RepositoriesService) GetBranchProtection(ctx context.Context, owner, re // GetRequiredStatusChecks gets the required status checks for a given protected branch. // -// GitHub API docs: https://developer.github.com/v3/repos/branches/#get-required-status-checks-of-protected-branch +// GitHub API docs: https://developer.github.com/v3/repos/branches/#get-status-checks-protection func (s *RepositoriesService) GetRequiredStatusChecks(ctx context.Context, owner, repo, branch string) (*RequiredStatusChecks, *Response, error) { u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/required_status_checks", owner, repo, branch) req, err := s.client.NewRequest("GET", u, nil) @@ -993,7 +993,7 @@ func (s *RepositoriesService) GetRequiredStatusChecks(ctx context.Context, owner // ListRequiredStatusChecksContexts lists the required status checks contexts for a given protected branch. // -// GitHub API docs: https://developer.github.com/v3/repos/branches/#list-required-status-checks-contexts-of-protected-branch +// GitHub API docs: https://developer.github.com/v3/repos/branches/#get-all-status-check-contexts func (s *RepositoriesService) ListRequiredStatusChecksContexts(ctx context.Context, owner, repo, branch string) (contexts []string, resp *Response, err error) { u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/required_status_checks/contexts", owner, repo, branch) req, err := s.client.NewRequest("GET", u, nil) @@ -1036,7 +1036,7 @@ func (s *RepositoriesService) UpdateBranchProtection(ctx context.Context, owner, // RemoveBranchProtection removes the protection of a given branch. // -// GitHub API docs: https://developer.github.com/v3/repos/branches/#remove-branch-protection +// GitHub API docs: https://developer.github.com/v3/repos/branches/#delete-branch-protection func (s *RepositoriesService) RemoveBranchProtection(ctx context.Context, owner, repo, branch string) (*Response, error) { u := fmt.Sprintf("repos/%v/%v/branches/%v/protection", owner, repo, branch) req, err := s.client.NewRequest("DELETE", u, nil) @@ -1052,7 +1052,7 @@ func (s *RepositoriesService) RemoveBranchProtection(ctx context.Context, owner, // GetSignaturesProtectedBranch gets required signatures of protected branch. // -// GitHub API docs: https://developer.github.com/v3/repos/branches/#get-required-signatures-of-protected-branch +// GitHub API docs: https://developer.github.com/v3/repos/branches/#get-commit-signature-protection func (s *RepositoriesService) GetSignaturesProtectedBranch(ctx context.Context, owner, repo, branch string) (*SignaturesProtectedBranch, *Response, error) { u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/required_signatures", owner, repo, branch) req, err := s.client.NewRequest("GET", u, nil) @@ -1075,7 +1075,7 @@ func (s *RepositoriesService) GetSignaturesProtectedBranch(ctx context.Context, // RequireSignaturesOnProtectedBranch makes signed commits required on a protected branch. // It requires admin access and branch protection to be enabled. // -// GitHub API docs: https://developer.github.com/v3/repos/branches/#add-required-signatures-of-protected-branch +// GitHub API docs: https://developer.github.com/v3/repos/branches/#create-commit-signature-protection func (s *RepositoriesService) RequireSignaturesOnProtectedBranch(ctx context.Context, owner, repo, branch string) (*SignaturesProtectedBranch, *Response, error) { u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/required_signatures", owner, repo, branch) req, err := s.client.NewRequest("POST", u, nil) @@ -1097,7 +1097,7 @@ func (s *RepositoriesService) RequireSignaturesOnProtectedBranch(ctx context.Con // OptionalSignaturesOnProtectedBranch removes required signed commits on a given branch. // -// GitHub API docs: https://developer.github.com/v3/repos/branches/#remove-required-signatures-of-protected-branch +// GitHub API docs: https://developer.github.com/v3/repos/branches/#delete-commit-signature-protection func (s *RepositoriesService) OptionalSignaturesOnProtectedBranch(ctx context.Context, owner, repo, branch string) (*Response, error) { u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/required_signatures", owner, repo, branch) req, err := s.client.NewRequest("DELETE", u, nil) @@ -1113,7 +1113,7 @@ func (s *RepositoriesService) OptionalSignaturesOnProtectedBranch(ctx context.Co // UpdateRequiredStatusChecks updates the required status checks for a given protected branch. // -// GitHub API docs: https://developer.github.com/v3/repos/branches/#update-required-status-checks-of-protected-branch +// GitHub API docs: https://developer.github.com/v3/repos/branches/#update-status-check-potection func (s *RepositoriesService) UpdateRequiredStatusChecks(ctx context.Context, owner, repo, branch string, sreq *RequiredStatusChecksRequest) (*RequiredStatusChecks, *Response, error) { u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/required_status_checks", owner, repo, branch) req, err := s.client.NewRequest("PATCH", u, sreq) @@ -1132,7 +1132,7 @@ func (s *RepositoriesService) UpdateRequiredStatusChecks(ctx context.Context, ow // License gets the contents of a repository's license if one is detected. // -// GitHub API docs: https://developer.github.com/v3/licenses/#get-the-contents-of-a-repositorys-license +// GitHub API docs: https://developer.github.com/v3/licenses/#get-the-license-for-a-repository func (s *RepositoriesService) License(ctx context.Context, owner, repo string) (*RepositoryLicense, *Response, error) { u := fmt.Sprintf("repos/%v/%v/license", owner, repo) req, err := s.client.NewRequest("GET", u, nil) @@ -1151,7 +1151,7 @@ func (s *RepositoriesService) License(ctx context.Context, owner, repo string) ( // GetPullRequestReviewEnforcement gets pull request review enforcement of a protected branch. // -// GitHub API docs: https://developer.github.com/v3/repos/branches/#get-pull-request-review-enforcement-of-protected-branch +// GitHub API docs: https://developer.github.com/v3/repos/branches/#get-pull-request-review-protection func (s *RepositoriesService) GetPullRequestReviewEnforcement(ctx context.Context, owner, repo, branch string) (*PullRequestReviewsEnforcement, *Response, error) { u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/required_pull_request_reviews", owner, repo, branch) req, err := s.client.NewRequest("GET", u, nil) @@ -1174,7 +1174,7 @@ func (s *RepositoriesService) GetPullRequestReviewEnforcement(ctx context.Contex // UpdatePullRequestReviewEnforcement patches pull request review enforcement of a protected branch. // It requires admin access and branch protection to be enabled. // -// GitHub API docs: https://developer.github.com/v3/repos/branches/#update-pull-request-review-enforcement-of-protected-branch +// GitHub API docs: https://developer.github.com/v3/repos/branches/#update-pull-request-review-protection func (s *RepositoriesService) UpdatePullRequestReviewEnforcement(ctx context.Context, owner, repo, branch string, patch *PullRequestReviewsEnforcementUpdate) (*PullRequestReviewsEnforcement, *Response, error) { u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/required_pull_request_reviews", owner, repo, branch) req, err := s.client.NewRequest("PATCH", u, patch) @@ -1197,7 +1197,7 @@ func (s *RepositoriesService) UpdatePullRequestReviewEnforcement(ctx context.Con // DisableDismissalRestrictions disables dismissal restrictions of a protected branch. // It requires admin access and branch protection to be enabled. // -// GitHub API docs: https://developer.github.com/v3/repos/branches/#update-pull-request-review-enforcement-of-protected-branch +// GitHub API docs: https://developer.github.com/v3/repos/branches/#update-pull-request-review-protection func (s *RepositoriesService) DisableDismissalRestrictions(ctx context.Context, owner, repo, branch string) (*PullRequestReviewsEnforcement, *Response, error) { u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/required_pull_request_reviews", owner, repo, branch) @@ -1224,7 +1224,7 @@ func (s *RepositoriesService) DisableDismissalRestrictions(ctx context.Context, // RemovePullRequestReviewEnforcement removes pull request enforcement of a protected branch. // -// GitHub API docs: https://developer.github.com/v3/repos/branches/#remove-pull-request-review-enforcement-of-protected-branch +// GitHub API docs: https://developer.github.com/v3/repos/branches/#delete-pull-request-review-protection func (s *RepositoriesService) RemovePullRequestReviewEnforcement(ctx context.Context, owner, repo, branch string) (*Response, error) { u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/required_pull_request_reviews", owner, repo, branch) req, err := s.client.NewRequest("DELETE", u, nil) @@ -1240,7 +1240,7 @@ func (s *RepositoriesService) RemovePullRequestReviewEnforcement(ctx context.Con // GetAdminEnforcement gets admin enforcement information of a protected branch. // -// GitHub API docs: https://developer.github.com/v3/repos/branches/#get-admin-enforcement-of-protected-branch +// GitHub API docs: https://developer.github.com/v3/repos/branches/#get-admin-branch-protection func (s *RepositoriesService) GetAdminEnforcement(ctx context.Context, owner, repo, branch string) (*AdminEnforcement, *Response, error) { u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/enforce_admins", owner, repo, branch) req, err := s.client.NewRequest("GET", u, nil) @@ -1263,7 +1263,7 @@ func (s *RepositoriesService) GetAdminEnforcement(ctx context.Context, owner, re // AddAdminEnforcement adds admin enforcement to a protected branch. // It requires admin access and branch protection to be enabled. // -// GitHub API docs: https://developer.github.com/v3/repos/branches/#add-admin-enforcement-of-protected-branch +// GitHub API docs: https://developer.github.com/v3/repos/branches/#set-admin-branch-protection func (s *RepositoriesService) AddAdminEnforcement(ctx context.Context, owner, repo, branch string) (*AdminEnforcement, *Response, error) { u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/enforce_admins", owner, repo, branch) req, err := s.client.NewRequest("POST", u, nil) @@ -1285,7 +1285,7 @@ func (s *RepositoriesService) AddAdminEnforcement(ctx context.Context, owner, re // RemoveAdminEnforcement removes admin enforcement from a protected branch. // -// GitHub API docs: https://developer.github.com/v3/repos/branches/#remove-admin-enforcement-of-protected-branch +// GitHub API docs: https://developer.github.com/v3/repos/branches/#delete-admin-branch-protection func (s *RepositoriesService) RemoveAdminEnforcement(ctx context.Context, owner, repo, branch string) (*Response, error) { u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/enforce_admins", owner, repo, branch) req, err := s.client.NewRequest("DELETE", u, nil) @@ -1357,7 +1357,7 @@ func (s *RepositoriesService) ReplaceAllTopics(ctx context.Context, owner, repo // ListApps lists the Github apps that have push access to a given protected branch. // It requires the Github apps to have `write` access to the `content` permission. // -// GitHub API docs: https://developer.github.com/v3/repos/branches/#list-apps-with-access-to-protected-branch +// GitHub API docs: https://developer.github.com/v3/repos/branches/#list-apps-with-access-to-the-protected-branch func (s *RepositoriesService) ListApps(ctx context.Context, owner, repo, branch string) ([]*App, *Response, error) { u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/restrictions/apps", owner, repo, branch) req, err := s.client.NewRequest("GET", u, nil) @@ -1380,7 +1380,7 @@ func (s *RepositoriesService) ListApps(ctx context.Context, owner, repo, branch // // Note: The list of users, apps, and teams in total is limited to 100 items. // -// GitHub API docs: https://developer.github.com/v3/repos/branches/#replace-app-restrictions-of-protected-branch +// GitHub API docs: https://developer.github.com/v3/repos/branches/#set-app-access-restrictions func (s *RepositoriesService) ReplaceAppRestrictions(ctx context.Context, owner, repo, branch string, slug []string) ([]*App, *Response, error) { u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/restrictions/apps", owner, repo, branch) req, err := s.client.NewRequest("PUT", u, slug) @@ -1402,7 +1402,7 @@ func (s *RepositoriesService) ReplaceAppRestrictions(ctx context.Context, owner, // // Note: The list of users, apps, and teams in total is limited to 100 items. // -// GitHub API docs: https://developer.github.com/v3/repos/branches/#add-app-restrictions-of-protected-branch +// GitHub API docs: https://developer.github.com/v3/repos/branches/#add-app-access-restrictions func (s *RepositoriesService) AddAppRestrictions(ctx context.Context, owner, repo, branch string, slug []string) ([]*App, *Response, error) { u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/restrictions/apps", owner, repo, branch) req, err := s.client.NewRequest("POST", u, slug) @@ -1424,7 +1424,7 @@ func (s *RepositoriesService) AddAppRestrictions(ctx context.Context, owner, rep // // Note: The list of users, apps, and teams in total is limited to 100 items. // -// GitHub API docs: https://developer.github.com/v3/repos/branches/#remove-app-restrictions-of-protected-branch +// GitHub API docs: https://developer.github.com/v3/repos/branches/#remove-app-access-restrictions func (s *RepositoriesService) RemoveAppRestrictions(ctx context.Context, owner, repo, branch string, slug []string) ([]*App, *Response, error) { u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/restrictions/apps", owner, repo, branch) req, err := s.client.NewRequest("DELETE", u, slug) diff --git a/github/repos_collaborators.go b/github/repos_collaborators.go index 65a533083b7..ec8e68535b7 100644 --- a/github/repos_collaborators.go +++ b/github/repos_collaborators.go @@ -41,7 +41,7 @@ type CollaboratorInvitation struct { // ListCollaborators lists the GitHub users that have access to the repository. // -// GitHub API docs: https://developer.github.com/v3/repos/collaborators/#list-collaborators +// GitHub API docs: https://developer.github.com/v3/repos/collaborators/#list-repository-collaborators func (s *RepositoriesService) ListCollaborators(ctx context.Context, owner, repo string, opts *ListCollaboratorsOptions) ([]*User, *Response, error) { u := fmt.Sprintf("repos/%v/%v/collaborators", owner, repo) u, err := addOptions(u, opts) @@ -68,7 +68,7 @@ func (s *RepositoriesService) ListCollaborators(ctx context.Context, owner, repo // Note: This will return false if the user is not a collaborator OR the user // is not a GitHub user. // -// GitHub API docs: https://developer.github.com/v3/repos/collaborators/#check-if-a-user-is-a-collaborator +// GitHub API docs: https://developer.github.com/v3/repos/collaborators/#check-if-a-user-is-a-repository-collaborator func (s *RepositoriesService) IsCollaborator(ctx context.Context, owner, repo, user string) (bool, *Response, error) { u := fmt.Sprintf("repos/%v/%v/collaborators/%v", owner, repo, user) req, err := s.client.NewRequest("GET", u, nil) @@ -91,7 +91,7 @@ type RepositoryPermissionLevel struct { } // GetPermissionLevel retrieves the specific permission level a collaborator has for a given repository. -// GitHub API docs: https://developer.github.com/v3/repos/collaborators/#review-a-users-permission-level +// GitHub API docs: https://developer.github.com/v3/repos/collaborators/#get-repository-permissions-for-a-user func (s *RepositoriesService) GetPermissionLevel(ctx context.Context, owner, repo, user string) (*RepositoryPermissionLevel, *Response, error) { u := fmt.Sprintf("repos/%v/%v/collaborators/%v/permission", owner, repo, user) req, err := s.client.NewRequest("GET", u, nil) @@ -125,7 +125,7 @@ type RepositoryAddCollaboratorOptions struct { // AddCollaborator sends an invitation to the specified GitHub user // to become a collaborator to the given repo. // -// GitHub API docs: https://developer.github.com/v3/repos/collaborators/#add-user-as-a-collaborator +// GitHub API docs: https://developer.github.com/v3/repos/collaborators/#add-a-repository-collaborator func (s *RepositoriesService) AddCollaborator(ctx context.Context, owner, repo, user string, opts *RepositoryAddCollaboratorOptions) (*CollaboratorInvitation, *Response, error) { u := fmt.Sprintf("repos/%v/%v/collaborators/%v", owner, repo, user) req, err := s.client.NewRequest("PUT", u, opts) @@ -143,7 +143,7 @@ func (s *RepositoriesService) AddCollaborator(ctx context.Context, owner, repo, // RemoveCollaborator removes the specified GitHub user as collaborator from the given repo. // Note: Does not return error if a valid user that is not a collaborator is removed. // -// GitHub API docs: https://developer.github.com/v3/repos/collaborators/#remove-user-as-a-collaborator +// GitHub API docs: https://developer.github.com/v3/repos/collaborators/#remove-a-repository-collaborator func (s *RepositoriesService) RemoveCollaborator(ctx context.Context, owner, repo, user string) (*Response, error) { u := fmt.Sprintf("repos/%v/%v/collaborators/%v", owner, repo, user) req, err := s.client.NewRequest("DELETE", u, nil) diff --git a/github/repos_comments.go b/github/repos_comments.go index 891825f965a..0ccdca37236 100644 --- a/github/repos_comments.go +++ b/github/repos_comments.go @@ -63,7 +63,7 @@ func (s *RepositoriesService) ListComments(ctx context.Context, owner, repo stri // ListCommitComments lists all the comments for a given commit SHA. // -// GitHub API docs: https://developer.github.com/v3/repos/comments/#list-comments-for-a-single-commit +// GitHub API docs: https://developer.github.com/v3/repos/comments/#list-commit-comments func (s *RepositoriesService) ListCommitComments(ctx context.Context, owner, repo, sha string, opts *ListOptions) ([]*RepositoryComment, *Response, error) { u := fmt.Sprintf("repos/%v/%v/commits/%v/comments", owner, repo, sha) u, err := addOptions(u, opts) @@ -110,7 +110,7 @@ func (s *RepositoriesService) CreateComment(ctx context.Context, owner, repo, sh // GetComment gets a single comment from a repository. // -// GitHub API docs: https://developer.github.com/v3/repos/comments/#get-a-single-commit-comment +// GitHub API docs: https://developer.github.com/v3/repos/comments/#get-a-commit-comment func (s *RepositoriesService) GetComment(ctx context.Context, owner, repo string, id int64) (*RepositoryComment, *Response, error) { u := fmt.Sprintf("repos/%v/%v/comments/%v", owner, repo, id) req, err := s.client.NewRequest("GET", u, nil) diff --git a/github/repos_commits.go b/github/repos_commits.go index 4db577085ad..07c071e0dc4 100644 --- a/github/repos_commits.go +++ b/github/repos_commits.go @@ -123,7 +123,7 @@ type BranchCommit struct { // ListCommits lists the commits of a repository. // -// GitHub API docs: https://developer.github.com/v3/repos/commits/#list-commits-on-a-repository +// GitHub API docs: https://developer.github.com/v3/repos/commits/#list-commits func (s *RepositoriesService) ListCommits(ctx context.Context, owner, repo string, opts *CommitsListOptions) ([]*RepositoryCommit, *Response, error) { u := fmt.Sprintf("repos/%v/%v/commits", owner, repo) u, err := addOptions(u, opts) @@ -148,7 +148,7 @@ func (s *RepositoriesService) ListCommits(ctx context.Context, owner, repo strin // GetCommit fetches the specified commit, including all details about it. // // GitHub API docs: https://developer.github.com/v3/repos/commits/#get-a-single-commit -// See also: https://developer.github.com/v3/git/commits/#get-a-single-commit provides the same functionality +// GitHub API docs: https://developer.github.com/v3/repos/commits/#get-a-commit func (s *RepositoriesService) GetCommit(ctx context.Context, owner, repo, sha string) (*RepositoryCommit, *Response, error) { u := fmt.Sprintf("repos/%v/%v/commits/%v", owner, repo, sha) @@ -168,7 +168,7 @@ func (s *RepositoriesService) GetCommit(ctx context.Context, owner, repo, sha st // GetCommitRaw fetches the specified commit in raw (diff or patch) format. // -// GitHub API docs: https://developer.github.com/v3/repos/commits/#get-a-single-commit +// GitHub API docs: https://developer.github.com/v3/repos/commits/#get-a-commit func (s *RepositoriesService) GetCommitRaw(ctx context.Context, owner string, repo string, sha string, opts RawOptions) (string, *Response, error) { u := fmt.Sprintf("repos/%v/%v/commits/%v", owner, repo, sha) req, err := s.client.NewRequest("GET", u, nil) @@ -197,7 +197,7 @@ func (s *RepositoriesService) GetCommitRaw(ctx context.Context, owner string, re // GetCommitSHA1 gets the SHA-1 of a commit reference. If a last-known SHA1 is // supplied and no new commits have occurred, a 304 Unmodified response is returned. // -// GitHub API docs: https://developer.github.com/v3/repos/commits/#get-a-single-commit +// GitHub API docs: https://developer.github.com/v3/repos/commits/#get-a-commit func (s *RepositoriesService) GetCommitSHA1(ctx context.Context, owner, repo, ref, lastSHA string) (string, *Response, error) { u := fmt.Sprintf("repos/%v/%v/commits/%v", owner, repo, refURLEscape(ref)) diff --git a/github/repos_community_health.go b/github/repos_community_health.go index e8775a6c15e..255c6fe7a58 100644 --- a/github/repos_community_health.go +++ b/github/repos_community_health.go @@ -38,7 +38,7 @@ type CommunityHealthMetrics struct { // GetCommunityHealthMetrics retrieves all the community health metrics for a repository. // -// GitHub API docs: https://developer.github.com/v3/repos/community/#retrieve-community-profile-metrics +// GitHub API docs: https://developer.github.com/v3/repos/community/#get-community-profile-metrics func (s *RepositoriesService) GetCommunityHealthMetrics(ctx context.Context, owner, repo string) (*CommunityHealthMetrics, *Response, error) { u := fmt.Sprintf("repos/%v/%v/community/profile", owner, repo) req, err := s.client.NewRequest("GET", u, nil) diff --git a/github/repos_contents.go b/github/repos_contents.go index 02d45a12ce0..fd895ac0eee 100644 --- a/github/repos_contents.go +++ b/github/repos_contents.go @@ -94,7 +94,7 @@ func (r *RepositoryContent) GetContent() (string, error) { // GetReadme gets the Readme file for the repository. // -// GitHub API docs: https://developer.github.com/v3/repos/contents/#get-the-readme +// GitHub API docs: https://developer.github.com/v3/repos/contents/#get-a-repository-readme func (s *RepositoriesService) GetReadme(ctx context.Context, owner, repo string, opts *RepositoryContentGetOptions) (*RepositoryContent, *Response, error) { u := fmt.Sprintf("repos/%v/%v/readme", owner, repo) u, err := addOptions(u, opts) @@ -146,7 +146,7 @@ func (s *RepositoriesService) DownloadContents(ctx context.Context, owner, repo, // as possible, both result types will be returned but only one will contain a // value and the other will be nil. // -// GitHub API docs: https://developer.github.com/v3/repos/contents/#get-contents +// GitHub API docs: https://developer.github.com/v3/repos/contents/#get-repository-content func (s *RepositoriesService) GetContents(ctx context.Context, owner, repo, path string, opts *RepositoryContentGetOptions) (fileContent *RepositoryContent, directoryContent []*RepositoryContent, resp *Response, err error) { escapedPath := (&url.URL{Path: path}).String() u := fmt.Sprintf("repos/%s/%s/contents/%s", owner, repo, escapedPath) @@ -177,7 +177,7 @@ func (s *RepositoriesService) GetContents(ctx context.Context, owner, repo, path // CreateFile creates a new file in a repository at the given path and returns // the commit and file metadata. // -// GitHub API docs: https://developer.github.com/v3/repos/contents/#create-or-update-a-file +// GitHub API docs: https://developer.github.com/v3/repos/contents/#create-or-update-file-contents func (s *RepositoriesService) CreateFile(ctx context.Context, owner, repo, path string, opts *RepositoryContentFileOptions) (*RepositoryContentResponse, *Response, error) { u := fmt.Sprintf("repos/%s/%s/contents/%s", owner, repo, path) req, err := s.client.NewRequest("PUT", u, opts) @@ -195,7 +195,7 @@ func (s *RepositoriesService) CreateFile(ctx context.Context, owner, repo, path // UpdateFile updates a file in a repository at the given path and returns the // commit and file metadata. Requires the blob SHA of the file being updated. // -// GitHub API docs: https://developer.github.com/v3/repos/contents/#create-or-update-a-file +// GitHub API docs: https://developer.github.com/v3/repos/contents/#create-or-update-file-contents func (s *RepositoriesService) UpdateFile(ctx context.Context, owner, repo, path string, opts *RepositoryContentFileOptions) (*RepositoryContentResponse, *Response, error) { u := fmt.Sprintf("repos/%s/%s/contents/%s", owner, repo, path) req, err := s.client.NewRequest("PUT", u, opts) diff --git a/github/repos_deployments.go b/github/repos_deployments.go index 3caa9730e8a..648c7506703 100644 --- a/github/repos_deployments.go +++ b/github/repos_deployments.go @@ -87,7 +87,7 @@ func (s *RepositoriesService) ListDeployments(ctx context.Context, owner, repo s // GetDeployment returns a single deployment of a repository. // -// GitHub API docs: https://developer.github.com/v3/repos/deployments/#get-a-single-deployment +// GitHub API docs: https://developer.github.com/v3/repos/deployments/#get-a-deployment func (s *RepositoriesService) GetDeployment(ctx context.Context, owner, repo string, deploymentID int64) (*Deployment, *Response, error) { u := fmt.Sprintf("repos/%v/%v/deployments/%v", owner, repo, deploymentID) @@ -203,7 +203,7 @@ func (s *RepositoriesService) ListDeploymentStatuses(ctx context.Context, owner, // GetDeploymentStatus returns a single deployment status of a repository. // -// GitHub API docs: https://developer.github.com/v3/repos/deployments/#get-a-single-deployment-status +// GitHub API docs: https://developer.github.com/v3/repos/deployments/#get-a-deployment-status func (s *RepositoriesService) GetDeploymentStatus(ctx context.Context, owner, repo string, deploymentID, deploymentStatusID int64) (*DeploymentStatus, *Response, error) { u := fmt.Sprintf("repos/%v/%v/deployments/%v/statuses/%v", owner, repo, deploymentID, deploymentStatusID) diff --git a/github/repos_hooks.go b/github/repos_hooks.go index d81e74c9cf9..5c64027a915 100644 --- a/github/repos_hooks.go +++ b/github/repos_hooks.go @@ -104,7 +104,7 @@ type createHookRequest struct { // Note that only a subset of the hook fields are used and hook must // not be nil. // -// GitHub API docs: https://developer.github.com/v3/repos/hooks/#create-a-hook +// GitHub API docs: https://developer.github.com/v3/repos/hooks/#create-a-repository-webhook func (s *RepositoriesService) CreateHook(ctx context.Context, owner, repo string, hook *Hook) (*Hook, *Response, error) { u := fmt.Sprintf("repos/%v/%v/hooks", owner, repo) @@ -131,7 +131,7 @@ func (s *RepositoriesService) CreateHook(ctx context.Context, owner, repo string // ListHooks lists all Hooks for the specified repository. // -// GitHub API docs: https://developer.github.com/v3/repos/hooks/#list-hooks +// GitHub API docs: https://developer.github.com/v3/repos/hooks/#list-repository-webhooks func (s *RepositoriesService) ListHooks(ctx context.Context, owner, repo string, opts *ListOptions) ([]*Hook, *Response, error) { u := fmt.Sprintf("repos/%v/%v/hooks", owner, repo) u, err := addOptions(u, opts) @@ -155,7 +155,7 @@ func (s *RepositoriesService) ListHooks(ctx context.Context, owner, repo string, // GetHook returns a single specified Hook. // -// GitHub API docs: https://developer.github.com/v3/repos/hooks/#get-single-hook +// GitHub API docs: https://developer.github.com/v3/repos/hooks/#get-a-repository-webhook func (s *RepositoriesService) GetHook(ctx context.Context, owner, repo string, id int64) (*Hook, *Response, error) { u := fmt.Sprintf("repos/%v/%v/hooks/%d", owner, repo, id) req, err := s.client.NewRequest("GET", u, nil) @@ -173,7 +173,7 @@ func (s *RepositoriesService) GetHook(ctx context.Context, owner, repo string, i // EditHook updates a specified Hook. // -// GitHub API docs: https://developer.github.com/v3/repos/hooks/#edit-a-hook +// GitHub API docs: https://developer.github.com/v3/repos/hooks/#update-a-repository-webhook func (s *RepositoriesService) EditHook(ctx context.Context, owner, repo string, id int64, hook *Hook) (*Hook, *Response, error) { u := fmt.Sprintf("repos/%v/%v/hooks/%d", owner, repo, id) req, err := s.client.NewRequest("PATCH", u, hook) @@ -191,7 +191,7 @@ func (s *RepositoriesService) EditHook(ctx context.Context, owner, repo string, // DeleteHook deletes a specified Hook. // -// GitHub API docs: https://developer.github.com/v3/repos/hooks/#delete-a-hook +// GitHub API docs: https://developer.github.com/v3/repos/hooks/#delete-a-repository-webhook func (s *RepositoriesService) DeleteHook(ctx context.Context, owner, repo string, id int64) (*Response, error) { u := fmt.Sprintf("repos/%v/%v/hooks/%d", owner, repo, id) req, err := s.client.NewRequest("DELETE", u, nil) @@ -203,7 +203,7 @@ func (s *RepositoriesService) DeleteHook(ctx context.Context, owner, repo string // PingHook triggers a 'ping' event to be sent to the Hook. // -// GitHub API docs: https://developer.github.com/v3/repos/hooks/#ping-a-hook +// GitHub API docs: https://developer.github.com/v3/repos/hooks/#ping-a-repository-webhook func (s *RepositoriesService) PingHook(ctx context.Context, owner, repo string, id int64) (*Response, error) { u := fmt.Sprintf("repos/%v/%v/hooks/%d/pings", owner, repo, id) req, err := s.client.NewRequest("POST", u, nil) @@ -215,7 +215,7 @@ func (s *RepositoriesService) PingHook(ctx context.Context, owner, repo string, // TestHook triggers a test Hook by github. // -// GitHub API docs: https://developer.github.com/v3/repos/hooks/#test-a-push-hook +// GitHub API docs: https://developer.github.com/v3/repos/hooks/#test-the-push-repository-webhook func (s *RepositoriesService) TestHook(ctx context.Context, owner, repo string, id int64) (*Response, error) { u := fmt.Sprintf("repos/%v/%v/hooks/%d/tests", owner, repo, id) req, err := s.client.NewRequest("POST", u, nil) diff --git a/github/repos_invitations.go b/github/repos_invitations.go index 6e76f2d579d..98d72a85558 100644 --- a/github/repos_invitations.go +++ b/github/repos_invitations.go @@ -27,7 +27,7 @@ type RepositoryInvitation struct { // ListInvitations lists all currently-open repository invitations. // -// GitHub API docs: https://developer.github.com/v3/repos/invitations/#list-invitations-for-a-repository +// GitHub API docs: https://developer.github.com/v3/repos/invitations/#list-repository-invitations func (s *RepositoriesService) ListInvitations(ctx context.Context, owner, repo string, opts *ListOptions) ([]*RepositoryInvitation, *Response, error) { u := fmt.Sprintf("repos/%v/%v/invitations", owner, repo) u, err := addOptions(u, opts) diff --git a/github/repos_keys.go b/github/repos_keys.go index 0eefd3dd96f..d35e6027b19 100644 --- a/github/repos_keys.go +++ b/github/repos_keys.go @@ -58,7 +58,7 @@ func (s *RepositoriesService) GetKey(ctx context.Context, owner string, repo str // CreateKey adds a deploy key for a repository. // -// GitHub API docs: https://developer.github.com/v3/repos/keys/#add-a-new-deploy-key +// GitHub API docs: https://developer.github.com/v3/repos/keys/#create-a-deploy-key func (s *RepositoriesService) CreateKey(ctx context.Context, owner string, repo string, key *Key) (*Key, *Response, error) { u := fmt.Sprintf("repos/%v/%v/keys", owner, repo) @@ -78,7 +78,7 @@ func (s *RepositoriesService) CreateKey(ctx context.Context, owner string, repo // DeleteKey deletes a deploy key. // -// GitHub API docs: https://developer.github.com/v3/repos/keys/#remove-a-deploy-key +// GitHub API docs: https://developer.github.com/v3/repos/keys/#delete-a-deploy-key func (s *RepositoriesService) DeleteKey(ctx context.Context, owner string, repo string, id int64) (*Response, error) { u := fmt.Sprintf("repos/%v/%v/keys/%v", owner, repo, id) diff --git a/github/repos_merging.go b/github/repos_merging.go index 04383c1ae32..b0a5dd08798 100644 --- a/github/repos_merging.go +++ b/github/repos_merging.go @@ -20,7 +20,7 @@ type RepositoryMergeRequest struct { // Merge a branch in the specified repository. // -// GitHub API docs: https://developer.github.com/v3/repos/merging/#perform-a-merge +// GitHub API docs: https://developer.github.com/v3/repos/merging/#merge-a-branch func (s *RepositoriesService) Merge(ctx context.Context, owner, repo string, request *RepositoryMergeRequest) (*RepositoryCommit, *Response, error) { u := fmt.Sprintf("repos/%v/%v/merges", owner, repo) req, err := s.client.NewRequest("POST", u, request) diff --git a/github/repos_pages.go b/github/repos_pages.go index bdbd84b6c04..8a3bc5ae378 100644 --- a/github/repos_pages.go +++ b/github/repos_pages.go @@ -51,7 +51,7 @@ type createPagesRequest struct { // EnablePages enables GitHub Pages for the named repo. // -// GitHub API docs: https://developer.github.com/v3/repos/pages/#enable-a-pages-site +// GitHub API docs: https://developer.github.com/v3/repos/pages/#create-a-github-pages-site func (s *RepositoriesService) EnablePages(ctx context.Context, owner, repo string, pages *Pages) (*Pages, *Response, error) { u := fmt.Sprintf("repos/%v/%v/pages", owner, repo) @@ -87,7 +87,7 @@ type PagesUpdate struct { // UpdatePages updates GitHub Pages for the named repo. // -// GitHub API docs: https://developer.github.com/v3/repos/pages/#update-information-about-a-pages-site +// GitHub API docs: https://developer.github.com/v3/repos/pages/#update-information-about-a-github-pages-site func (s *RepositoriesService) UpdatePages(ctx context.Context, owner, repo string, opts *PagesUpdate) (*Response, error) { u := fmt.Sprintf("repos/%v/%v/pages", owner, repo) @@ -106,7 +106,7 @@ func (s *RepositoriesService) UpdatePages(ctx context.Context, owner, repo strin // DisablePages disables GitHub Pages for the named repo. // -// GitHub API docs: https://developer.github.com/v3/repos/pages/#disable-a-pages-site +// GitHub API docs: https://developer.github.com/v3/repos/pages/#delete-a-github-pages-site func (s *RepositoriesService) DisablePages(ctx context.Context, owner, repo string) (*Response, error) { u := fmt.Sprintf("repos/%v/%v/pages", owner, repo) req, err := s.client.NewRequest("DELETE", u, nil) @@ -122,7 +122,7 @@ func (s *RepositoriesService) DisablePages(ctx context.Context, owner, repo stri // GetPagesInfo fetches information about a GitHub Pages site. // -// GitHub API docs: https://developer.github.com/v3/repos/pages/#get-information-about-a-pages-site +// GitHub API docs: https://developer.github.com/v3/repos/pages/#get-a-github-pages-site func (s *RepositoriesService) GetPagesInfo(ctx context.Context, owner, repo string) (*Pages, *Response, error) { u := fmt.Sprintf("repos/%v/%v/pages", owner, repo) req, err := s.client.NewRequest("GET", u, nil) @@ -141,7 +141,7 @@ func (s *RepositoriesService) GetPagesInfo(ctx context.Context, owner, repo stri // ListPagesBuilds lists the builds for a GitHub Pages site. // -// GitHub API docs: https://developer.github.com/v3/repos/pages/#list-pages-builds +// GitHub API docs: https://developer.github.com/v3/repos/pages/#list-github-pages-builds func (s *RepositoriesService) ListPagesBuilds(ctx context.Context, owner, repo string, opts *ListOptions) ([]*PagesBuild, *Response, error) { u := fmt.Sprintf("repos/%v/%v/pages/builds", owner, repo) u, err := addOptions(u, opts) @@ -184,7 +184,7 @@ func (s *RepositoriesService) GetLatestPagesBuild(ctx context.Context, owner, re // GetPageBuild fetches the specific build information for a GitHub pages site. // -// GitHub API docs: https://developer.github.com/v3/repos/pages/#get-a-specific-pages-build +// GitHub API docs: https://developer.github.com/v3/repos/pages/#get-github-pages-build func (s *RepositoriesService) GetPageBuild(ctx context.Context, owner, repo string, id int64) (*PagesBuild, *Response, error) { u := fmt.Sprintf("repos/%v/%v/pages/builds/%v", owner, repo, id) req, err := s.client.NewRequest("GET", u, nil) @@ -203,7 +203,7 @@ func (s *RepositoriesService) GetPageBuild(ctx context.Context, owner, repo stri // RequestPageBuild requests a build of a GitHub Pages site without needing to push new commit. // -// GitHub API docs: https://developer.github.com/v3/repos/pages/#request-a-page-build +// GitHub API docs: https://developer.github.com/v3/repos/pages/#request-a-github-pages-build func (s *RepositoriesService) RequestPageBuild(ctx context.Context, owner, repo string) (*PagesBuild, *Response, error) { u := fmt.Sprintf("repos/%v/%v/pages/builds", owner, repo) req, err := s.client.NewRequest("POST", u, nil) diff --git a/github/repos_releases.go b/github/repos_releases.go index 6cd64c7ff82..de42952a612 100644 --- a/github/repos_releases.go +++ b/github/repos_releases.go @@ -68,7 +68,7 @@ func (r ReleaseAsset) String() string { // ListReleases lists the releases for a repository. // -// GitHub API docs: https://developer.github.com/v3/repos/releases/#list-releases-for-a-repository +// GitHub API docs: https://developer.github.com/v3/repos/releases/#list-releases func (s *RepositoriesService) ListReleases(ctx context.Context, owner, repo string, opts *ListOptions) ([]*RepositoryRelease, *Response, error) { u := fmt.Sprintf("repos/%s/%s/releases", owner, repo) u, err := addOptions(u, opts) @@ -91,7 +91,7 @@ func (s *RepositoriesService) ListReleases(ctx context.Context, owner, repo stri // GetRelease fetches a single release. // -// GitHub API docs: https://developer.github.com/v3/repos/releases/#get-a-single-release +// GitHub API docs: https://developer.github.com/v3/repos/releases/#get-a-release func (s *RepositoriesService) GetRelease(ctx context.Context, owner, repo string, id int64) (*RepositoryRelease, *Response, error) { u := fmt.Sprintf("repos/%s/%s/releases/%d", owner, repo, id) return s.getSingleRelease(ctx, u) @@ -178,7 +178,7 @@ func (s *RepositoriesService) CreateRelease(ctx context.Context, owner, repo str // Note that only a subset of the release fields are used. // See RepositoryRelease for more information. // -// GitHub API docs: https://developer.github.com/v3/repos/releases/#edit-a-release +// GitHub API docs: https://developer.github.com/v3/repos/releases/#update-a-release func (s *RepositoriesService) EditRelease(ctx context.Context, owner, repo string, id int64, release *RepositoryRelease) (*RepositoryRelease, *Response, error) { u := fmt.Sprintf("repos/%s/%s/releases/%d", owner, repo, id) @@ -219,7 +219,7 @@ func (s *RepositoriesService) DeleteRelease(ctx context.Context, owner, repo str // ListReleaseAssets lists the release's assets. // -// GitHub API docs: https://developer.github.com/v3/repos/releases/#list-assets-for-a-release +// GitHub API docs: https://developer.github.com/v3/repos/releases/#list-release-assets func (s *RepositoriesService) ListReleaseAssets(ctx context.Context, owner, repo string, id int64, opts *ListOptions) ([]*ReleaseAsset, *Response, error) { u := fmt.Sprintf("repos/%s/%s/releases/%d/assets", owner, repo, id) u, err := addOptions(u, opts) @@ -242,7 +242,7 @@ func (s *RepositoriesService) ListReleaseAssets(ctx context.Context, owner, repo // GetReleaseAsset fetches a single release asset. // -// GitHub API docs: https://developer.github.com/v3/repos/releases/#get-a-single-release-asset +// GitHub API docs: https://developer.github.com/v3/repos/releases/#get-a-release-asset func (s *RepositoriesService) GetReleaseAsset(ctx context.Context, owner, repo string, id int64) (*ReleaseAsset, *Response, error) { u := fmt.Sprintf("repos/%s/%s/releases/assets/%d", owner, repo, id) @@ -271,7 +271,7 @@ func (s *RepositoriesService) GetReleaseAsset(ctx context.Context, owner, repo s // exist, but it's possible to pass any http.Client. If nil is passed the // redirectURL will be returned instead. // -// GitHub API docs: https://developer.github.com/v3/repos/releases/#get-a-single-release-asset +// GitHub API docs: https://developer.github.com/v3/repos/releases/#get-a-release-asset func (s *RepositoriesService) DownloadReleaseAsset(ctx context.Context, owner, repo string, id int64, followRedirectsClient *http.Client) (rc io.ReadCloser, redirectURL string, err error) { u := fmt.Sprintf("repos/%s/%s/releases/assets/%d", owner, repo, id) @@ -333,7 +333,7 @@ func (s *RepositoriesService) downloadReleaseAssetFromURL(ctx context.Context, f // EditReleaseAsset edits a repository release asset. // -// GitHub API docs: https://developer.github.com/v3/repos/releases/#edit-a-release-asset +// GitHub API docs: https://developer.github.com/v3/repos/releases/#update-a-release-asset func (s *RepositoriesService) EditReleaseAsset(ctx context.Context, owner, repo string, id int64, release *ReleaseAsset) (*ReleaseAsset, *Response, error) { u := fmt.Sprintf("repos/%s/%s/releases/assets/%d", owner, repo, id) diff --git a/github/repos_stats.go b/github/repos_stats.go index 0e257bad39d..633ca7c2a17 100644 --- a/github/repos_stats.go +++ b/github/repos_stats.go @@ -45,7 +45,7 @@ func (w WeeklyStats) String() string { // it is now computing the requested statistics. A follow up request, after a // delay of a second or so, should result in a successful request. // -// GitHub API docs: https://developer.github.com/v3/repos/statistics/#get-contributors-list-with-additions-deletions-and-commit-counts +// GitHub API docs: https://developer.github.com/v3/repos/statistics/#get-all-contributor-commit-activity func (s *RepositoriesService) ListContributorsStats(ctx context.Context, owner, repo string) ([]*ContributorStats, *Response, error) { u := fmt.Sprintf("repos/%v/%v/stats/contributors", owner, repo) req, err := s.client.NewRequest("GET", u, nil) @@ -84,7 +84,7 @@ func (w WeeklyCommitActivity) String() string { // it is now computing the requested statistics. A follow up request, after a // delay of a second or so, should result in a successful request. // -// GitHub API docs: https://developer.github.com/v3/repos/statistics/#get-the-last-year-of-commit-activity-data +// GitHub API docs: https://developer.github.com/v3/repos/statistics/#get-the-last-year-of-commit-activity func (s *RepositoriesService) ListCommitActivity(ctx context.Context, owner, repo string) ([]*WeeklyCommitActivity, *Response, error) { u := fmt.Sprintf("repos/%v/%v/stats/commit_activity", owner, repo) req, err := s.client.NewRequest("GET", u, nil) @@ -111,7 +111,7 @@ func (s *RepositoriesService) ListCommitActivity(ctx context.Context, owner, rep // it is now computing the requested statistics. A follow up request, after a // delay of a second or so, should result in a successful request. // -// GitHub API docs: https://developer.github.com/v3/repos/statistics/#get-the-number-of-additions-and-deletions-per-week +// GitHub API docs: https://developer.github.com/v3/repos/statistics/#get-the-weekly-commit-activity func (s *RepositoriesService) ListCodeFrequency(ctx context.Context, owner, repo string) ([]*WeeklyStats, *Response, error) { u := fmt.Sprintf("repos/%v/%v/stats/code_frequency", owner, repo) req, err := s.client.NewRequest("GET", u, nil) @@ -164,7 +164,7 @@ func (r RepositoryParticipation) String() string { // it is now computing the requested statistics. A follow up request, after a // delay of a second or so, should result in a successful request. // -// GitHub API docs: https://developer.github.com/v3/repos/statistics/#get-the-weekly-commit-count-for-the-repository-owner-and-everyone-else +// GitHub API docs: https://developer.github.com/v3/repos/statistics/#get-the-weekly-commit-count func (s *RepositoriesService) ListParticipation(ctx context.Context, owner, repo string) (*RepositoryParticipation, *Response, error) { u := fmt.Sprintf("repos/%v/%v/stats/participation", owner, repo) req, err := s.client.NewRequest("GET", u, nil) @@ -197,7 +197,7 @@ type PunchCard struct { // it is now computing the requested statistics. A follow up request, after a // delay of a second or so, should result in a successful request. // -// GitHub API docs: https://developer.github.com/v3/repos/statistics/#get-the-number-of-commits-per-hour-in-each-day +// GitHub API docs: https://developer.github.com/v3/repos/statistics/#get-the-hourly-commit-count-for-each-day func (s *RepositoriesService) ListPunchCard(ctx context.Context, owner, repo string) ([]*PunchCard, *Response, error) { u := fmt.Sprintf("repos/%v/%v/stats/punch_card", owner, repo) req, err := s.client.NewRequest("GET", u, nil) diff --git a/github/repos_statuses.go b/github/repos_statuses.go index cd7e424174a..53478c75a63 100644 --- a/github/repos_statuses.go +++ b/github/repos_statuses.go @@ -43,7 +43,7 @@ func (r RepoStatus) String() string { // ListStatuses lists the statuses of a repository at the specified // reference. ref can be a SHA, a branch name, or a tag name. // -// GitHub API docs: https://developer.github.com/v3/repos/statuses/#list-statuses-for-a-specific-ref +// GitHub API docs: https://developer.github.com/v3/repos/statuses/#list-commit-statuses-for-a-reference func (s *RepositoriesService) ListStatuses(ctx context.Context, owner, repo, ref string, opts *ListOptions) ([]*RepoStatus, *Response, error) { u := fmt.Sprintf("repos/%v/%v/commits/%v/statuses", owner, repo, refURLEscape(ref)) u, err := addOptions(u, opts) @@ -68,7 +68,7 @@ func (s *RepositoriesService) ListStatuses(ctx context.Context, owner, repo, ref // CreateStatus creates a new status for a repository at the specified // reference. Ref can be a SHA, a branch name, or a tag name. // -// GitHub API docs: https://developer.github.com/v3/repos/statuses/#create-a-status +// GitHub API docs: https://developer.github.com/v3/repos/statuses/#create-a-commit-status func (s *RepositoriesService) CreateStatus(ctx context.Context, owner, repo, ref string, status *RepoStatus) (*RepoStatus, *Response, error) { u := fmt.Sprintf("repos/%v/%v/statuses/%v", owner, repo, refURLEscape(ref)) req, err := s.client.NewRequest("POST", u, status) @@ -107,7 +107,7 @@ func (s CombinedStatus) String() string { // GetCombinedStatus returns the combined status of a repository at the specified // reference. ref can be a SHA, a branch name, or a tag name. // -// GitHub API docs: https://developer.github.com/v3/repos/statuses/#get-the-combined-status-for-a-specific-ref +// GitHub API docs: https://developer.github.com/v3/repos/statuses/#get-the-combined-status-for-a-specific-reference func (s *RepositoriesService) GetCombinedStatus(ctx context.Context, owner, repo, ref string, opts *ListOptions) (*CombinedStatus, *Response, error) { u := fmt.Sprintf("repos/%v/%v/commits/%v/status", owner, repo, refURLEscape(ref)) u, err := addOptions(u, opts) diff --git a/github/repos_traffic.go b/github/repos_traffic.go index 91d85706286..f2607287dd7 100644 --- a/github/repos_traffic.go +++ b/github/repos_traffic.go @@ -54,7 +54,7 @@ type TrafficBreakdownOptions struct { // ListTrafficReferrers list the top 10 referrers over the last 14 days. // -// GitHub API docs: https://developer.github.com/v3/repos/traffic/#list-referrers +// GitHub API docs: https://developer.github.com/v3/repos/traffic/#get-top-referral-sources func (s *RepositoriesService) ListTrafficReferrers(ctx context.Context, owner, repo string) ([]*TrafficReferrer, *Response, error) { u := fmt.Sprintf("repos/%v/%v/traffic/popular/referrers", owner, repo) @@ -74,7 +74,7 @@ func (s *RepositoriesService) ListTrafficReferrers(ctx context.Context, owner, r // ListTrafficPaths list the top 10 popular content over the last 14 days. // -// GitHub API docs: https://developer.github.com/v3/repos/traffic/#list-paths +// GitHub API docs: https://developer.github.com/v3/repos/traffic/#get-top-referral-paths func (s *RepositoriesService) ListTrafficPaths(ctx context.Context, owner, repo string) ([]*TrafficPath, *Response, error) { u := fmt.Sprintf("repos/%v/%v/traffic/popular/paths", owner, repo) @@ -94,7 +94,7 @@ func (s *RepositoriesService) ListTrafficPaths(ctx context.Context, owner, repo // ListTrafficViews get total number of views for the last 14 days and breaks it down either per day or week. // -// GitHub API docs: https://developer.github.com/v3/repos/traffic/#views +// GitHub API docs: https://developer.github.com/v3/repos/traffic/#get-page-views func (s *RepositoriesService) ListTrafficViews(ctx context.Context, owner, repo string, opts *TrafficBreakdownOptions) (*TrafficViews, *Response, error) { u := fmt.Sprintf("repos/%v/%v/traffic/views", owner, repo) u, err := addOptions(u, opts) @@ -118,7 +118,7 @@ func (s *RepositoriesService) ListTrafficViews(ctx context.Context, owner, repo // ListTrafficClones get total number of clones for the last 14 days and breaks it down either per day or week for the last 14 days. // -// GitHub API docs: https://developer.github.com/v3/repos/traffic/#clones +// GitHub API docs: https://developer.github.com/v3/repos/traffic/#get-repository-clones func (s *RepositoriesService) ListTrafficClones(ctx context.Context, owner, repo string, opts *TrafficBreakdownOptions) (*TrafficClones, *Response, error) { u := fmt.Sprintf("repos/%v/%v/traffic/clones", owner, repo) u, err := addOptions(u, opts) diff --git a/github/teams.go b/github/teams.go index 6a2d0318870..8b3611225cf 100644 --- a/github/teams.go +++ b/github/teams.go @@ -99,7 +99,7 @@ func (s *TeamsService) ListTeams(ctx context.Context, org string, opts *ListOpti // GetTeamByID fetches a team, given a specified organization ID, by ID. // -// GitHub API docs: https://developer.github.com/v3/teams/#get-team-by-name +// GitHub API docs: https://developer.github.com/v3/teams/#get-a-team-by-name func (s *TeamsService) GetTeamByID(ctx context.Context, orgID, teamID int64) (*Team, *Response, error) { u := fmt.Sprintf("organizations/%v/team/%v", orgID, teamID) req, err := s.client.NewRequest("GET", u, nil) @@ -118,7 +118,7 @@ func (s *TeamsService) GetTeamByID(ctx context.Context, orgID, teamID int64) (*T // GetTeamBySlug fetches a team, given a specified organization name, by slug. // -// GitHub API docs: https://developer.github.com/v3/teams/#get-team-by-name +// GitHub API docs: https://developer.github.com/v3/teams/#get-a-team-by-name func (s *TeamsService) GetTeamBySlug(ctx context.Context, org, slug string) (*Team, *Response, error) { u := fmt.Sprintf("orgs/%v/teams/%v", org, slug) req, err := s.client.NewRequest("GET", u, nil) @@ -168,7 +168,7 @@ func (s NewTeam) String() string { // CreateTeam creates a new team within an organization. // -// GitHub API docs: https://developer.github.com/v3/teams/#create-team +// GitHub API docs: https://developer.github.com/v3/teams/#create-a-team func (s *TeamsService) CreateTeam(ctx context.Context, org string, team NewTeam) (*Team, *Response, error) { u := fmt.Sprintf("orgs/%v/teams", org) req, err := s.client.NewRequest("POST", u, team) @@ -214,7 +214,7 @@ func copyNewTeamWithoutParent(team *NewTeam) *newTeamNoParent { // EditTeamByID edits a team, given an organization ID, selected by ID. // -// GitHub API docs: https://developer.github.com/v3/teams/#edit-team +// GitHub API docs: https://developer.github.com/v3/teams/#update-a-team func (s *TeamsService) EditTeamByID(ctx context.Context, orgID, teamID int64, team NewTeam, removeParent bool) (*Team, *Response, error) { u := fmt.Sprintf("organizations/%v/team/%v", orgID, teamID) @@ -241,7 +241,7 @@ func (s *TeamsService) EditTeamByID(ctx context.Context, orgID, teamID int64, te // EditTeamBySlug edits a team, given an organization name, by slug. // -// GitHub API docs: https://developer.github.com/v3/teams/#edit-team +// GitHub API docs: https://developer.github.com/v3/teams/#update-a-team func (s *TeamsService) EditTeamBySlug(ctx context.Context, org, slug string, team NewTeam, removeParent bool) (*Team, *Response, error) { u := fmt.Sprintf("orgs/%v/teams/%v", org, slug) @@ -268,7 +268,7 @@ func (s *TeamsService) EditTeamBySlug(ctx context.Context, org, slug string, tea // DeleteTeamByID deletes a team referenced by ID. // -// GitHub API docs: https://developer.github.com/v3/teams/#delete-team +// GitHub API docs: https://developer.github.com/v3/teams/#delete-a-team func (s *TeamsService) DeleteTeamByID(ctx context.Context, orgID, teamID int64) (*Response, error) { u := fmt.Sprintf("organizations/%v/team/%v", orgID, teamID) req, err := s.client.NewRequest("DELETE", u, nil) @@ -281,7 +281,7 @@ func (s *TeamsService) DeleteTeamByID(ctx context.Context, orgID, teamID int64) // DeleteTeamBySlug deletes a team reference by slug. // -// GitHub API docs: https://developer.github.com/v3/teams/#delete-team +// GitHub API docs: https://developer.github.com/v3/teams/#delete-a-team func (s *TeamsService) DeleteTeamBySlug(ctx context.Context, org, slug string) (*Response, error) { u := fmt.Sprintf("orgs/%v/teams/%v", org, slug) req, err := s.client.NewRequest("DELETE", u, nil) @@ -342,7 +342,7 @@ func (s *TeamsService) ListChildTeamsByParentSlug(ctx context.Context, org, slug // ListTeamReposByID lists the repositories given a team ID that the specified team has access to. // -// GitHub API docs: https://developer.github.com/v3/teams/#list-team-repos +// GitHub API docs: https://developer.github.com/v3/teams/#list-team-repositories func (s *TeamsService) ListTeamReposByID(ctx context.Context, orgID, teamID int64, opts *ListOptions) ([]*Repository, *Response, error) { u := fmt.Sprintf("organizations/%v/team/%v/repos", orgID, teamID) u, err := addOptions(u, opts) @@ -370,7 +370,7 @@ func (s *TeamsService) ListTeamReposByID(ctx context.Context, orgID, teamID int6 // ListTeamReposBySlug lists the repositories given a team slug that the specified team has access to. // -// GitHub API docs: https://developer.github.com/v3/teams/#list-team-repos +// GitHub API docs: https://developer.github.com/v3/teams/#list-team-repositories func (s *TeamsService) ListTeamReposBySlug(ctx context.Context, org, slug string, opts *ListOptions) ([]*Repository, *Response, error) { u := fmt.Sprintf("orgs/%v/teams/%v/repos", org, slug) u, err := addOptions(u, opts) @@ -400,7 +400,7 @@ func (s *TeamsService) ListTeamReposBySlug(ctx context.Context, org, slug string // repository is managed by team, a Repository is returned which includes the // permissions team has for that repo. // -// GitHub API docs: https://developer.github.com/v3/teams/#check-if-a-team-manages-a-repository +// GitHub API docs: https://developer.github.com/v3/teams/#check-team-permissions-for-a-repository func (s *TeamsService) IsTeamRepoByID(ctx context.Context, orgID, teamID int64, owner, repo string) (*Repository, *Response, error) { u := fmt.Sprintf("organizations/%v/team/%v/repos/%v/%v", orgID, teamID, owner, repo) req, err := s.client.NewRequest("GET", u, nil) @@ -424,7 +424,7 @@ func (s *TeamsService) IsTeamRepoByID(ctx context.Context, orgID, teamID int64, // repository is managed by team, a Repository is returned which includes the // permissions team has for that repo. // -// GitHub API docs: https://developer.github.com/v3/teams/#check-if-a-team-manages-a-repository +// GitHub API docs: https://developer.github.com/v3/teams/#check-team-permissions-for-a-repository func (s *TeamsService) IsTeamRepoBySlug(ctx context.Context, org, slug, owner, repo string) (*Repository, *Response, error) { u := fmt.Sprintf("orgs/%v/teams/%v/repos/%v/%v", org, slug, owner, repo) req, err := s.client.NewRequest("GET", u, nil) @@ -463,7 +463,7 @@ type TeamAddTeamRepoOptions struct { // The specified repository must be owned by the organization to which the team // belongs, or a direct fork of a repository owned by the organization. // -// GitHub API docs: https://developer.github.com/v3/teams/#add-or-update-team-repository +// GitHub API docs: https://developer.github.com/v3/teams/#add-or-update-team-repository-permissions func (s *TeamsService) AddTeamRepoByID(ctx context.Context, orgID, teamID int64, owner, repo string, opts *TeamAddTeamRepoOptions) (*Response, error) { u := fmt.Sprintf("organizations/%v/team/%v/repos/%v/%v", orgID, teamID, owner, repo) req, err := s.client.NewRequest("PUT", u, opts) @@ -478,7 +478,7 @@ func (s *TeamsService) AddTeamRepoByID(ctx context.Context, orgID, teamID int64, // The specified repository must be owned by the organization to which the team // belongs, or a direct fork of a repository owned by the organization. // -// GitHub API docs: https://developer.github.com/v3/teams/#add-or-update-team-repository +// GitHub API docs: https://developer.github.com/v3/teams/#add-or-update-team-repository-permissions func (s *TeamsService) AddTeamRepoBySlug(ctx context.Context, org, slug, owner, repo string, opts *TeamAddTeamRepoOptions) (*Response, error) { u := fmt.Sprintf("orgs/%v/teams/%v/repos/%v/%v", org, slug, owner, repo) req, err := s.client.NewRequest("PUT", u, opts) @@ -493,7 +493,7 @@ func (s *TeamsService) AddTeamRepoBySlug(ctx context.Context, org, slug, owner, // team given the team ID. Note that this does not delete the repository, it // just removes it from the team. // -// GitHub API docs: https://developer.github.com/v3/teams/#remove-team-repository +// GitHub API docs: https://developer.github.com/v3/teams/#remove-a-repository-from-a-team func (s *TeamsService) RemoveTeamRepoByID(ctx context.Context, orgID, teamID int64, owner, repo string) (*Response, error) { u := fmt.Sprintf("organizations/%v/team/%v/repos/%v/%v", orgID, teamID, owner, repo) req, err := s.client.NewRequest("DELETE", u, nil) @@ -508,7 +508,7 @@ func (s *TeamsService) RemoveTeamRepoByID(ctx context.Context, orgID, teamID int // team given the team slug. Note that this does not delete the repository, it // just removes it from the team. // -// GitHub API docs: https://developer.github.com/v3/teams/#remove-team-repository +// GitHub API docs: https://developer.github.com/v3/teams/#remove-a-repository-from-a-team func (s *TeamsService) RemoveTeamRepoBySlug(ctx context.Context, org, slug, owner, repo string) (*Response, error) { u := fmt.Sprintf("orgs/%v/teams/%v/repos/%v/%v", org, slug, owner, repo) req, err := s.client.NewRequest("DELETE", u, nil) @@ -520,7 +520,7 @@ func (s *TeamsService) RemoveTeamRepoBySlug(ctx context.Context, org, slug, owne } // ListUserTeams lists a user's teams -// GitHub API docs: https://developer.github.com/v3/teams/#list-user-teams +// GitHub API docs: https://developer.github.com/v3/teams/#list-teams-for-the-authenticated-user func (s *TeamsService) ListUserTeams(ctx context.Context, opts *ListOptions) ([]*Team, *Response, error) { u := "user/teams" u, err := addOptions(u, opts) @@ -593,7 +593,7 @@ func (s *TeamsService) ListTeamProjectsBySlug(ctx context.Context, org, slug str // ReviewTeamProjectsByID checks whether a team, given its ID, has read, write, or admin // permissions for an organization project. // -// GitHub API docs: https://developer.github.com/v3/teams/#review-a-team-project +// GitHub API docs: https://developer.github.com/v3/teams/#check-team-permissions-for-a-project func (s *TeamsService) ReviewTeamProjectsByID(ctx context.Context, orgID, teamID, projectID int64) (*Project, *Response, error) { u := fmt.Sprintf("organizations/%v/team/%v/projects/%v", orgID, teamID, projectID) req, err := s.client.NewRequest("GET", u, nil) @@ -617,7 +617,7 @@ func (s *TeamsService) ReviewTeamProjectsByID(ctx context.Context, orgID, teamID // ReviewTeamProjectsBySlug checks whether a team, given its slug, has read, write, or admin // permissions for an organization project. // -// GitHub API docs: https://developer.github.com/v3/teams/#review-a-team-project +// GitHub API docs: https://developer.github.com/v3/teams/#check-team-permissions-for-a-project func (s *TeamsService) ReviewTeamProjectsBySlug(ctx context.Context, org, slug string, projectID int64) (*Project, *Response, error) { u := fmt.Sprintf("orgs/%v/teams/%v/projects/%v", org, slug, projectID) req, err := s.client.NewRequest("GET", u, nil) @@ -654,7 +654,7 @@ type TeamProjectOptions struct { // To add a project to a team or update the team's permission on a project, the // authenticated user must have admin permissions for the project. // -// GitHub API docs: https://developer.github.com/v3/teams/#add-or-update-team-project +// GitHub API docs: https://developer.github.com/v3/teams/#add-or-update-team-project-permissions func (s *TeamsService) AddTeamProjectByID(ctx context.Context, orgID, teamID, projectID int64, opts *TeamProjectOptions) (*Response, error) { u := fmt.Sprintf("organizations/%v/team/%v/projects/%v", orgID, teamID, projectID) req, err := s.client.NewRequest("PUT", u, opts) @@ -673,7 +673,7 @@ func (s *TeamsService) AddTeamProjectByID(ctx context.Context, orgID, teamID, pr // To add a project to a team or update the team's permission on a project, the // authenticated user must have admin permissions for the project. // -// GitHub API docs: https://developer.github.com/v3/teams/#add-or-update-team-project +// GitHub API docs: https://developer.github.com/v3/teams/#add-or-update-team-project-permissions func (s *TeamsService) AddTeamProjectBySlug(ctx context.Context, org, slug string, projectID int64, opts *TeamProjectOptions) (*Response, error) { u := fmt.Sprintf("orgs/%v/teams/%v/projects/%v", org, slug, projectID) req, err := s.client.NewRequest("PUT", u, opts) @@ -695,7 +695,7 @@ func (s *TeamsService) AddTeamProjectBySlug(ctx context.Context, org, slug strin // or project. // Note: This endpoint removes the project from the team, but does not delete it. // -// GitHub API docs: https://developer.github.com/v3/teams/#remove-team-project +// GitHub API docs: https://developer.github.com/v3/teams/#remove-a-project-from-a-team func (s *TeamsService) RemoveTeamProjectByID(ctx context.Context, orgID, teamID, projectID int64) (*Response, error) { u := fmt.Sprintf("organizations/%v/team/%v/projects/%v", orgID, teamID, projectID) req, err := s.client.NewRequest("DELETE", u, nil) @@ -717,7 +717,7 @@ func (s *TeamsService) RemoveTeamProjectByID(ctx context.Context, orgID, teamID, // or project. // Note: This endpoint removes the project from the team, but does not delete it. // -// GitHub API docs: https://developer.github.com/v3/teams/#remove-team-project +// GitHub API docs: https://developer.github.com/v3/teams/#remove-a-project-from-a-team func (s *TeamsService) RemoveTeamProjectBySlug(ctx context.Context, org, slug string, projectID int64) (*Response, error) { u := fmt.Sprintf("orgs/%v/teams/%v/projects/%v", org, slug, projectID) req, err := s.client.NewRequest("DELETE", u, nil) @@ -746,7 +746,7 @@ type IDPGroup struct { // ListIDPGroupsInOrganization lists IDP groups available in an organization. // -// GitHub API docs: https://developer.github.com/v3/teams/team_sync/#list-idp-groups-in-an-organization +// GitHub API docs: https://developer.github.com/v3/teams/team_sync/#list-idp-groups-for-an-organization func (s *TeamsService) ListIDPGroupsInOrganization(ctx context.Context, org string, opts *ListCursorOptions) (*IDPGroupList, *Response, error) { u := fmt.Sprintf("orgs/%v/team-sync/groups", org) u, err := addOptions(u, opts) diff --git a/github/teams_discussion_comments.go b/github/teams_discussion_comments.go index 61b18f30984..5bdda665a0d 100644 --- a/github/teams_discussion_comments.go +++ b/github/teams_discussion_comments.go @@ -43,7 +43,7 @@ type DiscussionCommentListOptions struct { // ListCommentsByID lists all comments on a team discussion by team ID. // Authenticated user must grant read:discussion scope. // -// GitHub API docs: https://developer.github.com/v3/teams/discussion_comments/#list-comments +// GitHub API docs: https://developer.github.com/v3/teams/discussion_comments/#list-discussion-comments func (s *TeamsService) ListCommentsByID(ctx context.Context, orgID, teamID int64, discussionNumber int, options *DiscussionCommentListOptions) ([]*DiscussionComment, *Response, error) { u := fmt.Sprintf("organizations/%v/team/%v/discussions/%v/comments", orgID, teamID, discussionNumber) u, err := addOptions(u, options) @@ -68,7 +68,7 @@ func (s *TeamsService) ListCommentsByID(ctx context.Context, orgID, teamID int64 // ListCommentsBySlug lists all comments on a team discussion by team slug. // Authenticated user must grant read:discussion scope. // -// GitHub API docs: https://developer.github.com/v3/teams/discussion_comments/#list-comments +// GitHub API docs: https://developer.github.com/v3/teams/discussion_comments/#list-discussion-comments func (s *TeamsService) ListCommentsBySlug(ctx context.Context, org, slug string, discussionNumber int, options *DiscussionCommentListOptions) ([]*DiscussionComment, *Response, error) { u := fmt.Sprintf("orgs/%v/teams/%v/discussions/%v/comments", org, slug, discussionNumber) u, err := addOptions(u, options) @@ -93,7 +93,7 @@ func (s *TeamsService) ListCommentsBySlug(ctx context.Context, org, slug string, // GetCommentByID gets a specific comment on a team discussion by team ID. // Authenticated user must grant read:discussion scope. // -// GitHub API docs: https://developer.github.com/v3/teams/discussion_comments/#get-a-single-comment +// GitHub API docs: https://developer.github.com/v3/teams/discussion_comments/#get-a-discussion-comment func (s *TeamsService) GetCommentByID(ctx context.Context, orgID, teamID int64, discussionNumber, commentNumber int) (*DiscussionComment, *Response, error) { u := fmt.Sprintf("organizations/%v/team/%v/discussions/%v/comments/%v", orgID, teamID, discussionNumber, commentNumber) req, err := s.client.NewRequest("GET", u, nil) @@ -113,7 +113,7 @@ func (s *TeamsService) GetCommentByID(ctx context.Context, orgID, teamID int64, // GetCommentBySlug gets a specific comment on a team discussion by team slug. // Authenticated user must grant read:discussion scope. // -// GitHub API docs: https://developer.github.com/v3/teams/discussion_comments/#get-a-single-comment +// GitHub API docs: https://developer.github.com/v3/teams/discussion_comments/#get-a-discussion-comment func (s *TeamsService) GetCommentBySlug(ctx context.Context, org, slug string, discussionNumber, commentNumber int) (*DiscussionComment, *Response, error) { u := fmt.Sprintf("orgs/%v/teams/%v/discussions/%v/comments/%v", org, slug, discussionNumber, commentNumber) @@ -134,7 +134,7 @@ func (s *TeamsService) GetCommentBySlug(ctx context.Context, org, slug string, d // CreateCommentByID creates a new comment on a team discussion by team ID. // Authenticated user must grant write:discussion scope. // -// GitHub API docs: https://developer.github.com/v3/teams/discussion_comments/#create-a-comment +// GitHub API docs: https://developer.github.com/v3/teams/discussion_comments/#create-a-discussion-comment func (s *TeamsService) CreateCommentByID(ctx context.Context, orgID, teamID int64, discsusionNumber int, comment DiscussionComment) (*DiscussionComment, *Response, error) { u := fmt.Sprintf("organizations/%v/team/%v/discussions/%v/comments", orgID, teamID, discsusionNumber) req, err := s.client.NewRequest("POST", u, comment) @@ -154,7 +154,7 @@ func (s *TeamsService) CreateCommentByID(ctx context.Context, orgID, teamID int6 // CreateCommentBySlug creates a new comment on a team discussion by team slug. // Authenticated user must grant write:discussion scope. // -// GitHub API docs: https://developer.github.com/v3/teams/discussion_comments/#create-a-comment +// GitHub API docs: https://developer.github.com/v3/teams/discussion_comments/#create-a-discussion-comment func (s *TeamsService) CreateCommentBySlug(ctx context.Context, org, slug string, discsusionNumber int, comment DiscussionComment) (*DiscussionComment, *Response, error) { u := fmt.Sprintf("orgs/%v/teams/%v/discussions/%v/comments", org, slug, discsusionNumber) req, err := s.client.NewRequest("POST", u, comment) @@ -175,7 +175,7 @@ func (s *TeamsService) CreateCommentBySlug(ctx context.Context, org, slug string // Authenticated user must grant write:discussion scope. // User is allowed to edit body of a comment only. // -// GitHub API docs: https://developer.github.com/v3/teams/discussion_comments/#edit-a-comment +// GitHub API docs: https://developer.github.com/v3/teams/discussion_comments/#update-a-discussion-comment func (s *TeamsService) EditCommentByID(ctx context.Context, orgID, teamID int64, discussionNumber, commentNumber int, comment DiscussionComment) (*DiscussionComment, *Response, error) { u := fmt.Sprintf("organizations/%v/team/%v/discussions/%v/comments/%v", orgID, teamID, discussionNumber, commentNumber) req, err := s.client.NewRequest("PATCH", u, comment) @@ -196,7 +196,7 @@ func (s *TeamsService) EditCommentByID(ctx context.Context, orgID, teamID int64, // Authenticated user must grant write:discussion scope. // User is allowed to edit body of a comment only. // -// GitHub API docs: https://developer.github.com/v3/teams/discussion_comments/#edit-a-comment +// GitHub API docs: https://developer.github.com/v3/teams/discussion_comments/#update-a-discussion-comment func (s *TeamsService) EditCommentBySlug(ctx context.Context, org, slug string, discussionNumber, commentNumber int, comment DiscussionComment) (*DiscussionComment, *Response, error) { u := fmt.Sprintf("orgs/%v/teams/%v/discussions/%v/comments/%v", org, slug, discussionNumber, commentNumber) req, err := s.client.NewRequest("PATCH", u, comment) @@ -216,7 +216,7 @@ func (s *TeamsService) EditCommentBySlug(ctx context.Context, org, slug string, // DeleteCommentByID deletes a comment on a team discussion by team ID. // Authenticated user must grant write:discussion scope. // -// GitHub API docs: https://developer.github.com/v3/teams/discussion_comments/#delete-a-comment +// GitHub API docs: https://developer.github.com/v3/teams/discussion_comments/#delete-a-discussion-comment func (s *TeamsService) DeleteCommentByID(ctx context.Context, orgID, teamID int64, discussionNumber, commentNumber int) (*Response, error) { u := fmt.Sprintf("organizations/%v/team/%v/discussions/%v/comments/%v", orgID, teamID, discussionNumber, commentNumber) req, err := s.client.NewRequest("DELETE", u, nil) @@ -230,7 +230,7 @@ func (s *TeamsService) DeleteCommentByID(ctx context.Context, orgID, teamID int6 // DeleteCommentBySlug deletes a comment on a team discussion by team slug. // Authenticated user must grant write:discussion scope. // -// GitHub API docs: https://developer.github.com/v3/teams/discussion_comments/#delete-a-comment +// GitHub API docs: https://developer.github.com/v3/teams/discussion_comments/#delete-a-discussion-comment func (s *TeamsService) DeleteCommentBySlug(ctx context.Context, org, slug string, discussionNumber, commentNumber int) (*Response, error) { u := fmt.Sprintf("orgs/%v/teams/%v/discussions/%v/comments/%v", org, slug, discussionNumber, commentNumber) req, err := s.client.NewRequest("DELETE", u, nil) diff --git a/github/teams_discussions.go b/github/teams_discussions.go index f0f2206ac92..17abe5d5e65 100644 --- a/github/teams_discussions.go +++ b/github/teams_discussions.go @@ -99,7 +99,7 @@ func (s *TeamsService) ListDiscussionsBySlug(ctx context.Context, org, slug stri // GetDiscussionByID gets a specific discussion on a team's page given Organization and Team ID. // Authenticated user must grant read:discussion scope. // -// GitHub API docs: https://developer.github.com/v3/teams/discussions/#get-a-single-discussion +// GitHub API docs: https://developer.github.com/v3/teams/discussions/#get-a-discussion func (s *TeamsService) GetDiscussionByID(ctx context.Context, orgID, teamID int64, discussionNumber int) (*TeamDiscussion, *Response, error) { u := fmt.Sprintf("organizations/%v/team/%v/discussions/%v", orgID, teamID, discussionNumber) req, err := s.client.NewRequest("GET", u, nil) @@ -119,7 +119,7 @@ func (s *TeamsService) GetDiscussionByID(ctx context.Context, orgID, teamID int6 // GetDiscussionBySlug gets a specific discussion on a team's page given Organization name and Team's slug. // Authenticated user must grant read:discussion scope. // -// GitHub API docs: https://developer.github.com/v3/teams/discussions/#get-a-single-discussion +// GitHub API docs: https://developer.github.com/v3/teams/discussions/#get-a-discussion func (s *TeamsService) GetDiscussionBySlug(ctx context.Context, org, slug string, discussionNumber int) (*TeamDiscussion, *Response, error) { u := fmt.Sprintf("orgs/%v/teams/%v/discussions/%v", org, slug, discussionNumber) req, err := s.client.NewRequest("GET", u, nil) @@ -180,7 +180,7 @@ func (s *TeamsService) CreateDiscussionBySlug(ctx context.Context, org, slug str // Authenticated user must grant write:discussion scope. // User is allowed to change Title and Body of a discussion only. // -// GitHub API docs: https://developer.github.com/v3/teams/discussions/#edit-a-discussion +// GitHub API docs: https://developer.github.com/v3/teams/discussions/#update-a-discussion func (s *TeamsService) EditDiscussionByID(ctx context.Context, orgID, teamID int64, discussionNumber int, discussion TeamDiscussion) (*TeamDiscussion, *Response, error) { u := fmt.Sprintf("organizations/%v/team/%v/discussions/%v", orgID, teamID, discussionNumber) req, err := s.client.NewRequest("PATCH", u, discussion) @@ -201,7 +201,7 @@ func (s *TeamsService) EditDiscussionByID(ctx context.Context, orgID, teamID int // Authenticated user must grant write:discussion scope. // User is allowed to change Title and Body of a discussion only. // -// GitHub API docs: https://developer.github.com/v3/teams/discussions/#edit-a-discussion +// GitHub API docs: https://developer.github.com/v3/teams/discussions/#update-a-discussion func (s *TeamsService) EditDiscussionBySlug(ctx context.Context, org, slug string, discussionNumber int, discussion TeamDiscussion) (*TeamDiscussion, *Response, error) { u := fmt.Sprintf("orgs/%v/teams/%v/discussions/%v", org, slug, discussionNumber) req, err := s.client.NewRequest("PATCH", u, discussion) diff --git a/github/teams_members.go b/github/teams_members.go index a29263e75c7..b5d31aaf562 100644 --- a/github/teams_members.go +++ b/github/teams_members.go @@ -73,7 +73,7 @@ func (s *TeamsService) ListTeamMembersBySlug(ctx context.Context, org, slug stri // GetTeamMembershipByID returns the membership status for a user in a team, given a specified // organization ID, by team ID. // -// GitHub API docs: https://developer.github.com/v3/teams/members/#get-team-membership +// GitHub API docs: https://developer.github.com/v3/teams/members/#get-team-membership-for-a-user func (s *TeamsService) GetTeamMembershipByID(ctx context.Context, orgID, teamID int64, user string) (*Membership, *Response, error) { u := fmt.Sprintf("organizations/%v/team/%v/memberships/%v", orgID, teamID, user) req, err := s.client.NewRequest("GET", u, nil) @@ -93,7 +93,7 @@ func (s *TeamsService) GetTeamMembershipByID(ctx context.Context, orgID, teamID // GetTeamMembershipBySlug returns the membership status for a user in a team, given a specified // organization name, by team slug. // -// GitHub API docs: https://developer.github.com/v3/teams/members/#get-team-membership +// GitHub API docs: https://developer.github.com/v3/teams/members/#get-team-membership-for-a-user func (s *TeamsService) GetTeamMembershipBySlug(ctx context.Context, org, slug, user string) (*Membership, *Response, error) { u := fmt.Sprintf("orgs/%v/teams/%v/memberships/%v", org, slug, user) req, err := s.client.NewRequest("GET", u, nil) @@ -127,7 +127,7 @@ type TeamAddTeamMembershipOptions struct { // AddTeamMembership adds or invites a user to a team, given a specified // organization ID, by team ID. // -// GitHub API docs: https://developer.github.com/v3/teams/members/#add-or-update-team-membership +// GitHub API docs: https://developer.github.com/v3/teams/members/#add-or-update-team-membership-for-a-user func (s *TeamsService) AddTeamMembershipByID(ctx context.Context, orgID, teamID int64, user string, opts *TeamAddTeamMembershipOptions) (*Membership, *Response, error) { u := fmt.Sprintf("organizations/%v/team/%v/memberships/%v", orgID, teamID, user) req, err := s.client.NewRequest("PUT", u, opts) @@ -147,7 +147,7 @@ func (s *TeamsService) AddTeamMembershipByID(ctx context.Context, orgID, teamID // AddTeamMembershipBySlug adds or invites a user to a team, given a specified // organization name, by team slug. // -// GitHub API docs: https://developer.github.com/v3/teams/members/#add-or-update-team-membership +// GitHub API docs: https://developer.github.com/v3/teams/members/#add-or-update-team-membership-for-a-user func (s *TeamsService) AddTeamMembershipBySlug(ctx context.Context, org, slug, user string, opts *TeamAddTeamMembershipOptions) (*Membership, *Response, error) { u := fmt.Sprintf("orgs/%v/teams/%v/memberships/%v", org, slug, user) req, err := s.client.NewRequest("PUT", u, opts) @@ -167,7 +167,7 @@ func (s *TeamsService) AddTeamMembershipBySlug(ctx context.Context, org, slug, u // RemoveTeamMembership removes a user from a team, given a specified // organization ID, by team ID. // -// GitHub API docs: https://developer.github.com/v3/teams/members/#remove-team-membership +// GitHub API docs: https://developer.github.com/v3/teams/members/#remove-team-membership-for-a-user func (s *TeamsService) RemoveTeamMembershipByID(ctx context.Context, orgID, teamID int64, user string) (*Response, error) { u := fmt.Sprintf("organizations/%v/team/%v/memberships/%v", orgID, teamID, user) req, err := s.client.NewRequest("DELETE", u, nil) @@ -181,7 +181,7 @@ func (s *TeamsService) RemoveTeamMembershipByID(ctx context.Context, orgID, team // RemoveTeamMembership removes a user from a team, given a specified // organization name, by team slug. // -// GitHub API docs: https://developer.github.com/v3/teams/members/#remove-team-membership +// GitHub API docs: https://developer.github.com/v3/teams/members/#remove-team-membership-for-a-user func (s *TeamsService) RemoveTeamMembershipBySlug(ctx context.Context, org, slug, user string) (*Response, error) { u := fmt.Sprintf("orgs/%v/teams/%v/memberships/%v", org, slug, user) req, err := s.client.NewRequest("DELETE", u, nil) diff --git a/github/users.go b/github/users.go index 1db2d3230f8..a387ee1f70e 100644 --- a/github/users.go +++ b/github/users.go @@ -78,8 +78,8 @@ func (u User) String() string { // Get fetches a user. Passing the empty string will fetch the authenticated // user. // -// GitHub API docs: https://developer.github.com/v3/users/#get-a-single-user // GitHub API docs: https://developer.github.com/v3/users/#get-the-authenticated-user +// GitHub API docs: https://developer.github.com/v3/users/#get-a-user func (s *UsersService) Get(ctx context.Context, user string) (*User, *Response, error) { var u string if user != "" { @@ -164,7 +164,7 @@ type UserContext struct { // GetHovercard fetches contextual information about user. It requires authentication // via Basic Auth or via OAuth with the repo scope. // -// GitHub API docs: https://developer.github.com/v3/users/#get-contextual-information-about-a-user +// GitHub API docs: https://developer.github.com/v3/users/#get-contextual-information-for-a-user func (s *UsersService) GetHovercard(ctx context.Context, user string, opts *HovercardOptions) (*Hovercard, *Response, error) { u := fmt.Sprintf("users/%v/hovercard", user) u, err := addOptions(u, opts) @@ -202,7 +202,7 @@ type UserListOptions struct { // // To paginate through all users, populate 'Since' with the ID of the last user. // -// GitHub API docs: https://developer.github.com/v3/users/#get-all-users +// GitHub API docs: https://developer.github.com/v3/users/#list-users func (s *UsersService) ListAll(ctx context.Context, opts *UserListOptions) ([]*User, *Response, error) { u, err := addOptions("users", opts) if err != nil { @@ -226,7 +226,7 @@ func (s *UsersService) ListAll(ctx context.Context, opts *UserListOptions) ([]*U // ListInvitations lists all currently-open repository invitations for the // authenticated user. // -// GitHub API docs: https://developer.github.com/v3/repos/invitations/#list-a-users-repository-invitations +// GitHub API docs: https://developer.github.com/v3/repos/invitations/#list-repository-invitations-for-the-authenticated-user func (s *UsersService) ListInvitations(ctx context.Context, opts *ListOptions) ([]*RepositoryInvitation, *Response, error) { u, err := addOptions("user/repository_invitations", opts) if err != nil { diff --git a/github/users_blocking.go b/github/users_blocking.go index c60bfdbcd5a..1c292e50d43 100644 --- a/github/users_blocking.go +++ b/github/users_blocking.go @@ -12,7 +12,7 @@ import ( // ListBlockedUsers lists all the blocked users by the authenticated user. // -// GitHub API docs: https://developer.github.com/v3/users/blocking/#list-blocked-users +// GitHub API docs: https://developer.github.com/v3/users/blocking/#list-users-blocked-by-the-authenticated-user func (s *UsersService) ListBlockedUsers(ctx context.Context, opts *ListOptions) ([]*User, *Response, error) { u := "user/blocks" u, err := addOptions(u, opts) @@ -39,7 +39,7 @@ func (s *UsersService) ListBlockedUsers(ctx context.Context, opts *ListOptions) // IsBlocked reports whether specified user is blocked by the authenticated user. // -// GitHub API docs: https://developer.github.com/v3/users/blocking/#check-whether-youve-blocked-a-user +// GitHub API docs: https://developer.github.com/v3/users/blocking/#check-if-a-user-is-blocked-by-the-authenticated-user func (s *UsersService) IsBlocked(ctx context.Context, user string) (bool, *Response, error) { u := fmt.Sprintf("user/blocks/%v", user) diff --git a/github/users_emails.go b/github/users_emails.go index bf02d1a6102..05870c02270 100644 --- a/github/users_emails.go +++ b/github/users_emails.go @@ -17,7 +17,7 @@ type UserEmail struct { // ListEmails lists all email addresses for the authenticated user. // -// GitHub API docs: https://developer.github.com/v3/users/emails/#list-email-addresses-for-a-user +// GitHub API docs: https://developer.github.com/v3/users/emails/#list-email-addresses-for-the-authenticated-user func (s *UsersService) ListEmails(ctx context.Context, opts *ListOptions) ([]*UserEmail, *Response, error) { u := "user/emails" u, err := addOptions(u, opts) @@ -41,7 +41,7 @@ func (s *UsersService) ListEmails(ctx context.Context, opts *ListOptions) ([]*Us // AddEmails adds email addresses of the authenticated user. // -// GitHub API docs: https://developer.github.com/v3/users/emails/#add-email-addresses +// GitHub API docs: https://developer.github.com/v3/users/emails/#add-an-email-address-for-the-authenticated-user func (s *UsersService) AddEmails(ctx context.Context, emails []string) ([]*UserEmail, *Response, error) { u := "user/emails" req, err := s.client.NewRequest("POST", u, emails) @@ -60,7 +60,7 @@ func (s *UsersService) AddEmails(ctx context.Context, emails []string) ([]*UserE // DeleteEmails deletes email addresses from authenticated user. // -// GitHub API docs: https://developer.github.com/v3/users/emails/#delete-email-addresses +// GitHub API docs: https://developer.github.com/v3/users/emails/#delete-an-email-address-for-the-authenticated-user func (s *UsersService) DeleteEmails(ctx context.Context, emails []string) (*Response, error) { u := "user/emails" req, err := s.client.NewRequest("DELETE", u, emails) diff --git a/github/users_followers.go b/github/users_followers.go index fa841c6c5de..bd0a3735c08 100644 --- a/github/users_followers.go +++ b/github/users_followers.go @@ -44,8 +44,8 @@ func (s *UsersService) ListFollowers(ctx context.Context, user string, opts *Lis // ListFollowing lists the people that a user is following. Passing the empty // string will list people the authenticated user is following. // -// GitHub API docs: https://developer.github.com/v3/users/followers/#list-users-followed-by-another-user -// GitHub API docs: https://developer.github.com/v3/users/followers/#list-users-followed-by-the-authenticated-user +// GitHub API docs: https://developer.github.com/v3/users/followers/#list-the-people-the-authenticated-user-follows +// GitHub API docs: https://developer.github.com/v3/users/followers/#list-the-people-a-user-follows func (s *UsersService) ListFollowing(ctx context.Context, user string, opts *ListOptions) ([]*User, *Response, error) { var u string if user != "" { @@ -75,8 +75,8 @@ func (s *UsersService) ListFollowing(ctx context.Context, user string, opts *Lis // IsFollowing checks if "user" is following "target". Passing the empty // string for "user" will check if the authenticated user is following "target". // -// GitHub API docs: https://developer.github.com/v3/users/followers/#check-if-one-user-follows-another -// GitHub API docs: https://developer.github.com/v3/users/followers/#check-if-you-are-following-a-user +// GitHub API docs: https://developer.github.com/v3/users/followers/#check-if-a-person-is-followed-by-the-authenticated-user +// GitHub API docs: https://developer.github.com/v3/users/followers/#check-if-a-user-follows-another-user func (s *UsersService) IsFollowing(ctx context.Context, user, target string) (bool, *Response, error) { var u string if user != "" { diff --git a/github/users_gpg_keys.go b/github/users_gpg_keys.go index 20b6edfd5b2..077a6c2eb37 100644 --- a/github/users_gpg_keys.go +++ b/github/users_gpg_keys.go @@ -45,7 +45,7 @@ type GPGEmail struct { // via Basic Auth or via OAuth with at least read:gpg_key scope. // // GitHub API docs: https://developer.github.com/v3/users/gpg_keys/#list-gpg-keys-for-a-user -// GitHub API docs: https://developer.github.com/v3/users/gpg_keys/#list-your-gpg-keys +// GitHub API docs: https://developer.github.com/v3/users/gpg_keys/#list-gpg-keys-for-the-authenticated-user func (s *UsersService) ListGPGKeys(ctx context.Context, user string, opts *ListOptions) ([]*GPGKey, *Response, error) { var u string if user != "" { @@ -75,7 +75,7 @@ func (s *UsersService) ListGPGKeys(ctx context.Context, user string, opts *ListO // GetGPGKey gets extended details for a single GPG key. It requires authentication // via Basic Auth or via OAuth with at least read:gpg_key scope. // -// GitHub API docs: https://developer.github.com/v3/users/gpg_keys/#get-a-single-gpg-key +// GitHub API docs: https://developer.github.com/v3/users/gpg_keys/#get-a-gpg-key-for-the-authenticated-user func (s *UsersService) GetGPGKey(ctx context.Context, id int64) (*GPGKey, *Response, error) { u := fmt.Sprintf("user/gpg_keys/%v", id) req, err := s.client.NewRequest("GET", u, nil) @@ -117,7 +117,7 @@ func (s *UsersService) CreateGPGKey(ctx context.Context, armoredPublicKey string // DeleteGPGKey deletes a GPG key. It requires authentication via Basic Auth or // via OAuth with at least admin:gpg_key scope. // -// GitHub API docs: https://developer.github.com/v3/users/gpg_keys/#delete-a-gpg-key +// GitHub API docs: https://developer.github.com/v3/users/gpg_keys/#delete-a-gpg-key-for-the-authenticated-user func (s *UsersService) DeleteGPGKey(ctx context.Context, id int64) (*Response, error) { u := fmt.Sprintf("user/gpg_keys/%v", id) req, err := s.client.NewRequest("DELETE", u, nil) diff --git a/github/users_keys.go b/github/users_keys.go index 1091606a9f2..e6b6380864e 100644 --- a/github/users_keys.go +++ b/github/users_keys.go @@ -28,7 +28,7 @@ func (k Key) String() string { // string will fetch keys for the authenticated user. // // GitHub API docs: https://developer.github.com/v3/users/keys/#list-public-keys-for-a-user -// GitHub API docs: https://developer.github.com/v3/users/keys/#list-your-public-keys +// GitHub API docs: https://developer.github.com/v3/users/keys/#list-public-ssh-keys-for-the-authenticated-user func (s *UsersService) ListKeys(ctx context.Context, user string, opts *ListOptions) ([]*Key, *Response, error) { var u string if user != "" { @@ -57,7 +57,7 @@ func (s *UsersService) ListKeys(ctx context.Context, user string, opts *ListOpti // GetKey fetches a single public key. // -// GitHub API docs: https://developer.github.com/v3/users/keys/#get-a-single-public-key +// GitHub API docs: https://developer.github.com/v3/users/keys/#get-a-public-ssh-key-for-the-authenticated-user func (s *UsersService) GetKey(ctx context.Context, id int64) (*Key, *Response, error) { u := fmt.Sprintf("user/keys/%v", id) @@ -77,7 +77,7 @@ func (s *UsersService) GetKey(ctx context.Context, id int64) (*Key, *Response, e // CreateKey adds a public key for the authenticated user. // -// GitHub API docs: https://developer.github.com/v3/users/keys/#create-a-public-key +// GitHub API docs: https://developer.github.com/v3/users/keys/#create-a-public-ssh-key-for-the-authenticated-user func (s *UsersService) CreateKey(ctx context.Context, key *Key) (*Key, *Response, error) { u := "user/keys" @@ -97,7 +97,7 @@ func (s *UsersService) CreateKey(ctx context.Context, key *Key) (*Key, *Response // DeleteKey deletes a public key. // -// GitHub API docs: https://developer.github.com/v3/users/keys/#delete-a-public-key +// GitHub API docs: https://developer.github.com/v3/users/keys/#delete-a-public-ssh-key-for-the-authenticated-user func (s *UsersService) DeleteKey(ctx context.Context, id int64) (*Response, error) { u := fmt.Sprintf("user/keys/%v", id) diff --git a/update-urls/main.go b/update-urls/main.go index 5309178f5fa..c9455cf4fd4 100644 --- a/update-urls/main.go +++ b/update-urls/main.go @@ -967,6 +967,8 @@ func processCallExpr(expr *ast.CallExpr) (recv, funcName string, args []string) if r == "fmt" && fn == "Sprintf" && len(as) > 0 { // Special case - return format string. args = append(args, as[0]) } + case *ast.CompositeLit: + logf("processCallExpr: *ast.CompositeLit: %#v", arg) // Type, Lbrace, Elts, Rbrace, Incomplete case *ast.Ident: // NamePos, Name, Obj args = append(args, arg.Name) case *ast.MapType: From c4f1bb0ddd33a860942f3734d6f7ea54a5d51ea6 Mon Sep 17 00:00:00 2001 From: Jake Krammer Date: Tue, 7 Jul 2020 18:48:09 -0700 Subject: [PATCH 0201/1468] Handle package webhook (#1569) Fixes: #1550. --- github/event.go | 2 + github/event_types.go | 16 ++ github/github-accessors.go | 472 ++++++++++++++++++++++++++++++++ github/github-stringify_test.go | 99 +++++++ github/messages.go | 1 + github/messages_test.go | 4 + github/packages.go | 101 +++++++ 7 files changed, 695 insertions(+) create mode 100644 github/packages.go diff --git a/github/event.go b/github/event.go index 848fa6daeee..3b96b029ab9 100644 --- a/github/event.go +++ b/github/event.go @@ -76,6 +76,8 @@ func (e *Event) ParsePayload() (payload interface{}, err error) { payload = &OrganizationEvent{} case "OrgBlockEvent": payload = &OrgBlockEvent{} + case "PackageEvent": + payload = &PackageEvent{} case "PageBuildEvent": payload = &PageBuildEvent{} case "PingEvent": diff --git a/github/event_types.go b/github/event_types.go index bbb25af2a7e..fe6991f535b 100644 --- a/github/event_types.go +++ b/github/event_types.go @@ -468,6 +468,22 @@ type OrgBlockEvent struct { Installation *Installation `json:"installation,omitempty"` } +// PackageEvent represents activity related to GitHub Packages. +// The Webhook event name is "package". +// +// This event is triggered when a GitHub Package is published or updated. +// +// GitHub API docs: https://developer.github.com/webhooks/event-payloads/#package +type PackageEvent struct { + // Action is the action that was performed. + // Can be "published" or "updated". + Action *string `json:"action,omitempty"` + Package *Package `json:"package,omitempty"` + Repo *Repository `json:"repository,omitempty"` + Org *Organization `json:"organization,omitempty"` + Sender *User `json:"sender,omitempty"` +} + // PageBuildEvent represents an attempted build of a GitHub Pages site, whether // successful or not. // The Webhook event name is "page_build". diff --git a/github/github-accessors.go b/github/github-accessors.go index 3e2e03400af..8c591ce838a 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -7172,6 +7172,478 @@ func (o *OrgStats) GetTotalTeams() int { return *o.TotalTeams } +// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise. +func (p *Package) GetCreatedAt() Timestamp { + if p == nil || p.CreatedAt == nil { + return Timestamp{} + } + return *p.CreatedAt +} + +// GetHTMLURL returns the HTMLURL field if it's non-nil, zero value otherwise. +func (p *Package) GetHTMLURL() string { + if p == nil || p.HTMLURL == nil { + return "" + } + return *p.HTMLURL +} + +// GetID returns the ID field if it's non-nil, zero value otherwise. +func (p *Package) GetID() int64 { + if p == nil || p.ID == nil { + return 0 + } + return *p.ID +} + +// GetName returns the Name field if it's non-nil, zero value otherwise. +func (p *Package) GetName() string { + if p == nil || p.Name == nil { + return "" + } + return *p.Name +} + +// GetOwner returns the Owner field. +func (p *Package) GetOwner() *User { + if p == nil { + return nil + } + return p.Owner +} + +// GetPackageType returns the PackageType field if it's non-nil, zero value otherwise. +func (p *Package) GetPackageType() string { + if p == nil || p.PackageType == nil { + return "" + } + return *p.PackageType +} + +// GetPackageVersion returns the PackageVersion field. +func (p *Package) GetPackageVersion() *PackageVersion { + if p == nil { + return nil + } + return p.PackageVersion +} + +// GetRegistry returns the Registry field. +func (p *Package) GetRegistry() *PackageRegistry { + if p == nil { + return nil + } + return p.Registry +} + +// GetUpdatedAt returns the UpdatedAt field if it's non-nil, zero value otherwise. +func (p *Package) GetUpdatedAt() Timestamp { + if p == nil || p.UpdatedAt == nil { + return Timestamp{} + } + return *p.UpdatedAt +} + +// GetAction returns the Action field if it's non-nil, zero value otherwise. +func (p *PackageEvent) GetAction() string { + if p == nil || p.Action == nil { + return "" + } + return *p.Action +} + +// GetOrg returns the Org field. +func (p *PackageEvent) GetOrg() *Organization { + if p == nil { + return nil + } + return p.Org +} + +// GetPackage returns the Package field. +func (p *PackageEvent) GetPackage() *Package { + if p == nil { + return nil + } + return p.Package +} + +// GetRepo returns the Repo field. +func (p *PackageEvent) GetRepo() *Repository { + if p == nil { + return nil + } + return p.Repo +} + +// GetSender returns the Sender field. +func (p *PackageEvent) GetSender() *User { + if p == nil { + return nil + } + return p.Sender +} + +// GetAuthor returns the Author field. +func (p *PackageFile) GetAuthor() *User { + if p == nil { + return nil + } + return p.Author +} + +// GetContentType returns the ContentType field if it's non-nil, zero value otherwise. +func (p *PackageFile) GetContentType() string { + if p == nil || p.ContentType == nil { + return "" + } + return *p.ContentType +} + +// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise. +func (p *PackageFile) GetCreatedAt() Timestamp { + if p == nil || p.CreatedAt == nil { + return Timestamp{} + } + return *p.CreatedAt +} + +// GetDownloadURL returns the DownloadURL field if it's non-nil, zero value otherwise. +func (p *PackageFile) GetDownloadURL() string { + if p == nil || p.DownloadURL == nil { + return "" + } + return *p.DownloadURL +} + +// GetID returns the ID field if it's non-nil, zero value otherwise. +func (p *PackageFile) GetID() int64 { + if p == nil || p.ID == nil { + return 0 + } + return *p.ID +} + +// GetMD5 returns the MD5 field if it's non-nil, zero value otherwise. +func (p *PackageFile) GetMD5() string { + if p == nil || p.MD5 == nil { + return "" + } + return *p.MD5 +} + +// GetName returns the Name field if it's non-nil, zero value otherwise. +func (p *PackageFile) GetName() string { + if p == nil || p.Name == nil { + return "" + } + return *p.Name +} + +// GetSHA1 returns the SHA1 field if it's non-nil, zero value otherwise. +func (p *PackageFile) GetSHA1() string { + if p == nil || p.SHA1 == nil { + return "" + } + return *p.SHA1 +} + +// GetSHA256 returns the SHA256 field if it's non-nil, zero value otherwise. +func (p *PackageFile) GetSHA256() string { + if p == nil || p.SHA256 == nil { + return "" + } + return *p.SHA256 +} + +// GetSize returns the Size field if it's non-nil, zero value otherwise. +func (p *PackageFile) GetSize() int64 { + if p == nil || p.Size == nil { + return 0 + } + return *p.Size +} + +// GetState returns the State field if it's non-nil, zero value otherwise. +func (p *PackageFile) GetState() string { + if p == nil || p.State == nil { + return "" + } + return *p.State +} + +// GetUpdatedAt returns the UpdatedAt field if it's non-nil, zero value otherwise. +func (p *PackageFile) GetUpdatedAt() Timestamp { + if p == nil || p.UpdatedAt == nil { + return Timestamp{} + } + return *p.UpdatedAt +} + +// GetAboutURL returns the AboutURL field if it's non-nil, zero value otherwise. +func (p *PackageRegistry) GetAboutURL() string { + if p == nil || p.AboutURL == nil { + return "" + } + return *p.AboutURL +} + +// GetName returns the Name field if it's non-nil, zero value otherwise. +func (p *PackageRegistry) GetName() string { + if p == nil || p.Name == nil { + return "" + } + return *p.Name +} + +// GetType returns the Type field if it's non-nil, zero value otherwise. +func (p *PackageRegistry) GetType() string { + if p == nil || p.Type == nil { + return "" + } + return *p.Type +} + +// GetURL returns the URL field if it's non-nil, zero value otherwise. +func (p *PackageRegistry) GetURL() string { + if p == nil || p.URL == nil { + return "" + } + return *p.URL +} + +// GetVendor returns the Vendor field if it's non-nil, zero value otherwise. +func (p *PackageRegistry) GetVendor() string { + if p == nil || p.Vendor == nil { + return "" + } + return *p.Vendor +} + +// GetAuthor returns the Author field. +func (p *PackageRelease) GetAuthor() *User { + if p == nil { + return nil + } + return p.Author +} + +// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise. +func (p *PackageRelease) GetCreatedAt() Timestamp { + if p == nil || p.CreatedAt == nil { + return Timestamp{} + } + return *p.CreatedAt +} + +// GetDraft returns the Draft field if it's non-nil, zero value otherwise. +func (p *PackageRelease) GetDraft() bool { + if p == nil || p.Draft == nil { + return false + } + return *p.Draft +} + +// GetHTMLURL returns the HTMLURL field if it's non-nil, zero value otherwise. +func (p *PackageRelease) GetHTMLURL() string { + if p == nil || p.HTMLURL == nil { + return "" + } + return *p.HTMLURL +} + +// GetID returns the ID field if it's non-nil, zero value otherwise. +func (p *PackageRelease) GetID() int64 { + if p == nil || p.ID == nil { + return 0 + } + return *p.ID +} + +// GetName returns the Name field if it's non-nil, zero value otherwise. +func (p *PackageRelease) GetName() string { + if p == nil || p.Name == nil { + return "" + } + return *p.Name +} + +// GetPrerelease returns the Prerelease field if it's non-nil, zero value otherwise. +func (p *PackageRelease) GetPrerelease() bool { + if p == nil || p.Prerelease == nil { + return false + } + return *p.Prerelease +} + +// GetPublishedAt returns the PublishedAt field if it's non-nil, zero value otherwise. +func (p *PackageRelease) GetPublishedAt() Timestamp { + if p == nil || p.PublishedAt == nil { + return Timestamp{} + } + return *p.PublishedAt +} + +// GetTagName returns the TagName field if it's non-nil, zero value otherwise. +func (p *PackageRelease) GetTagName() string { + if p == nil || p.TagName == nil { + return "" + } + return *p.TagName +} + +// GetTargetCommitish returns the TargetCommitish field if it's non-nil, zero value otherwise. +func (p *PackageRelease) GetTargetCommitish() string { + if p == nil || p.TargetCommitish == nil { + return "" + } + return *p.TargetCommitish +} + +// GetURL returns the URL field if it's non-nil, zero value otherwise. +func (p *PackageRelease) GetURL() string { + if p == nil || p.URL == nil { + return "" + } + return *p.URL +} + +// GetAuthor returns the Author field. +func (p *PackageVersion) GetAuthor() *User { + if p == nil { + return nil + } + return p.Author +} + +// GetBody returns the Body field if it's non-nil, zero value otherwise. +func (p *PackageVersion) GetBody() string { + if p == nil || p.Body == nil { + return "" + } + return *p.Body +} + +// GetBodyHTML returns the BodyHTML field if it's non-nil, zero value otherwise. +func (p *PackageVersion) GetBodyHTML() string { + if p == nil || p.BodyHTML == nil { + return "" + } + return *p.BodyHTML +} + +// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise. +func (p *PackageVersion) GetCreatedAt() Timestamp { + if p == nil || p.CreatedAt == nil { + return Timestamp{} + } + return *p.CreatedAt +} + +// GetDraft returns the Draft field if it's non-nil, zero value otherwise. +func (p *PackageVersion) GetDraft() bool { + if p == nil || p.Draft == nil { + return false + } + return *p.Draft +} + +// GetHTMLURL returns the HTMLURL field if it's non-nil, zero value otherwise. +func (p *PackageVersion) GetHTMLURL() string { + if p == nil || p.HTMLURL == nil { + return "" + } + return *p.HTMLURL +} + +// GetID returns the ID field if it's non-nil, zero value otherwise. +func (p *PackageVersion) GetID() int64 { + if p == nil || p.ID == nil { + return 0 + } + return *p.ID +} + +// GetInstallationCommand returns the InstallationCommand field if it's non-nil, zero value otherwise. +func (p *PackageVersion) GetInstallationCommand() string { + if p == nil || p.InstallationCommand == nil { + return "" + } + return *p.InstallationCommand +} + +// GetManifest returns the Manifest field if it's non-nil, zero value otherwise. +func (p *PackageVersion) GetManifest() string { + if p == nil || p.Manifest == nil { + return "" + } + return *p.Manifest +} + +// GetPrerelease returns the Prerelease field if it's non-nil, zero value otherwise. +func (p *PackageVersion) GetPrerelease() bool { + if p == nil || p.Prerelease == nil { + return false + } + return *p.Prerelease +} + +// GetRelease returns the Release field. +func (p *PackageVersion) GetRelease() *PackageRelease { + if p == nil { + return nil + } + return p.Release +} + +// GetSummary returns the Summary field if it's non-nil, zero value otherwise. +func (p *PackageVersion) GetSummary() string { + if p == nil || p.Summary == nil { + return "" + } + return *p.Summary +} + +// GetTagName returns the TagName field if it's non-nil, zero value otherwise. +func (p *PackageVersion) GetTagName() string { + if p == nil || p.TagName == nil { + return "" + } + return *p.TagName +} + +// GetTargetCommitish returns the TargetCommitish field if it's non-nil, zero value otherwise. +func (p *PackageVersion) GetTargetCommitish() string { + if p == nil || p.TargetCommitish == nil { + return "" + } + return *p.TargetCommitish +} + +// GetTargetOID returns the TargetOID field if it's non-nil, zero value otherwise. +func (p *PackageVersion) GetTargetOID() string { + if p == nil || p.TargetOID == nil { + return "" + } + return *p.TargetOID +} + +// GetUpdatedAt returns the UpdatedAt field if it's non-nil, zero value otherwise. +func (p *PackageVersion) GetUpdatedAt() Timestamp { + if p == nil || p.UpdatedAt == nil { + return Timestamp{} + } + return *p.UpdatedAt +} + +// GetVersion returns the Version field if it's non-nil, zero value otherwise. +func (p *PackageVersion) GetVersion() string { + if p == nil || p.Version == nil { + return "" + } + return *p.Version +} + // GetAction returns the Action field if it's non-nil, zero value otherwise. func (p *Page) GetAction() string { if p == nil || p.Action == nil { diff --git a/github/github-stringify_test.go b/github/github-stringify_test.go index 0d64461b5e1..6b4ac2dab2f 100644 --- a/github/github-stringify_test.go +++ b/github/github-stringify_test.go @@ -897,6 +897,105 @@ func TestOrganization_String(t *testing.T) { } } +func TestPackage_String(t *testing.T) { + v := Package{ + ID: Int64(0), + Name: String(""), + PackageType: String(""), + HTMLURL: String(""), + CreatedAt: &Timestamp{}, + UpdatedAt: &Timestamp{}, + Owner: &User{}, + PackageVersion: &PackageVersion{}, + Registry: &PackageRegistry{}, + } + want := `github.Package{ID:0, Name:"", PackageType:"", HTMLURL:"", CreatedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, UpdatedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, Owner:github.User{}, PackageVersion:github.PackageVersion{}, Registry:github.PackageRegistry{}}` + if got := v.String(); got != want { + t.Errorf("Package.String = %v, want %v", got, want) + } +} + +func TestPackageFile_String(t *testing.T) { + v := PackageFile{ + DownloadURL: String(""), + ID: Int64(0), + Name: String(""), + SHA256: String(""), + SHA1: String(""), + MD5: String(""), + ContentType: String(""), + State: String(""), + Author: &User{}, + Size: Int64(0), + CreatedAt: &Timestamp{}, + UpdatedAt: &Timestamp{}, + } + want := `github.PackageFile{DownloadURL:"", ID:0, Name:"", SHA256:"", SHA1:"", MD5:"", ContentType:"", State:"", Author:github.User{}, Size:0, CreatedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, UpdatedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}}` + if got := v.String(); got != want { + t.Errorf("PackageFile.String = %v, want %v", got, want) + } +} + +func TestPackageRegistry_String(t *testing.T) { + v := PackageRegistry{ + AboutURL: String(""), + Name: String(""), + Type: String(""), + URL: String(""), + Vendor: String(""), + } + want := `github.PackageRegistry{AboutURL:"", Name:"", Type:"", URL:"", Vendor:""}` + if got := v.String(); got != want { + t.Errorf("PackageRegistry.String = %v, want %v", got, want) + } +} + +func TestPackageRelease_String(t *testing.T) { + v := PackageRelease{ + URL: String(""), + HTMLURL: String(""), + ID: Int64(0), + TagName: String(""), + TargetCommitish: String(""), + Name: String(""), + Draft: Bool(false), + Author: &User{}, + Prerelease: Bool(false), + CreatedAt: &Timestamp{}, + PublishedAt: &Timestamp{}, + } + want := `github.PackageRelease{URL:"", HTMLURL:"", ID:0, TagName:"", TargetCommitish:"", Name:"", Draft:false, Author:github.User{}, Prerelease:false, CreatedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, PublishedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}}` + if got := v.String(); got != want { + t.Errorf("PackageRelease.String = %v, want %v", got, want) + } +} + +func TestPackageVersion_String(t *testing.T) { + v := PackageVersion{ + ID: Int64(0), + Version: String(""), + Summary: String(""), + Body: String(""), + BodyHTML: String(""), + Release: &PackageRelease{}, + Manifest: String(""), + HTMLURL: String(""), + TagName: String(""), + TargetCommitish: String(""), + TargetOID: String(""), + Draft: Bool(false), + Prerelease: Bool(false), + CreatedAt: &Timestamp{}, + UpdatedAt: &Timestamp{}, + Author: &User{}, + InstallationCommand: String(""), + } + want := `github.PackageVersion{ID:0, Version:"", Summary:"", Body:"", BodyHTML:"", Release:github.PackageRelease{}, Manifest:"", HTMLURL:"", TagName:"", TargetCommitish:"", TargetOID:"", Draft:false, Prerelease:false, CreatedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, UpdatedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, Author:github.User{}, InstallationCommand:""}` + if got := v.String(); got != want { + t.Errorf("PackageVersion.String = %v, want %v", got, want) + } +} + func TestPageStats_String(t *testing.T) { v := PageStats{ TotalPages: Int(0), diff --git a/github/messages.go b/github/messages.go index 8ae80452184..2c1c7a7e6f5 100644 --- a/github/messages.go +++ b/github/messages.go @@ -64,6 +64,7 @@ var ( "milestone": "MilestoneEvent", "organization": "OrganizationEvent", "org_block": "OrgBlockEvent", + "package": "PackageEvent", "page_build": "PageBuildEvent", "ping": "PingEvent", "project": "ProjectEvent", diff --git a/github/messages_test.go b/github/messages_test.go index e0650048efc..9a0fd74afd2 100644 --- a/github/messages_test.go +++ b/github/messages_test.go @@ -275,6 +275,10 @@ func TestParseWebHook(t *testing.T) { payload: &OrgBlockEvent{}, messageType: "org_block", }, + { + payload: &PackageEvent{}, + messageType: "package", + }, { payload: &PageBuildEvent{}, messageType: "page_build", diff --git a/github/packages.go b/github/packages.go new file mode 100644 index 00000000000..446e4faa231 --- /dev/null +++ b/github/packages.go @@ -0,0 +1,101 @@ +// Copyright 2020 The go-github AUTHORS. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package github + +// Package represents a GitHub package. +type Package struct { + ID *int64 `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + PackageType *string `json:"package_type,omitempty"` + HTMLURL *string `json:"html_url,omitempty"` + CreatedAt *Timestamp `json:"created_at,omitempty"` + UpdatedAt *Timestamp `json:"updated_at,omitempty"` + Owner *User `json:"owner,omitempty"` + PackageVersion *PackageVersion `json:"package_version,omitempty"` + Registry *PackageRegistry `json:"registry,omitempty"` +} + +func (p Package) String() string { + return Stringify(p) +} + +// PackageVersion represents a GitHub package version. +type PackageVersion struct { + ID *int64 `json:"id,omitempty"` + Version *string `json:"version,omitempty"` + Summary *string `json:"summary,omitempty"` + Body *string `json:"body,omitempty"` + BodyHTML *string `json:"body_html,omitempty"` + Release *PackageRelease `json:"release,omitempty"` + Manifest *string `json:"manifest,omitempty"` + HTMLURL *string `json:"html_url,omitempty"` + TagName *string `json:"tag_name,omitempty"` + TargetCommitish *string `json:"target_commitish,omitempty"` + TargetOID *string `json:"target_oid,omitempty"` + Draft *bool `json:"draft,omitempty"` + Prerelease *bool `json:"prerelease,omitempty"` + CreatedAt *Timestamp `json:"created_at,omitempty"` + UpdatedAt *Timestamp `json:"updated_at,omitempty"` + PackageFiles []*PackageFile `json:"package_files,omitempty"` + Author *User `json:"author,omitempty"` + InstallationCommand *string `json:"installation_command,omitempty"` +} + +func (pv PackageVersion) String() string { + return Stringify(pv) +} + +// PackageRelease represents a GitHub package version release. +type PackageRelease struct { + URL *string `json:"url,omitempty"` + HTMLURL *string `json:"html_url,omitempty"` + ID *int64 `json:"id,omitempty"` + TagName *string `json:"tag_name,omitempty"` + TargetCommitish *string `json:"target_commitish,omitempty"` + Name *string `json:"name,omitempty"` + Draft *bool `json:"draft,omitempty"` + Author *User `json:"author,omitempty"` + Prerelease *bool `json:"prerelease,omitempty"` + CreatedAt *Timestamp `json:"created_at,omitempty"` + PublishedAt *Timestamp `json:"published_at,omitempty"` +} + +func (r PackageRelease) String() string { + return Stringify(r) +} + +// PackageFile represents a GitHub package version release file. +type PackageFile struct { + DownloadURL *string `json:"download_url,omitempty"` + ID *int64 `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + SHA256 *string `json:"sha256,omitempty"` + SHA1 *string `json:"sha1,omitempty"` + MD5 *string `json:"md5,omitempty"` + ContentType *string `json:"content_type,omitempty"` + State *string `json:"state,omitempty"` + Author *User `json:"author,omitempty"` + Size *int64 `json:"size,omitempty"` + CreatedAt *Timestamp `json:"created_at,omitempty"` + UpdatedAt *Timestamp `json:"updated_at,omitempty"` +} + +func (pf PackageFile) String() string { + return Stringify(pf) +} + +// PackageRegistry represents a GitHub package registry. +type PackageRegistry struct { + AboutURL *string `json:"about_url,omitempty"` + Name *string `json:"name,omitempty"` + Type *string `json:"type,omitempty"` + URL *string `json:"url,omitempty"` + Vendor *string `json:"vendor,omitempty"` +} + +func (r PackageRegistry) String() string { + return Stringify(r) +} From e881974953e6ab6d1a6a1610e98ed6401a3aa1ba Mon Sep 17 00:00:00 2001 From: angie pinilla Date: Wed, 15 Jul 2020 20:47:50 -0400 Subject: [PATCH 0202/1468] Revert changes in #1530 (#1571) --- github/repos.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/github/repos.go b/github/repos.go index 156e6e3ec44..0956d7c6fe9 100644 --- a/github/repos.go +++ b/github/repos.go @@ -864,9 +864,9 @@ type BranchRestrictions struct { // different from the response structure. type BranchRestrictionsRequest struct { // The list of user logins with push access. (Required; use []string{} instead of nil for empty list.) - Users []string `json:"users,omitempty"` + Users []string `json:"users"` // The list of team slugs with push access. (Required; use []string{} instead of nil for empty list.) - Teams []string `json:"teams,omitempty"` + Teams []string `json:"teams"` // The list of app slugs with push access. Apps []string `json:"apps,omitempty"` } From 4a2bf0671d35d62e3c8807cf7df4df6c516ff42a Mon Sep 17 00:00:00 2001 From: Simon Davis Date: Sat, 25 Jul 2020 15:43:12 -0700 Subject: [PATCH 0203/1468] Add rocket and eyes reactions (#1586) --- github/github-accessors.go | 16 ++++++++++++++++ github/pulls_comments_test.go | 4 ++++ github/reactions.go | 16 +++++++++------- github/reactions_test.go | 4 ++++ 4 files changed, 33 insertions(+), 7 deletions(-) diff --git a/github/github-accessors.go b/github/github-accessors.go index 8c591ce838a..1dee732df4c 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -10364,6 +10364,14 @@ func (r *Reactions) GetConfused() int { return *r.Confused } +// GetEyes returns the Eyes field if it's non-nil, zero value otherwise. +func (r *Reactions) GetEyes() int { + if r == nil || r.Eyes == nil { + return 0 + } + return *r.Eyes +} + // GetHeart returns the Heart field if it's non-nil, zero value otherwise. func (r *Reactions) GetHeart() int { if r == nil || r.Heart == nil { @@ -10404,6 +10412,14 @@ func (r *Reactions) GetPlusOne() int { return *r.PlusOne } +// GetRocket returns the Rocket field if it's non-nil, zero value otherwise. +func (r *Reactions) GetRocket() int { + if r == nil || r.Rocket == nil { + return 0 + } + return *r.Rocket +} + // GetTotalCount returns the TotalCount field if it's non-nil, zero value otherwise. func (r *Reactions) GetTotalCount() int { if r == nil || r.TotalCount == nil { diff --git a/github/pulls_comments_test.go b/github/pulls_comments_test.go index ace57003828..7d3a7c76f44 100644 --- a/github/pulls_comments_test.go +++ b/github/pulls_comments_test.go @@ -29,6 +29,8 @@ func TestPullComments_marshall(t *testing.T) { Confused: Int(0), Heart: Int(0), Hooray: Int(0), + Rocket: Int(0), + Eyes: Int(0), URL: String("u"), } @@ -116,6 +118,8 @@ func TestPullComments_marshall(t *testing.T) { "confused": 0, "heart": 0, "hooray": 0, + "rocket": 0, + "eyes": 0, "url": "u" }, "created_at": "2002-02-10T15:30:00Z", diff --git a/github/reactions.go b/github/reactions.go index ce0a7518295..47eb41f0ee5 100644 --- a/github/reactions.go +++ b/github/reactions.go @@ -25,7 +25,7 @@ type Reaction struct { NodeID *string `json:"node_id,omitempty"` // Content is the type of reaction. // Possible values are: - // "+1", "-1", "laugh", "confused", "heart", "hooray". + // "+1", "-1", "laugh", "confused", "heart", "hooray", "rocket", or "eyes". Content *string `json:"content,omitempty"` } @@ -38,6 +38,8 @@ type Reactions struct { Confused *int `json:"confused,omitempty"` Heart *int `json:"heart,omitempty"` Hooray *int `json:"hooray,omitempty"` + Rocket *int `json:"rocket,omitempty"` + Eyes *int `json:"eyes,omitempty"` URL *string `json:"url,omitempty"` } @@ -86,7 +88,7 @@ func (s *ReactionsService) ListCommentReactions(ctx context.Context, owner, repo // CreateCommentReaction creates a reaction for a commit comment. // Note that if you have already created a reaction of type content, the // previously created reaction will be returned with Status: 200 OK. -// The content should have one of the following values: "+1", "-1", "laugh", "confused", "heart", "hooray". +// The content should have one of the following values: "+1", "-1", "laugh", "confused", "heart", "hooray", "rocket", or "eyes". // // GitHub API docs: https://developer.github.com/v3/reactions/#create-reaction-for-a-commit-comment func (s *ReactionsService) CreateCommentReaction(ctx context.Context, owner, repo string, id int64, content string) (*Reaction, *Response, error) { @@ -158,7 +160,7 @@ func (s *ReactionsService) ListIssueReactions(ctx context.Context, owner, repo s // CreateIssueReaction creates a reaction for an issue. // Note that if you have already created a reaction of type content, the // previously created reaction will be returned with Status: 200 OK. -// The content should have one of the following values: "+1", "-1", "laugh", "confused", "heart", "hooray". +// The content should have one of the following values: "+1", "-1", "laugh", "confused", "heart", "hooray", "rocket", or "eyes". // // GitHub API docs: https://developer.github.com/v3/reactions/#create-reaction-for-an-issue func (s *ReactionsService) CreateIssueReaction(ctx context.Context, owner, repo string, number int, content string) (*Reaction, *Response, error) { @@ -230,7 +232,7 @@ func (s *ReactionsService) ListIssueCommentReactions(ctx context.Context, owner, // CreateIssueCommentReaction creates a reaction for an issue comment. // Note that if you have already created a reaction of type content, the // previously created reaction will be returned with Status: 200 OK. -// The content should have one of the following values: "+1", "-1", "laugh", "confused", "heart", "hooray". +// The content should have one of the following values: "+1", "-1", "laugh", "confused", "heart", "hooray", "rocket", or "eyes". // // GitHub API docs: https://developer.github.com/v3/reactions/#create-reaction-for-an-issue-comment func (s *ReactionsService) CreateIssueCommentReaction(ctx context.Context, owner, repo string, id int64, content string) (*Reaction, *Response, error) { @@ -302,7 +304,7 @@ func (s *ReactionsService) ListPullRequestCommentReactions(ctx context.Context, // CreatePullRequestCommentReaction creates a reaction for a pull request review comment. // Note that if you have already created a reaction of type content, the // previously created reaction will be returned with Status: 200 OK. -// The content should have one of the following values: "+1", "-1", "laugh", "confused", "heart", "hooray". +// The content should have one of the following values: "+1", "-1", "laugh", "confused", "heart", "hooray", "rocket", or "eyes". // // GitHub API docs: https://developer.github.com/v3/reactions/#create-reaction-for-a-pull-request-review-comment func (s *ReactionsService) CreatePullRequestCommentReaction(ctx context.Context, owner, repo string, id int64, content string) (*Reaction, *Response, error) { @@ -371,7 +373,7 @@ func (s *ReactionsService) ListTeamDiscussionReactions(ctx context.Context, team } // CreateTeamDiscussionReaction creates a reaction for a team discussion. -// The content should have one of the following values: "+1", "-1", "laugh", "confused", "heart", "hooray". +// The content should have one of the following values: "+1", "-1", "laugh", "confused", "heart", "hooray", "rocket", or "eyes". // // GitHub API docs: https://developer.github.com/v3/reactions/#create-reaction-for-a-team-discussion-legacy func (s *ReactionsService) CreateTeamDiscussionReaction(ctx context.Context, teamID int64, discussionNumber int, content string) (*Reaction, *Response, error) { @@ -438,7 +440,7 @@ func (s *ReactionsService) ListTeamDiscussionCommentReactions(ctx context.Contex } // CreateTeamDiscussionCommentReaction creates a reaction for a team discussion comment. -// The content should have one of the following values: "+1", "-1", "laugh", "confused", "heart", "hooray". +// The content should have one of the following values: "+1", "-1", "laugh", "confused", "heart", "hooray", "rocket", or "eyes". // // GitHub API docs: https://developer.github.com/v3/reactions/#create-reaction-for-a-team-discussion-comment-legacy func (s *ReactionsService) CreateTeamDiscussionCommentReaction(ctx context.Context, teamID int64, discussionNumber, commentNumber int, content string) (*Reaction, *Response, error) { diff --git a/github/reactions_test.go b/github/reactions_test.go index ede3105e0df..9beaff73784 100644 --- a/github/reactions_test.go +++ b/github/reactions_test.go @@ -43,6 +43,8 @@ func TestReactions_Marshal(t *testing.T) { Confused: Int(1), Heart: Int(1), Hooray: Int(1), + Rocket: Int(1), + Eyes: Int(1), URL: String("u"), } @@ -54,6 +56,8 @@ func TestReactions_Marshal(t *testing.T) { "confused": 1, "heart": 1, "hooray": 1, + "rocket": 1, + "eyes": 1, "url": "u" }` From 954e7c82b2994a9f418f300c3f1e147f6a51bd29 Mon Sep 17 00:00:00 2001 From: "David J. M. Karlsen" Date: Mon, 3 Aug 2020 02:44:43 +0200 Subject: [PATCH 0204/1468] Add busy field to Runner (#1590) Fixes: #1589. --- github/actions_runners.go | 1 + github/github-accessors.go | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/github/actions_runners.go b/github/actions_runners.go index 2cac674e043..8960ac8eaa0 100644 --- a/github/actions_runners.go +++ b/github/actions_runners.go @@ -69,6 +69,7 @@ type Runner struct { Name *string `json:"name,omitempty"` OS *string `json:"os,omitempty"` Status *string `json:"status,omitempty"` + Busy *bool `json:"busy,omitempty"` } // Runners represents a collection of self-hosted runners for a repository. diff --git a/github/github-accessors.go b/github/github-accessors.go index 1dee732df4c..07687b6ae38 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -12324,6 +12324,14 @@ func (r *ReviewersRequest) GetNodeID() string { return *r.NodeID } +// GetBusy returns the Busy field if it's non-nil, zero value otherwise. +func (r *Runner) GetBusy() bool { + if r == nil || r.Busy == nil { + return false + } + return *r.Busy +} + // GetID returns the ID field if it's non-nil, zero value otherwise. func (r *Runner) GetID() int64 { if r == nil || r.ID == nil { From 512c5836f16ad8b37d4a009a55fefe1417ab30f5 Mon Sep 17 00:00:00 2001 From: Juan Date: Mon, 10 Aug 2020 19:42:07 -0400 Subject: [PATCH 0205/1468] Remove Sort & Direction Fields From IssueComments (#1584) --- github/github-accessors.go | 16 ---------------- github/issues_comments.go | 6 ------ github/issues_comments_test.go | 8 ++------ 3 files changed, 2 insertions(+), 28 deletions(-) diff --git a/github/github-accessors.go b/github/github-accessors.go index 07687b6ae38..8e35c555fca 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -5084,14 +5084,6 @@ func (i *IssueEvent) GetURL() string { return *i.URL } -// GetDirection returns the Direction field if it's non-nil, zero value otherwise. -func (i *IssueListCommentsOptions) GetDirection() string { - if i == nil || i.Direction == nil { - return "" - } - return *i.Direction -} - // GetSince returns the Since field if it's non-nil, zero value otherwise. func (i *IssueListCommentsOptions) GetSince() time.Time { if i == nil || i.Since == nil { @@ -5100,14 +5092,6 @@ func (i *IssueListCommentsOptions) GetSince() time.Time { return *i.Since } -// GetSort returns the Sort field if it's non-nil, zero value otherwise. -func (i *IssueListCommentsOptions) GetSort() string { - if i == nil || i.Sort == nil { - return "" - } - return *i.Sort -} - // GetAssignee returns the Assignee field if it's non-nil, zero value otherwise. func (i *IssueRequest) GetAssignee() string { if i == nil || i.Assignee == nil { diff --git a/github/issues_comments.go b/github/issues_comments.go index fc67511bf6d..eade48eed10 100644 --- a/github/issues_comments.go +++ b/github/issues_comments.go @@ -35,12 +35,6 @@ func (i IssueComment) String() string { // IssueListCommentsOptions specifies the optional parameters to the // IssuesService.ListComments method. type IssueListCommentsOptions struct { - // Sort specifies how to sort comments. Possible values are: created, updated. - Sort *string `url:"sort,omitempty"` - - // Direction in which to sort comments. Possible values are: asc, desc. - Direction *string `url:"direction,omitempty"` - // Since filters comments by time. Since *time.Time `url:"since,omitempty"` diff --git a/github/issues_comments_test.go b/github/issues_comments_test.go index 69acb24280e..2b5ec50c29c 100644 --- a/github/issues_comments_test.go +++ b/github/issues_comments_test.go @@ -23,18 +23,14 @@ func TestIssuesService_ListComments_allIssues(t *testing.T) { testMethod(t, r, "GET") testHeader(t, r, "Accept", mediaTypeReactionsPreview) testFormValues(t, r, values{ - "sort": "updated", - "direction": "desc", - "since": "2002-02-10T15:30:00Z", - "page": "2", + "since": "2002-02-10T15:30:00Z", + "page": "2", }) fmt.Fprint(w, `[{"id":1}]`) }) since := time.Date(2002, time.February, 10, 15, 30, 0, 0, time.UTC) opt := &IssueListCommentsOptions{ - Sort: String("updated"), - Direction: String("desc"), Since: &since, ListOptions: ListOptions{Page: 2}, } From e19d4dd52119e904f326181ea091b575acf632c6 Mon Sep 17 00:00:00 2001 From: Kumar Saurabh Date: Tue, 11 Aug 2020 18:14:37 +0530 Subject: [PATCH 0206/1468] Read response body for TCP connection reuse (#1576) --- github/github.go | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/github/github.go b/github/github.go index c68a80c7b99..fc642dc98f6 100644 --- a/github/github.go +++ b/github/github.go @@ -554,7 +554,21 @@ func (c *Client) Do(ctx context.Context, req *http.Request, v interface{}) (*Res return nil, err } - defer resp.Body.Close() + + defer func() { + // Ensure the response body is fully read and closed + // before we reconnect, so that we reuse the same TCP connection. + // Close the previous response's body. But read at least some of + // the body so if it's small the underlying TCP connection will be + // re-used. No need to check for errors: if it fails, the Transport + // won't reuse it anyway. + const maxBodySlurpSize = 2 << 10 + if resp.ContentLength == -1 || resp.ContentLength <= maxBodySlurpSize { + io.CopyN(ioutil.Discard, resp.Body, maxBodySlurpSize) + } + + resp.Body.Close() + }() response := newResponse(resp) From 6f77b2b280cae50544e55f0f8acae1191fb4b9e0 Mon Sep 17 00:00:00 2001 From: aprp Date: Sat, 15 Aug 2020 21:30:55 +0700 Subject: [PATCH 0207/1468] Add JSON marshal test for license (#1603) --- github/licenses_test.go | 94 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) diff --git a/github/licenses_test.go b/github/licenses_test.go index a71f6a4efba..5446ffd1f48 100644 --- a/github/licenses_test.go +++ b/github/licenses_test.go @@ -13,6 +13,100 @@ import ( "testing" ) +func TestRepositoryLicense_marshal(t *testing.T) { + testJSONMarshal(t, &RepositoryLicense{}, "{}") + + rl := &RepositoryLicense{ + Name: String("n"), + Path: String("p"), + SHA: String("s"), + Size: Int(1), + URL: String("u"), + HTMLURL: String("h"), + GitURL: String("g"), + DownloadURL: String("d"), + Type: String("t"), + Content: String("c"), + Encoding: String("e"), + License: &License{ + Key: String("k"), + Name: String("n"), + URL: String("u"), + SPDXID: String("s"), + HTMLURL: String("h"), + Featured: Bool(true), + Description: String("d"), + Implementation: String("i"), + Permissions: &[]string{"p"}, + Conditions: &[]string{"c"}, + Limitations: &[]string{"l"}, + Body: String("b"), + }, + } + want := `{ + "name": "n", + "path": "p", + "sha": "s", + "size": 1, + "url": "u", + "html_url": "h", + "git_url": "g", + "download_url": "d", + "type": "t", + "content": "c", + "encoding": "e", + "license": { + "key": "k", + "name": "n", + "url": "u", + "spdx_id": "s", + "html_url": "h", + "featured": true, + "description": "d", + "implementation": "i", + "permissions": ["p"], + "conditions": ["c"], + "limitations": ["l"], + "body": "b" + } + }` + testJSONMarshal(t, rl, want) +} + +func TestLicense_marshal(t *testing.T) { + testJSONMarshal(t, &License{}, "{}") + + l := &License{ + Key: String("k"), + Name: String("n"), + URL: String("u"), + SPDXID: String("s"), + HTMLURL: String("h"), + Featured: Bool(true), + Description: String("d"), + Implementation: String("i"), + Permissions: &[]string{"p"}, + Conditions: &[]string{"c"}, + Limitations: &[]string{"l"}, + Body: String("b"), + } + want := `{ + "key": "k", + "name": "n", + "url": "u", + "spdx_id": "s", + "html_url": "h", + "featured": true, + "description": "d", + "implementation": "i", + "permissions": ["p"], + "conditions": ["c"], + "limitations": ["l"], + "body": "b" + }` + testJSONMarshal(t, l, want) +} + func TestLicensesService_List(t *testing.T) { client, mux, _, teardown := setup() defer teardown() From 6cbf5c6e8870dc452a3efc3756b426251edad354 Mon Sep 17 00:00:00 2001 From: Asier Marruedo Date: Sat, 15 Aug 2020 23:12:23 +0200 Subject: [PATCH 0208/1468] Add support for Issue Import GitHub API (#1595) --- github/github-accessors.go | 168 ++++++++++++++++++++++++++++++++++++ github/github.go | 3 + github/issue_import.go | 152 ++++++++++++++++++++++++++++++++ github/issue_import_test.go | 144 +++++++++++++++++++++++++++++++ 4 files changed, 467 insertions(+) create mode 100644 github/issue_import.go create mode 100644 github/issue_import_test.go diff --git a/github/github-accessors.go b/github/github-accessors.go index 8e35c555fca..0c8e260ebf9 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -1460,6 +1460,14 @@ func (c *CombinedStatus) GetTotalCount() int { return *c.TotalCount } +// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise. +func (c *Comment) GetCreatedAt() time.Time { + if c == nil || c.CreatedAt == nil { + return time.Time{} + } + return *c.CreatedAt +} + // GetTotalCommitComments returns the TotalCommitComments field if it's non-nil, zero value otherwise. func (c *CommentStats) GetTotalCommitComments() int { if c == nil || c.TotalCommitComments == nil { @@ -5084,6 +5092,166 @@ func (i *IssueEvent) GetURL() string { return *i.URL } +// GetAssignee returns the Assignee field if it's non-nil, zero value otherwise. +func (i *IssueImport) GetAssignee() string { + if i == nil || i.Assignee == nil { + return "" + } + return *i.Assignee +} + +// GetClosed returns the Closed field if it's non-nil, zero value otherwise. +func (i *IssueImport) GetClosed() bool { + if i == nil || i.Closed == nil { + return false + } + return *i.Closed +} + +// GetClosedAt returns the ClosedAt field if it's non-nil, zero value otherwise. +func (i *IssueImport) GetClosedAt() time.Time { + if i == nil || i.ClosedAt == nil { + return time.Time{} + } + return *i.ClosedAt +} + +// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise. +func (i *IssueImport) GetCreatedAt() time.Time { + if i == nil || i.CreatedAt == nil { + return time.Time{} + } + return *i.CreatedAt +} + +// GetMilestone returns the Milestone field if it's non-nil, zero value otherwise. +func (i *IssueImport) GetMilestone() int { + if i == nil || i.Milestone == nil { + return 0 + } + return *i.Milestone +} + +// GetUpdatedAt returns the UpdatedAt field if it's non-nil, zero value otherwise. +func (i *IssueImport) GetUpdatedAt() time.Time { + if i == nil || i.UpdatedAt == nil { + return time.Time{} + } + return *i.UpdatedAt +} + +// GetCode returns the Code field if it's non-nil, zero value otherwise. +func (i *IssueImportError) GetCode() string { + if i == nil || i.Code == nil { + return "" + } + return *i.Code +} + +// GetField returns the Field field if it's non-nil, zero value otherwise. +func (i *IssueImportError) GetField() string { + if i == nil || i.Field == nil { + return "" + } + return *i.Field +} + +// GetLocation returns the Location field if it's non-nil, zero value otherwise. +func (i *IssueImportError) GetLocation() string { + if i == nil || i.Location == nil { + return "" + } + return *i.Location +} + +// GetResource returns the Resource field if it's non-nil, zero value otherwise. +func (i *IssueImportError) GetResource() string { + if i == nil || i.Resource == nil { + return "" + } + return *i.Resource +} + +// GetValue returns the Value field if it's non-nil, zero value otherwise. +func (i *IssueImportError) GetValue() string { + if i == nil || i.Value == nil { + return "" + } + return *i.Value +} + +// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise. +func (i *IssueImportResponse) GetCreatedAt() time.Time { + if i == nil || i.CreatedAt == nil { + return time.Time{} + } + return *i.CreatedAt +} + +// GetDocumentationURL returns the DocumentationURL field if it's non-nil, zero value otherwise. +func (i *IssueImportResponse) GetDocumentationURL() string { + if i == nil || i.DocumentationURL == nil { + return "" + } + return *i.DocumentationURL +} + +// GetID returns the ID field if it's non-nil, zero value otherwise. +func (i *IssueImportResponse) GetID() int { + if i == nil || i.ID == nil { + return 0 + } + return *i.ID +} + +// GetImportIssuesURL returns the ImportIssuesURL field if it's non-nil, zero value otherwise. +func (i *IssueImportResponse) GetImportIssuesURL() string { + if i == nil || i.ImportIssuesURL == nil { + return "" + } + return *i.ImportIssuesURL +} + +// GetMessage returns the Message field if it's non-nil, zero value otherwise. +func (i *IssueImportResponse) GetMessage() string { + if i == nil || i.Message == nil { + return "" + } + return *i.Message +} + +// GetRepositoryURL returns the RepositoryURL field if it's non-nil, zero value otherwise. +func (i *IssueImportResponse) GetRepositoryURL() string { + if i == nil || i.RepositoryURL == nil { + return "" + } + return *i.RepositoryURL +} + +// GetStatus returns the Status field if it's non-nil, zero value otherwise. +func (i *IssueImportResponse) GetStatus() string { + if i == nil || i.Status == nil { + return "" + } + return *i.Status +} + +// GetUpdatedAt returns the UpdatedAt field if it's non-nil, zero value otherwise. +func (i *IssueImportResponse) GetUpdatedAt() time.Time { + if i == nil || i.UpdatedAt == nil { + return time.Time{} + } + return *i.UpdatedAt +} + +// GetURL returns the URL field if it's non-nil, zero value otherwise. +func (i *IssueImportResponse) GetURL() string { + if i == nil || i.URL == nil { + return "" + } + return *i.URL +} + // GetSince returns the Since field if it's non-nil, zero value otherwise. func (i *IssueListCommentsOptions) GetSince() time.Time { if i == nil || i.Since == nil { diff --git a/github/github.go b/github/github.go index fc642dc98f6..b6abc8f4078 100644 --- a/github/github.go +++ b/github/github.go @@ -43,6 +43,7 @@ const ( mediaTypeV3Diff = "application/vnd.github.v3.diff" mediaTypeV3Patch = "application/vnd.github.v3.patch" mediaTypeOrgPermissionRepo = "application/vnd.github.v3.repository+json" + mediaTypeIssueImportAPI = "application/vnd.github.golden-comet-preview+json" // Media Type values to access preview APIs @@ -170,6 +171,7 @@ type Client struct { Git *GitService Gitignores *GitignoresService Interactions *InteractionsService + IssueImport *IssueImportService Issues *IssuesService Licenses *LicensesService Marketplace *MarketplaceService @@ -277,6 +279,7 @@ func NewClient(httpClient *http.Client) *Client { c.Git = (*GitService)(&c.common) c.Gitignores = (*GitignoresService)(&c.common) c.Interactions = (*InteractionsService)(&c.common) + c.IssueImport = (*IssueImportService)(&c.common) c.Issues = (*IssuesService)(&c.common) c.Licenses = (*LicensesService)(&c.common) c.Marketplace = &MarketplaceService{client: c} diff --git a/github/issue_import.go b/github/issue_import.go new file mode 100644 index 00000000000..a9810407cc8 --- /dev/null +++ b/github/issue_import.go @@ -0,0 +1,152 @@ +// Copyright 2020 The go-github AUTHORS. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package github + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "time" +) + +// IssueImportService handles communication with the issue import related +// methods of the Issue Import GitHub API. +type IssueImportService service + +// IssueImportRequest represents a request to create an issue. +// +// https://gist.github.com/jonmagic/5282384165e0f86ef105#supported-issue-and-comment-fields +type IssueImportRequest struct { + IssueImport IssueImport `json:"issue"` + Comments []*Comment `json:"comments,omitempty"` +} + +// IssueImport represents body of issue to import. +type IssueImport struct { + Title string `json:"title"` + Body string `json:"body"` + CreatedAt *time.Time `json:"created_at,omitempty"` + ClosedAt *time.Time `json:"closed_at,omitempty"` + UpdatedAt *time.Time `json:"updated_at,omitempty"` + Assignee *string `json:"assignee,omitempty"` + Milestone *int `json:"milestone,omitempty"` + Closed *bool `json:"closed,omitempty"` + Labels []string `json:"labels,omitempty"` +} + +// Comment represents comments of issue to import. +type Comment struct { + CreatedAt *time.Time `json:"created_at,omitempty"` + Body string `json:"body"` +} + +// IssueImportResponse represents the response of an issue import create request. +// +// https://gist.github.com/jonmagic/5282384165e0f86ef105#import-issue-response +type IssueImportResponse struct { + ID *int `json:"id,omitempty"` + Status *string `json:"status,omitempty"` + URL *string `json:"url,omitempty"` + ImportIssuesURL *string `json:"import_issues_url,omitempty"` + RepositoryURL *string `json:"repository_url,omitempty"` + CreatedAt *time.Time `json:"created_at,omitempty"` + UpdatedAt *time.Time `json:"updated_at,omitempty"` + Message *string `json:"message,omitempty"` + DocumentationURL *string `json:"documentation_url,omitempty"` + Errors []*IssueImportError `json:"errors,omitempty"` +} + +// IssueImportError represents errors of an issue import create request. +type IssueImportError struct { + Location *string `json:"location,omitempty"` + Resource *string `json:"resource,omitempty"` + Field *string `json:"field,omitempty"` + Value *string `json:"value,omitempty"` + Code *string `json:"code,omitempty"` +} + +// Create a new imported issue on the specified repository. +// +// https://gist.github.com/jonmagic/5282384165e0f86ef105#start-an-issue-import +func (s *IssueImportService) Create(ctx context.Context, owner, repo string, issue *IssueImportRequest) (*IssueImportResponse, *Response, error) { + u := fmt.Sprintf("repos/%v/%v/import/issues", owner, repo) + req, err := s.client.NewRequest("POST", u, issue) + if err != nil { + return nil, nil, err + } + + // TODO: remove custom Accept headers when APIs fully launch. + req.Header.Set("Accept", mediaTypeIssueImportAPI) + + i := new(IssueImportResponse) + resp, err := s.client.Do(ctx, req, i) + if err != nil { + aerr, ok := err.(*AcceptedError) + if ok { + decErr := json.Unmarshal(aerr.Raw, i) + if decErr != nil { + err = decErr + } + + return i, resp, nil + } + + return nil, resp, err + } + + return i, resp, nil +} + +// CheckStatus checks the status of an imported issue. +// +// https://gist.github.com/jonmagic/5282384165e0f86ef105#import-status-request +func (s *IssueImportService) CheckStatus(ctx context.Context, owner, repo string, issueID int64) (*IssueImportResponse, *Response, error) { + u := fmt.Sprintf("repos/%v/%v/import/issues/%v", owner, repo, issueID) + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + + // TODO: remove custom Accept headers when APIs fully launch. + req.Header.Set("Accept", mediaTypeIssueImportAPI) + + i := new(IssueImportResponse) + resp, err := s.client.Do(ctx, req, i) + if err != nil { + return nil, resp, err + } + + return i, resp, nil +} + +// CheckStatusSince checks the status of multiple imported issues since a given date. +// +// https://gist.github.com/jonmagic/5282384165e0f86ef105#check-status-of-multiple-issues +func (s *IssueImportService) CheckStatusSince(ctx context.Context, owner, repo string, since time.Time) ([]*IssueImportResponse, *Response, error) { + u := fmt.Sprintf("repos/%v/%v/import/issues?since=%v", owner, repo, since.Format("2006-01-02")) + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + + // TODO: remove custom Accept headers when APIs fully launch. + req.Header.Set("Accept", mediaTypeIssueImportAPI) + + var b bytes.Buffer + resp, err := s.client.Do(ctx, req, &b) + if err != nil { + return nil, resp, err + } + + var i []*IssueImportResponse + err = json.Unmarshal(b.Bytes(), &i) + if err != nil { + return nil, resp, err + } + + return i, resp, nil +} diff --git a/github/issue_import_test.go b/github/issue_import_test.go new file mode 100644 index 00000000000..5948ef44e6a --- /dev/null +++ b/github/issue_import_test.go @@ -0,0 +1,144 @@ +// Copyright 2020 The go-github AUTHORS. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package github + +import ( + "context" + "encoding/json" + "fmt" + "net/http" + "reflect" + "testing" + "time" +) + +func TestIssueImportService_Create(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + createdAt := time.Date(2020, time.August, 11, 15, 30, 0, 0, time.UTC) + input := &IssueImportRequest{ + IssueImport: IssueImport{ + Assignee: String("developer"), + Body: "Dummy description", + CreatedAt: &createdAt, + Labels: []string{"l1", "l2"}, + Milestone: Int(1), + Title: "Dummy Issue", + }, + Comments: []*Comment{{ + CreatedAt: &createdAt, + Body: "Comment body", + }}, + } + + mux.HandleFunc("/repos/o/r/import/issues", func(w http.ResponseWriter, r *http.Request) { + v := new(IssueImportRequest) + json.NewDecoder(r.Body).Decode(v) + testMethod(t, r, "POST") + testHeader(t, r, "Accept", mediaTypeIssueImportAPI) + if !reflect.DeepEqual(v, input) { + t.Errorf("Request body = %+v, want %+v", v, input) + } + + w.WriteHeader(http.StatusAccepted) + w.Write(issueImportResponseJSON) + }) + + got, _, err := client.IssueImport.Create(context.Background(), "o", "r", input) + if err != nil { + t.Errorf("Create returned error: %v", err) + } + + want := wantIssueImportResponse + if !reflect.DeepEqual(got, want) { + t.Errorf("Create = %+v, want %+v", got, want) + } +} + +func TestIssueImportService_Create_invalidOwner(t *testing.T) { + client, _, _, teardown := setup() + defer teardown() + + _, _, err := client.IssueImport.Create(context.Background(), "%", "r", nil) + testURLParseError(t, err) +} + +func TestIssueImportService_CheckStatus(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/repos/o/r/import/issues/3", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + testHeader(t, r, "Accept", mediaTypeIssueImportAPI) + w.WriteHeader(http.StatusOK) + w.Write(issueImportResponseJSON) + }) + + got, _, err := client.IssueImport.CheckStatus(context.Background(), "o", "r", 3) + if err != nil { + t.Errorf("CheckStatus returned error: %v", err) + } + + want := wantIssueImportResponse + if !reflect.DeepEqual(got, want) { + t.Errorf("CheckStatus = %+v, want %+v", got, want) + } +} + +func TestIssueImportService_CheckStatus_invalidOwner(t *testing.T) { + client, _, _, teardown := setup() + defer teardown() + + _, _, err := client.IssueImport.CheckStatus(context.Background(), "%", "r", 1) + testURLParseError(t, err) +} + +func TestIssueImportService_CheckStatusSince(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/repos/o/r/import/issues", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + testHeader(t, r, "Accept", mediaTypeIssueImportAPI) + w.WriteHeader(http.StatusOK) + w.Write([]byte(fmt.Sprintf("[%s]", issueImportResponseJSON))) + }) + + got, _, err := client.IssueImport.CheckStatusSince(context.Background(), "o", "r", time.Now()) + if err != nil { + t.Errorf("CheckStatusSince returned error: %v", err) + } + + want := []*IssueImportResponse{wantIssueImportResponse} + if !reflect.DeepEqual(want, got) { + t.Errorf("CheckStatusSince = %v, want = %v", got, want) + } +} + +func TestIssueImportService_CheckStatusSince_invalidOwner(t *testing.T) { + client, _, _, teardown := setup() + defer teardown() + + _, _, err := client.IssueImport.CheckStatusSince(context.Background(), "%", "r", time.Now()) + testURLParseError(t, err) +} + +var issueImportResponseJSON = []byte(`{ + "id": 3, + "status": "pending", + "url": "https://api.github.com/repos/o/r/import/issues/3", + "import_issues_url": "https://api.github.com/repos/o/r/import/issues", + "repository_url": "https://api.github.com/repos/o/r" +}`) + +var wantIssueImportResponse = &IssueImportResponse{ + ID: Int(3), + Status: String("pending"), + URL: String("https://api.github.com/repos/o/r/import/issues/3"), + ImportIssuesURL: String("https://api.github.com/repos/o/r/import/issues"), + RepositoryURL: String("https://api.github.com/repos/o/r"), +} From 5d9ab32569c264068046f6879da90cd73a5b4580 Mon Sep 17 00:00:00 2001 From: Nikolaos Kanakis <4174162+nicolasmanic@users.noreply.github.com> Date: Sat, 15 Aug 2020 23:15:21 +0200 Subject: [PATCH 0209/1468] Add Workflow run and dispatch events (#1600) --- github/event.go | 4 +++ github/event_types.go | 27 ++++++++++++++ github/github-accessors.go | 72 ++++++++++++++++++++++++++++++++++++++ github/messages.go | 2 ++ github/messages_test.go | 8 +++++ 5 files changed, 113 insertions(+) diff --git a/github/event.go b/github/event.go index 3b96b029ab9..6fcae541a9a 100644 --- a/github/event.go +++ b/github/event.go @@ -118,6 +118,10 @@ func (e *Event) ParsePayload() (payload interface{}, err error) { payload = &UserEvent{} case "WatchEvent": payload = &WatchEvent{} + case "WorkflowDispatchEvent": + payload = &WorkflowDispatchEvent{} + case "WorkflowRunEvent": + payload = &WorkflowRunEvent{} } err = json.Unmarshal(*e.RawPayload, &payload) return payload, err diff --git a/github/event_types.go b/github/event_types.go index fe6991f535b..171c8ea343e 100644 --- a/github/event_types.go +++ b/github/event_types.go @@ -945,3 +945,30 @@ type WatchEvent struct { Sender *User `json:"sender,omitempty"` Installation *Installation `json:"installation,omitempty"` } + +// WorkflowDispatchEvent is triggered when someone triggers a workflow run on GitHub or +// sends a POST request to the create a workflow dispatch event endpoint. +// +// GitHub API docs: https://docs.github.com/en/developers/webhooks-and-events/webhook-events-and-payloads#workflow_dispatch +type WorkflowDispatchEvent struct { + Inputs json.RawMessage `json:"inputs,omitempty"` + Ref *string `json:"ref,omitempty"` + Workflow *string `json:"workflow,omitempty"` + + // The following fields are only populated by Webhook events. + Repo *Repository `json:"repository,omitempty"` + Org *Organization `json:"organization,omitempty"` + Sender *User `json:"sender,omitempty"` +} + +// WorkflowRunEvent is triggered when a GitHub Actions workflow run is requested or completed. +// +// GitHub API docs: https://docs.github.com/en/developers/webhooks-and-events/webhook-events-and-payloads#workflow_run +type WorkflowRunEvent struct { + Action *string `json:"action,omitempty"` + + // The following fields are only populated by Webhook events. + Org *Organization `json:"organization,omitempty"` + Repo *Repository `json:"repository,omitempty"` + Sender *User `json:"sender,omitempty"` +} diff --git a/github/github-accessors.go b/github/github-accessors.go index 0c8e260ebf9..5e8fe2bf28f 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -15060,6 +15060,46 @@ func (w *WorkflowBill) GetTotalMS() int64 { return *w.TotalMS } +// GetOrg returns the Org field. +func (w *WorkflowDispatchEvent) GetOrg() *Organization { + if w == nil { + return nil + } + return w.Org +} + +// GetRef returns the Ref field if it's non-nil, zero value otherwise. +func (w *WorkflowDispatchEvent) GetRef() string { + if w == nil || w.Ref == nil { + return "" + } + return *w.Ref +} + +// GetRepo returns the Repo field. +func (w *WorkflowDispatchEvent) GetRepo() *Repository { + if w == nil { + return nil + } + return w.Repo +} + +// GetSender returns the Sender field. +func (w *WorkflowDispatchEvent) GetSender() *User { + if w == nil { + return nil + } + return w.Sender +} + +// GetWorkflow returns the Workflow field if it's non-nil, zero value otherwise. +func (w *WorkflowDispatchEvent) GetWorkflow() string { + if w == nil || w.Workflow == nil { + return "" + } + return *w.Workflow +} + // GetMacOS returns the MacOS field. func (w *WorkflowEnvironment) GetMacOS() *WorkflowBill { if w == nil { @@ -15412,6 +15452,38 @@ func (w *WorkflowRunEnvironment) GetWindows() *WorkflowRunBill { return w.Windows } +// GetAction returns the Action field if it's non-nil, zero value otherwise. +func (w *WorkflowRunEvent) GetAction() string { + if w == nil || w.Action == nil { + return "" + } + return *w.Action +} + +// GetOrg returns the Org field. +func (w *WorkflowRunEvent) GetOrg() *Organization { + if w == nil { + return nil + } + return w.Org +} + +// GetRepo returns the Repo field. +func (w *WorkflowRunEvent) GetRepo() *Repository { + if w == nil { + return nil + } + return w.Repo +} + +// GetSender returns the Sender field. +func (w *WorkflowRunEvent) GetSender() *User { + if w == nil { + return nil + } + return w.Sender +} + // GetTotalCount returns the TotalCount field if it's non-nil, zero value otherwise. func (w *WorkflowRuns) GetTotalCount() int { if w == nil || w.TotalCount == nil { diff --git a/github/messages.go b/github/messages.go index 2c1c7a7e6f5..424a961c940 100644 --- a/github/messages.go +++ b/github/messages.go @@ -85,6 +85,8 @@ var ( "team_add": "TeamAddEvent", "user": "UserEvent", "watch": "WatchEvent", + "workflow_dispatch": "WorkflowDispatchEvent", + "workflow_run": "WorkflowRunEvent", } ) diff --git a/github/messages_test.go b/github/messages_test.go index 9a0fd74afd2..5f5a4c1b794 100644 --- a/github/messages_test.go +++ b/github/messages_test.go @@ -359,6 +359,14 @@ func TestParseWebHook(t *testing.T) { payload: &RepositoryDispatchEvent{}, messageType: "repository_dispatch", }, + { + payload: &WorkflowDispatchEvent{}, + messageType: "workflow_dispatch", + }, + { + payload: &WorkflowRunEvent{}, + messageType: "workflow_run", + }, } for _, test := range tests { From 00ac78b1681f7a279e95c87038ab85319ccb4376 Mon Sep 17 00:00:00 2001 From: Glenn Lewis <6598971+gmlewis@users.noreply.github.com> Date: Sun, 16 Aug 2020 14:35:17 -0400 Subject: [PATCH 0210/1468] Support Go 1.15 and 1.14 in workflows/tests.yml (#1605) --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index bf3f173cdff..ef4830e94d1 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -7,7 +7,7 @@ jobs: test: strategy: matrix: - go-version: [1.x, 1.13.x] + go-version: [1.x, 1.14.x] platform: [ubuntu-latest, windows-latest] runs-on: ${{ matrix.platform }} From 0bc3888d42a4de6d2f0495c9a874b10c176c1d04 Mon Sep 17 00:00:00 2001 From: Martin Holman Date: Mon, 17 Aug 2020 09:43:18 -0700 Subject: [PATCH 0211/1468] Update content type header for AppsService.CreateAttachment (#1602) --- github/apps.go | 2 +- github/apps_test.go | 2 +- github/github.go | 3 +++ 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/github/apps.go b/github/apps.go index 45262c41a0f..afbdd67ff57 100644 --- a/github/apps.go +++ b/github/apps.go @@ -291,7 +291,7 @@ func (s *AppsService) CreateAttachment(ctx context.Context, contentReferenceID i } // TODO: remove custom Accept headers when APIs fully launch. - req.Header.Set("Accept", mediaTypeReactionsPreview) + req.Header.Set("Accept", mediaTypeContentAttachmentsPreview) m := &Attachment{} resp, err := s.client.Do(ctx, req, m) diff --git a/github/apps_test.go b/github/apps_test.go index e80a2986f6a..6610482f55f 100644 --- a/github/apps_test.go +++ b/github/apps_test.go @@ -328,7 +328,7 @@ func TestAppsService_CreateAttachement(t *testing.T) { mux.HandleFunc("/content_references/11/attachments", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "POST") - testHeader(t, r, "Accept", mediaTypeReactionsPreview) + testHeader(t, r, "Accept", mediaTypeContentAttachmentsPreview) w.WriteHeader(http.StatusOK) w.Write([]byte(`{"id":1,"title":"title1","body":"body1"}`)) diff --git a/github/github.go b/github/github.go index b6abc8f4078..5d20d6d3884 100644 --- a/github/github.go +++ b/github/github.go @@ -136,6 +136,9 @@ const ( // https://developer.github.com/changes/2019-12-03-internal-visibility-changes/ mediaTypeRepositoryVisibilityPreview = "application/vnd.github.nebula-preview+json" + + // https://developer.github.com/changes/2018-12-10-content-attachments-api/ + mediaTypeContentAttachmentsPreview = "application/vnd.github.corsair-preview+json" ) // A Client manages communication with the GitHub API. From 5be7808eade4a0d75bdbd949f3a2f97def0b536a Mon Sep 17 00:00:00 2001 From: Thomas Aidan Curran Date: Wed, 19 Aug 2020 00:19:47 +0200 Subject: [PATCH 0212/1468] Update go-github/example/topics/main.go (#1611) Added a more accurate in line documentation for main.go functionality --- example/topics/main.go | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/example/topics/main.go b/example/topics/main.go index 54741c9fec6..0def2ac9c68 100644 --- a/example/topics/main.go +++ b/example/topics/main.go @@ -3,9 +3,9 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// The simple command demonstrates a simple functionality which -// prompts the user for a GitHub topic and lists all the public -// organization memberships of the specified topic. +// The simple command demonstrates the functionality that +// prompts the user for a GitHub topic and lists all the entities +// that are related to the specified topic or subject. package main import ( @@ -15,9 +15,8 @@ import ( "github.com/google/go-github/v32/github" ) -// Fetch all the public organizations' membership of a user. -// -func FetchTopics(topic string) (*github.TopicsSearchResult, error) { +// Fetch and lists all the public topics associated with the specified GitHub topic +func fetchTopics(topic string) (*github.TopicsSearchResult, error) { client := github.NewClient(nil) topics, _, err := client.Search.Topics(context.Background(), topic, nil) return topics, err @@ -28,7 +27,7 @@ func main() { fmt.Print("Enter GitHub topic: ") fmt.Scanf("%s", &topic) - topics, err := FetchTopics(topic) + topics, err := fetchTopics(topic) if err != nil { fmt.Printf("Error: %v\n", err) return From bd957f2d6a671382a9af3116c43ff7dd55b8dc0e Mon Sep 17 00:00:00 2001 From: Ink33 <51873347+Ink-33@users.noreply.github.com> Date: Thu, 20 Aug 2020 00:45:08 +0800 Subject: [PATCH 0213/1468] Correct spelling errors (#1612) --- update-urls/main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/update-urls/main.go b/update-urls/main.go index c9455cf4fd4..3d8ca216357 100644 --- a/update-urls/main.go +++ b/update-urls/main.go @@ -6,7 +6,7 @@ // update-urls updates GitHub URL docs for each service endpoint. // // It is meant to be used periodically by go-github repo maintainers -// to update stale GitHub Developer v3 API documenation URLs. +// to update stale GitHub Developer v3 API documentation URLs. // // Usage (from go-github directory): // go run ./update-urls/main.go From 9be567b093538700c72a43eb414d182ae6876e17 Mon Sep 17 00:00:00 2001 From: Piyush Chugh Date: Sat, 22 Aug 2020 08:28:41 +0530 Subject: [PATCH 0214/1468] Add comment about Repositories.Create and creation delay (#1613) Fixes: #1585 --- .gitignore | 1 + github/event_types.go | 2 +- github/pulls.go | 4 ++-- github/repos.go | 15 ++++++++++----- 4 files changed, 14 insertions(+), 8 deletions(-) diff --git a/.gitignore b/.gitignore index d99e2ea721c..5af45b86f5d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ *.sh *.test coverage.out +vendor/ diff --git a/github/event_types.go b/github/event_types.go index 171c8ea343e..450ead56e97 100644 --- a/github/event_types.go +++ b/github/event_types.go @@ -344,7 +344,7 @@ type LabelEvent struct { // their GitHub Marketplace plan. // Webhook event name "marketplace_purchase". // -// Github API docs: https://developer.github.com/v3/activity/events/types/#marketplacepurchaseevent +// GitHub API docs: https://developer.github.com/v3/activity/events/types/#marketplacepurchaseevent type MarketplacePurchaseEvent struct { // Action is the action that was performed. Possible values are: // "purchased", "cancelled", "pending_change", "pending_change_cancelled", "changed". diff --git a/github/pulls.go b/github/pulls.go index 4ac62a83739..b0876d8a2ae 100644 --- a/github/pulls.go +++ b/github/pulls.go @@ -81,12 +81,12 @@ func (p PullRequest) String() string { return Stringify(p) } -// PRLink represents a single link object from Github pull request _links. +// PRLink represents a single link object from GitHub pull request _links. type PRLink struct { HRef *string `json:"href,omitempty"` } -// PRLinks represents the "_links" object in a Github pull request. +// PRLinks represents the "_links" object in a GitHub pull request. type PRLinks struct { Self *PRLink `json:"self,omitempty"` HTML *PRLink `json:"html,omitempty"` diff --git a/github/repos.go b/github/repos.go index 0956d7c6fe9..4f15ac18673 100644 --- a/github/repos.go +++ b/github/repos.go @@ -327,6 +327,11 @@ type createRepoRequest struct { // Note that only a subset of the repo fields are used and repo must // not be nil. // +// Also note that this method will return the response without actually +// waiting for GitHub to finish creating the repository and letting the +// changes propagate throughout its servers. You may set up a loop with +// exponential back-off to verify repository's creation. +// // GitHub API docs: https://developer.github.com/v3/repos/#create-a-repository-for-the-authenticated-user // GitHub API docs: https://developer.github.com/v3/repos/#create-an-organization-repository func (s *RepositoriesService) Create(ctx context.Context, org string, repo *Repository) (*Repository, *Response, error) { @@ -1354,8 +1359,8 @@ func (s *RepositoriesService) ReplaceAllTopics(ctx context.Context, owner, repo return t.Names, resp, nil } -// ListApps lists the Github apps that have push access to a given protected branch. -// It requires the Github apps to have `write` access to the `content` permission. +// ListApps lists the GitHub apps that have push access to a given protected branch. +// It requires the GitHub apps to have `write` access to the `content` permission. // // GitHub API docs: https://developer.github.com/v3/repos/branches/#list-apps-with-access-to-the-protected-branch func (s *RepositoriesService) ListApps(ctx context.Context, owner, repo, branch string) ([]*App, *Response, error) { @@ -1376,7 +1381,7 @@ func (s *RepositoriesService) ListApps(ctx context.Context, owner, repo, branch // ReplaceAppRestrictions replaces the apps that have push access to a given protected branch. // It removes all apps that previously had push access and grants push access to the new list of apps. -// It requires the Github apps to have `write` access to the `content` permission. +// It requires the GitHub apps to have `write` access to the `content` permission. // // Note: The list of users, apps, and teams in total is limited to 100 items. // @@ -1398,7 +1403,7 @@ func (s *RepositoriesService) ReplaceAppRestrictions(ctx context.Context, owner, } // AddAppRestrictions grants the specified apps push access to a given protected branch. -// It requires the Github apps to have `write` access to the `content` permission. +// It requires the GitHub apps to have `write` access to the `content` permission. // // Note: The list of users, apps, and teams in total is limited to 100 items. // @@ -1420,7 +1425,7 @@ func (s *RepositoriesService) AddAppRestrictions(ctx context.Context, owner, rep } // RemoveAppRestrictions removes the ability of an app to push to this branch. -// It requires the Github apps to have `write` access to the `content` permission. +// It requires the GitHub apps to have `write` access to the `content` permission. // // Note: The list of users, apps, and teams in total is limited to 100 items. // From b6aa4a7a0beb88d6802247932f7829d5241fadbd Mon Sep 17 00:00:00 2001 From: Martin Holman Date: Fri, 21 Aug 2020 20:01:25 -0700 Subject: [PATCH 0215/1468] Add content_reference event (#1597) --- github/apps.go | 7 +++++ github/event.go | 2 ++ github/event_types.go | 14 +++++++++ github/github-accessors.go | 64 ++++++++++++++++++++++++++++++++++++++ github/messages.go | 1 + github/messages_test.go | 4 +++ 6 files changed, 92 insertions(+) diff --git a/github/apps.go b/github/apps.go index afbdd67ff57..c50bb0daaef 100644 --- a/github/apps.go +++ b/github/apps.go @@ -112,6 +112,13 @@ type Attachment struct { Body *string `json:"body,omitempty"` } +// ContentReference represents a reference to a URL in an issue or pull request. +type ContentReference struct { + ID *int64 `json:"id,omitempty"` + NodeID *string `json:"node_id,omitempty"` + Reference *string `json:"reference,omitempty"` +} + func (i Installation) String() string { return Stringify(i) } diff --git a/github/event.go b/github/event.go index 6fcae541a9a..eec905159fe 100644 --- a/github/event.go +++ b/github/event.go @@ -36,6 +36,8 @@ func (e *Event) ParsePayload() (payload interface{}, err error) { payload = &CheckSuiteEvent{} case "CommitCommentEvent": payload = &CommitCommentEvent{} + case "ContentReferenceEvent": + payload = &ContentReferenceEvent{} case "CreateEvent": payload = &CreateEvent{} case "DeleteEvent": diff --git a/github/event_types.go b/github/event_types.go index 450ead56e97..cdfd6e8831d 100644 --- a/github/event_types.go +++ b/github/event_types.go @@ -64,6 +64,20 @@ type CommitCommentEvent struct { Installation *Installation `json:"installation,omitempty"` } +// ContentReferenceEvent is triggered when the body or comment of an issue or +// pull request includes a URL that matches a configured content reference +// domain. +// The Webhook event name is "content_reference". +// +// GitHub API docs: https://developer.github.com/webhooks/event-payloads/#content_reference +type ContentReferenceEvent struct { + Action *string `json:"action,omitempty"` + ContentReference *ContentReference `json:"content_reference,omitempty"` + Repo *Repository `json:"repository,omitempty"` + Sender *User `json:"sender,omitempty"` + Installation *Installation `json:"installation,omitempty"` +} + // CreateEvent represents a created repository, branch, or tag. // The Webhook event name is "create". // diff --git a/github/github-accessors.go b/github/github-accessors.go index 5e8fe2bf28f..422f721aada 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -2020,6 +2020,70 @@ func (c *CommunityHealthMetrics) GetUpdatedAt() time.Time { return *c.UpdatedAt } +// GetID returns the ID field if it's non-nil, zero value otherwise. +func (c *ContentReference) GetID() int64 { + if c == nil || c.ID == nil { + return 0 + } + return *c.ID +} + +// GetNodeID returns the NodeID field if it's non-nil, zero value otherwise. +func (c *ContentReference) GetNodeID() string { + if c == nil || c.NodeID == nil { + return "" + } + return *c.NodeID +} + +// GetReference returns the Reference field if it's non-nil, zero value otherwise. +func (c *ContentReference) GetReference() string { + if c == nil || c.Reference == nil { + return "" + } + return *c.Reference +} + +// GetAction returns the Action field if it's non-nil, zero value otherwise. +func (c *ContentReferenceEvent) GetAction() string { + if c == nil || c.Action == nil { + return "" + } + return *c.Action +} + +// GetContentReference returns the ContentReference field. +func (c *ContentReferenceEvent) GetContentReference() *ContentReference { + if c == nil { + return nil + } + return c.ContentReference +} + +// GetInstallation returns the Installation field. +func (c *ContentReferenceEvent) GetInstallation() *Installation { + if c == nil { + return nil + } + return c.Installation +} + +// GetRepo returns the Repo field. +func (c *ContentReferenceEvent) GetRepo() *Repository { + if c == nil { + return nil + } + return c.Repo +} + +// GetSender returns the Sender field. +func (c *ContentReferenceEvent) GetSender() *User { + if c == nil { + return nil + } + return c.Sender +} + // GetAvatarURL returns the AvatarURL field if it's non-nil, zero value otherwise. func (c *Contributor) GetAvatarURL() string { if c == nil || c.AvatarURL == nil { diff --git a/github/messages.go b/github/messages.go index 424a961c940..adf623e0e88 100644 --- a/github/messages.go +++ b/github/messages.go @@ -44,6 +44,7 @@ var ( "check_run": "CheckRunEvent", "check_suite": "CheckSuiteEvent", "commit_comment": "CommitCommentEvent", + "content_reference": "ContentReferenceEvent", "create": "CreateEvent", "delete": "DeleteEvent", "deploy_key": "DeployKeyEvent", diff --git a/github/messages_test.go b/github/messages_test.go index 5f5a4c1b794..2a5d0d5eef7 100644 --- a/github/messages_test.go +++ b/github/messages_test.go @@ -194,6 +194,10 @@ func TestParseWebHook(t *testing.T) { payload: &CommitCommentEvent{}, messageType: "commit_comment", }, + { + payload: &ContentReferenceEvent{}, + messageType: "content_reference", + }, { payload: &CreateEvent{}, messageType: "create", From cde755d32b109cae77a1d8ac62bb90a42adb472a Mon Sep 17 00:00:00 2001 From: Jef LeCompte Date: Fri, 21 Aug 2020 23:06:24 -0400 Subject: [PATCH 0216/1468] Update main GitHub API v3 link (#1614) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 380b12ad716..172c55f0ccd 100644 --- a/README.md +++ b/README.md @@ -217,7 +217,7 @@ for { For complete usage of go-github, see the full [package docs][]. -[GitHub API v3]: https://developer.github.com/v3/ +[GitHub API v3]: https://docs.github.com/en/rest [oauth2]: https://github.com/golang/oauth2 [oauth2 docs]: https://godoc.org/golang.org/x/oauth2 [personal API token]: https://github.com/blog/1509-personal-api-tokens From 5f5296864910f405d005d679b3c65cbe4c002d05 Mon Sep 17 00:00:00 2001 From: Piyush Chugh Date: Sat, 22 Aug 2020 08:42:54 +0530 Subject: [PATCH 0217/1468] Fix GitHub Enterprise API subdomain (#1599) Fixes: #1552. --- .gitignore | 2 + github/actions_workflow_runs.go | 2 +- github/github.go | 8 ++- github/github_test.go | 110 ++++++++++++++++++++++++++++++++ github/teams_members.go | 8 +-- 5 files changed, 123 insertions(+), 7 deletions(-) diff --git a/.gitignore b/.gitignore index 5af45b86f5d..3f716daf3d8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,6 @@ *.sh *.test coverage.out +# intellij files +.idea/ vendor/ diff --git a/github/actions_workflow_runs.go b/github/actions_workflow_runs.go index 4213c6b15f0..9d4c00ea39c 100644 --- a/github/actions_workflow_runs.go +++ b/github/actions_workflow_runs.go @@ -154,7 +154,7 @@ func (s *ActionsService) GetWorkflowRunByID(ctx context.Context, owner, repo str return run, resp, nil } -// RerunWorkflow re-runs a workflow by ID. +// RerunWorkflowByID re-runs a workflow by ID. // // GitHub API docs: https://developer.github.com/v3/actions/workflow-runs/#re-run-a-workflow func (s *ActionsService) RerunWorkflowByID(ctx context.Context, owner, repo string, runID int64) (*Response, error) { diff --git a/github/github.go b/github/github.go index 5d20d6d3884..c739de925f3 100644 --- a/github/github.go +++ b/github/github.go @@ -319,7 +319,9 @@ func NewEnterpriseClient(baseURL, uploadURL string, httpClient *http.Client) (*C if !strings.HasSuffix(baseEndpoint.Path, "/") { baseEndpoint.Path += "/" } - if !strings.HasSuffix(baseEndpoint.Path, "/api/v3/") { + if !strings.HasSuffix(baseEndpoint.Path, "/api/v3/") && + !strings.HasPrefix(baseEndpoint.Host, "api.") && + !strings.Contains(baseEndpoint.Host, ".api.") { baseEndpoint.Path += "api/v3/" } @@ -330,7 +332,9 @@ func NewEnterpriseClient(baseURL, uploadURL string, httpClient *http.Client) (*C if !strings.HasSuffix(uploadEndpoint.Path, "/") { uploadEndpoint.Path += "/" } - if !strings.HasSuffix(uploadEndpoint.Path, "/api/uploads/") { + if !strings.HasSuffix(uploadEndpoint.Path, "/api/uploads/") && + !strings.HasPrefix(uploadEndpoint.Host, "api.") && + !strings.Contains(uploadEndpoint.Host, ".api.") { uploadEndpoint.Path += "api/uploads/" } diff --git a/github/github_test.go b/github/github_test.go index 2d5ac738dca..d86ec206cb0 100644 --- a/github/github_test.go +++ b/github/github_test.go @@ -255,6 +255,116 @@ func TestNewEnterpriseClient_addsEnterpriseSuffixAndTrailingSlashToURLs(t *testi } } +func TestNewEnterpriseClient_URLHasExistingAPIPrefix_AddTrailingSlash(t *testing.T) { + baseURL := "https://api.custom-url" + uploadURL := "https://api.custom-upload-url" + formattedBaseURL := baseURL + "/" + formattedUploadURL := uploadURL + "/" + + c, err := NewEnterpriseClient(baseURL, uploadURL, nil) + if err != nil { + t.Fatalf("NewEnterpriseClient returned unexpected error: %v", err) + } + + if got, want := c.BaseURL.String(), formattedBaseURL; got != want { + t.Errorf("NewClient BaseURL is %v, want %v", got, want) + } + if got, want := c.UploadURL.String(), formattedUploadURL; got != want { + t.Errorf("NewClient UploadURL is %v, want %v", got, want) + } +} + +func TestNewEnterpriseClient_URLHasExistingAPIPrefixAndTrailingSlash(t *testing.T) { + baseURL := "https://api.custom-url/" + uploadURL := "https://api.custom-upload-url/" + + c, err := NewEnterpriseClient(baseURL, uploadURL, nil) + if err != nil { + t.Fatalf("NewEnterpriseClient returned unexpected error: %v", err) + } + + if got, want := c.BaseURL.String(), baseURL; got != want { + t.Errorf("NewClient BaseURL is %v, want %v", got, want) + } + if got, want := c.UploadURL.String(), uploadURL; got != want { + t.Errorf("NewClient UploadURL is %v, want %v", got, want) + } +} + +func TestNewEnterpriseClient_URLHasAPISubdomain_AddTrailingSlash(t *testing.T) { + baseURL := "https://catalog.api.custom-url" + uploadURL := "https://catalog.api.custom-upload-url" + formattedBaseURL := baseURL + "/" + formattedUploadURL := uploadURL + "/" + + c, err := NewEnterpriseClient(baseURL, uploadURL, nil) + if err != nil { + t.Fatalf("NewEnterpriseClient returned unexpected error: %v", err) + } + + if got, want := c.BaseURL.String(), formattedBaseURL; got != want { + t.Errorf("NewClient BaseURL is %v, want %v", got, want) + } + if got, want := c.UploadURL.String(), formattedUploadURL; got != want { + t.Errorf("NewClient UploadURL is %v, want %v", got, want) + } +} + +func TestNewEnterpriseClient_URLHasAPISubdomainAndTrailingSlash(t *testing.T) { + baseURL := "https://catalog.api.custom-url/" + uploadURL := "https://catalog.api.custom-upload-url/" + + c, err := NewEnterpriseClient(baseURL, uploadURL, nil) + if err != nil { + t.Fatalf("NewEnterpriseClient returned unexpected error: %v", err) + } + + if got, want := c.BaseURL.String(), baseURL; got != want { + t.Errorf("NewClient BaseURL is %v, want %v", got, want) + } + if got, want := c.UploadURL.String(), uploadURL; got != want { + t.Errorf("NewClient UploadURL is %v, want %v", got, want) + } +} + +func TestNewEnterpriseClient_URLIsNotAProperAPISubdomain_addsEnterpriseSuffixAndSlash(t *testing.T) { + baseURL := "https://cloud-api.custom-url" + uploadURL := "https://cloud-api.custom-upload-url" + formattedBaseURL := baseURL + "/api/v3/" + formattedUploadURL := uploadURL + "/api/uploads/" + + c, err := NewEnterpriseClient(baseURL, uploadURL, nil) + if err != nil { + t.Fatalf("NewEnterpriseClient returned unexpected error: %v", err) + } + + if got, want := c.BaseURL.String(), formattedBaseURL; got != want { + t.Errorf("NewClient BaseURL is %v, want %v", got, want) + } + if got, want := c.UploadURL.String(), formattedUploadURL; got != want { + t.Errorf("NewClient UploadURL is %v, want %v", got, want) + } +} + +func TestNewEnterpriseClient_URLIsNotAProperAPISubdomain_addsEnterpriseSuffix(t *testing.T) { + baseURL := "https://cloud-api.custom-url/" + uploadURL := "https://cloud-api.custom-upload-url/" + formattedBaseURL := baseURL + "api/v3/" + formattedUploadURL := uploadURL + "api/uploads/" + + c, err := NewEnterpriseClient(baseURL, uploadURL, nil) + if err != nil { + t.Fatalf("NewEnterpriseClient returned unexpected error: %v", err) + } + + if got, want := c.BaseURL.String(), formattedBaseURL; got != want { + t.Errorf("NewClient BaseURL is %v, want %v", got, want) + } + if got, want := c.UploadURL.String(), formattedUploadURL; got != want { + t.Errorf("NewClient UploadURL is %v, want %v", got, want) + } +} + // Ensure that length of Client.rateLimits is the same as number of fields in RateLimits struct. func TestClient_rateLimits(t *testing.T) { if got, want := len(Client{}.rateLimits), reflect.TypeOf(RateLimits{}).NumField(); got != want { diff --git a/github/teams_members.go b/github/teams_members.go index b5d31aaf562..c8c561f44b1 100644 --- a/github/teams_members.go +++ b/github/teams_members.go @@ -124,7 +124,7 @@ type TeamAddTeamMembershipOptions struct { Role string `json:"role,omitempty"` } -// AddTeamMembership adds or invites a user to a team, given a specified +// AddTeamMembershipByID adds or invites a user to a team, given a specified // organization ID, by team ID. // // GitHub API docs: https://developer.github.com/v3/teams/members/#add-or-update-team-membership-for-a-user @@ -164,7 +164,7 @@ func (s *TeamsService) AddTeamMembershipBySlug(ctx context.Context, org, slug, u return t, resp, nil } -// RemoveTeamMembership removes a user from a team, given a specified +// RemoveTeamMembershipByID removes a user from a team, given a specified // organization ID, by team ID. // // GitHub API docs: https://developer.github.com/v3/teams/members/#remove-team-membership-for-a-user @@ -178,7 +178,7 @@ func (s *TeamsService) RemoveTeamMembershipByID(ctx context.Context, orgID, team return s.client.Do(ctx, req, nil) } -// RemoveTeamMembership removes a user from a team, given a specified +// RemoveTeamMembershipBySlug removes a user from a team, given a specified // organization name, by team slug. // // GitHub API docs: https://developer.github.com/v3/teams/members/#remove-team-membership-for-a-user @@ -217,7 +217,7 @@ func (s *TeamsService) ListPendingTeamInvitationsByID(ctx context.Context, orgID return pendingInvitations, resp, nil } -// ListPendingTeamInvitationsByID get pending invitation list of a team, given a specified +// ListPendingTeamInvitationsBySlug get pending invitation list of a team, given a specified // organization name, by team slug. // // GitHub API docs: https://developer.github.com/v3/teams/members/#list-pending-team-invitations From 5f503791518ca65b08fdf0abf21ea69dd775978b Mon Sep 17 00:00:00 2001 From: Bradley McAllister Date: Fri, 21 Aug 2020 20:15:17 -0700 Subject: [PATCH 0218/1468] Add RepositoriesService.CompareCommitsRaw method (#1582) --- github/repos_commits.go | 33 ++++++++++++++++++++- github/repos_commits_test.go | 57 ++++++++++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+), 1 deletion(-) diff --git a/github/repos_commits.go b/github/repos_commits.go index 07c071e0dc4..b5e5b99c60f 100644 --- a/github/repos_commits.go +++ b/github/repos_commits.go @@ -221,7 +221,6 @@ func (s *RepositoriesService) GetCommitSHA1(ctx context.Context, owner, repo, re } // CompareCommits compares a range of commits with each other. -// todo: support media formats - https://github.com/google/go-github/issues/6 // // GitHub API docs: https://developer.github.com/v3/repos/commits/#compare-two-commits func (s *RepositoriesService) CompareCommits(ctx context.Context, owner, repo string, base, head string) (*CommitsComparison, *Response, error) { @@ -241,6 +240,38 @@ func (s *RepositoriesService) CompareCommits(ctx context.Context, owner, repo st return comp, resp, nil } +// CompareCommitsRaw compares a range of commits with each other in raw (diff or patch) format. +// +// Both "base" and "head" must be branch names in "repo". +// To compare branches across other repositories in the same network as "repo", +// use the format ":branch". +// +// GitHub API docs: https://developer.github.com/v3/repos/commits/#compare-two-commits +func (s *RepositoriesService) CompareCommitsRaw(ctx context.Context, owner, repo, base, head string, opts RawOptions) (string, *Response, error) { + u := fmt.Sprintf("repos/%v/%v/compare/%v...%v", owner, repo, base, head) + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return "", nil, err + } + + switch opts.Type { + case Diff: + req.Header.Set("Accept", mediaTypeV3Diff) + case Patch: + req.Header.Set("Accept", mediaTypeV3Patch) + default: + return "", nil, fmt.Errorf("unsupported raw type %d", opts.Type) + } + + var buf bytes.Buffer + resp, err := s.client.Do(ctx, req, &buf) + if err != nil { + return "", resp, err + } + + return buf.String(), resp, nil +} + // ListBranchesHeadCommit gets all branches where the given commit SHA is the HEAD, // or latest commit for the branch. // diff --git a/github/repos_commits_test.go b/github/repos_commits_test.go index 221ddaf7d44..6da964fec56 100644 --- a/github/repos_commits_test.go +++ b/github/repos_commits_test.go @@ -400,6 +400,63 @@ func TestRepositoriesService_CompareCommits(t *testing.T) { } } +func TestRepositoriesService_CompareCommitsRaw_diff(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + const rawStr = "@@diff content" + + mux.HandleFunc("/repos/o/r/compare/b...h", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + testHeader(t, r, "Accept", mediaTypeV3Diff) + fmt.Fprint(w, rawStr) + }) + + got, _, err := client.Repositories.CompareCommitsRaw(context.Background(), "o", "r", "b", "h", RawOptions{Type: Diff}) + if err != nil { + t.Fatalf("Repositories.GetCommitRaw returned error: %v", err) + } + want := rawStr + if got != want { + t.Errorf("Repositories.GetCommitRaw returned %s want %s", got, want) + } +} + +func TestRepositoriesService_CompareCommitsRaw_patch(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + const rawStr = "@@patch content" + + mux.HandleFunc("/repos/o/r/compare/b...h", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + testHeader(t, r, "Accept", mediaTypeV3Patch) + fmt.Fprint(w, rawStr) + }) + + got, _, err := client.Repositories.CompareCommitsRaw(context.Background(), "o", "r", "b", "h", RawOptions{Type: Patch}) + if err != nil { + t.Fatalf("Repositories.GetCommitRaw returned error: %v", err) + } + want := rawStr + if got != want { + t.Errorf("Repositories.GetCommitRaw returned %s want %s", got, want) + } +} + +func TestRepositoriesService_CompareCommitsRaw_invalid(t *testing.T) { + client, _, _, teardown := setup() + defer teardown() + + _, _, err := client.Repositories.CompareCommitsRaw(context.Background(), "o", "r", "s", "h", RawOptions{100}) + if err == nil { + t.Fatal("Repositories.GetCommitRaw should return error") + } + if !strings.Contains(err.Error(), "unsupported raw type") { + t.Error("Repositories.GetCommitRaw should return unsupported raw type error") + } +} + func TestRepositoriesService_ListBranchesHeadCommit(t *testing.T) { client, mux, _, teardown := setup() defer teardown() From d57a3a84ba041135efb6b7ad3991f827c93c306a Mon Sep 17 00:00:00 2001 From: David McIntosh <804610+mctofu@users.noreply.github.com> Date: Fri, 21 Aug 2020 20:18:13 -0700 Subject: [PATCH 0219/1468] Return http.Response from DownloadContents (#1542) Fixes: #1531 --- github/repos_contents.go | 20 ++++++++----- github/repos_contents_test.go | 55 +++++++++++++++++++++++++++++++++-- 2 files changed, 64 insertions(+), 11 deletions(-) diff --git a/github/repos_contents.go b/github/repos_contents.go index fd895ac0eee..d6a3272e827 100644 --- a/github/repos_contents.go +++ b/github/repos_contents.go @@ -117,26 +117,30 @@ func (s *RepositoriesService) GetReadme(ctx context.Context, owner, repo string, // specified file. This function will work with files of any size, as opposed // to GetContents which is limited to 1 Mb files. It is the caller's // responsibility to close the ReadCloser. -func (s *RepositoriesService) DownloadContents(ctx context.Context, owner, repo, filepath string, opts *RepositoryContentGetOptions) (io.ReadCloser, error) { +// +// It is possible for the download to result in a failed response when the +// returned error is nil. Callers should check the returned Response status +// code to verify the content is from a successful response. +func (s *RepositoriesService) DownloadContents(ctx context.Context, owner, repo, filepath string, opts *RepositoryContentGetOptions) (io.ReadCloser, *Response, error) { dir := path.Dir(filepath) filename := path.Base(filepath) - _, dirContents, _, err := s.GetContents(ctx, owner, repo, dir, opts) + _, dirContents, resp, err := s.GetContents(ctx, owner, repo, dir, opts) if err != nil { - return nil, err + return nil, resp, err } for _, contents := range dirContents { if *contents.Name == filename { if contents.DownloadURL == nil || *contents.DownloadURL == "" { - return nil, fmt.Errorf("No download link found for %s", filepath) + return nil, resp, fmt.Errorf("No download link found for %s", filepath) } - resp, err := s.client.client.Get(*contents.DownloadURL) + dlResp, err := s.client.client.Get(*contents.DownloadURL) if err != nil { - return nil, err + return nil, &Response{Response: dlResp}, err } - return resp.Body, nil + return dlResp.Body, &Response{Response: dlResp}, nil } } - return nil, fmt.Errorf("No file named %s found in %s", filename, dir) + return nil, resp, fmt.Errorf("No file named %s found in %s", filename, dir) } // GetContents can return either the metadata and content of a single file diff --git a/github/repos_contents_test.go b/github/repos_contents_test.go index f122525800a..a0c4695c202 100644 --- a/github/repos_contents_test.go +++ b/github/repos_contents_test.go @@ -118,11 +118,15 @@ func TestRepositoriesService_DownloadContents_Success(t *testing.T) { fmt.Fprint(w, "foo") }) - r, err := client.Repositories.DownloadContents(context.Background(), "o", "r", "d/f", nil) + r, resp, err := client.Repositories.DownloadContents(context.Background(), "o", "r", "d/f", nil) if err != nil { t.Errorf("Repositories.DownloadContents returned error: %v", err) } + if got, want := resp.Response.StatusCode, http.StatusOK; got != want { + t.Errorf("Repositories.DownloadContents returned status code %v, want %v", got, want) + } + bytes, err := ioutil.ReadAll(r) if err != nil { t.Errorf("Error reading response body: %v", err) @@ -134,6 +138,43 @@ func TestRepositoriesService_DownloadContents_Success(t *testing.T) { } } +func TestRepositoriesService_DownloadContents_FailedResponse(t *testing.T) { + client, mux, serverURL, teardown := setup() + defer teardown() + mux.HandleFunc("/repos/o/r/contents/d", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + fmt.Fprint(w, `[{ + "type": "file", + "name": "f", + "download_url": "`+serverURL+baseURLPath+`/download/f" + }]`) + }) + mux.HandleFunc("/download/f", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + w.WriteHeader(http.StatusInternalServerError) + fmt.Fprint(w, "foo error") + }) + + r, resp, err := client.Repositories.DownloadContents(context.Background(), "o", "r", "d/f", nil) + if err != nil { + t.Errorf("Repositories.DownloadContents returned error: %v", err) + } + + if got, want := resp.Response.StatusCode, http.StatusInternalServerError; got != want { + t.Errorf("Repositories.DownloadContents returned status code %v, want %v", got, want) + } + + bytes, err := ioutil.ReadAll(r) + if err != nil { + t.Errorf("Error reading response body: %v", err) + } + r.Close() + + if got, want := string(bytes), "foo error"; got != want { + t.Errorf("Repositories.DownloadContents returned %v, want %v", got, want) + } +} + func TestRepositoriesService_DownloadContents_NoDownloadURL(t *testing.T) { client, mux, _, teardown := setup() defer teardown() @@ -145,10 +186,14 @@ func TestRepositoriesService_DownloadContents_NoDownloadURL(t *testing.T) { }]`) }) - _, err := client.Repositories.DownloadContents(context.Background(), "o", "r", "d/f", nil) + _, resp, err := client.Repositories.DownloadContents(context.Background(), "o", "r", "d/f", nil) if err == nil { t.Errorf("Repositories.DownloadContents did not return expected error") } + + if resp == nil { + t.Errorf("Repositories.DownloadContents did not return expected response") + } } func TestRepositoriesService_DownloadContents_NoFile(t *testing.T) { @@ -159,10 +204,14 @@ func TestRepositoriesService_DownloadContents_NoFile(t *testing.T) { fmt.Fprint(w, `[]`) }) - _, err := client.Repositories.DownloadContents(context.Background(), "o", "r", "d/f", nil) + _, resp, err := client.Repositories.DownloadContents(context.Background(), "o", "r", "d/f", nil) if err == nil { t.Errorf("Repositories.DownloadContents did not return expected error") } + + if resp == nil { + t.Errorf("Repositories.DownloadContents did not return expected response") + } } func TestRepositoriesService_GetContents_File(t *testing.T) { From 159b448168db1fc1bc61a556e6280e12dfc00a6d Mon Sep 17 00:00:00 2001 From: Glenn Lewis <6598971+gmlewis@users.noreply.github.com> Date: Tue, 1 Sep 2020 18:30:47 -0400 Subject: [PATCH 0220/1468] Switch to new GitHub v3 API Documentation website (#1621) --- CONTRIBUTING.md | 4 +- README.md | 6 +- github/actions.go | 2 +- github/actions_artifacts.go | 14 +- github/actions_runners.go | 24 +- github/actions_secrets.go | 28 +- github/actions_workflow_jobs.go | 6 +- github/actions_workflow_runs.go | 18 +- github/actions_workflows.go | 10 +- github/activity.go | 2 +- github/activity_events.go | 20 +- github/activity_notifications.go | 20 +- github/activity_star.go | 12 +- github/activity_watching.go | 12 +- github/admin.go | 6 +- github/admin_stats.go | 2 +- github/admin_users_test.go | 4 +- github/apps.go | 30 +- github/apps_installation.go | 10 +- github/apps_manifest.go | 2 +- github/apps_marketplace.go | 14 +- github/authorizations.go | 14 +- github/checks.go | 24 +- github/code-scanning.go | 6 +- github/doc.go | 6 +- github/event_types.go | 82 +- github/gists.go | 32 +- github/gists_comments.go | 10 +- github/git.go | 2 +- github/git_blobs.go | 6 +- github/git_commits.go | 4 +- github/git_refs.go | 10 +- github/git_tags.go | 4 +- github/git_trees.go | 4 +- github/github.go | 20 +- github/github_test.go | 12 +- github/gitignore.go | 6 +- github/interactions.go | 2 +- github/interactions_orgs.go | 6 +- github/interactions_repos.go | 6 +- github/issues.go | 22 +- github/issues_assignees.go | 8 +- github/issues_comments.go | 12 +- github/issues_events.go | 6 +- github/issues_labels.go | 22 +- github/issues_milestones.go | 10 +- github/issues_timeline.go | 4 +- github/licenses.go | 6 +- github/messages.go | 4 +- github/migrations.go | 14 +- github/migrations_source_import.go | 20 +- github/migrations_user.go | 12 +- github/misc.go | 10 +- github/orgs.go | 14 +- github/orgs_hooks.go | 12 +- github/orgs_members.go | 32 +- github/orgs_outside_collaborators.go | 6 +- github/orgs_projects.go | 4 +- github/orgs_users_blocking.go | 8 +- github/projects.go | 44 +- github/pulls.go | 26 +- github/pulls_comments.go | 14 +- github/pulls_reviewers.go | 6 +- github/pulls_reviews.go | 18 +- github/reactions.go | 50 +- github/repos.go | 100 +- github/repos_collaborators.go | 12 +- github/repos_comments.go | 12 +- github/repos_commits.go | 16 +- github/repos_community_health.go | 2 +- github/repos_contents.go | 14 +- github/repos_deployments.go | 14 +- github/repos_forks.go | 4 +- github/repos_hooks.go | 14 +- github/repos_invitations.go | 6 +- github/repos_keys.go | 8 +- github/repos_merging.go | 2 +- github/repos_pages.go | 16 +- github/repos_projects.go | 4 +- github/repos_releases.go | 26 +- github/repos_stats.go | 10 +- github/repos_statuses.go | 6 +- github/repos_traffic.go | 8 +- github/search.go | 16 +- github/teams.go | 66 +- github/teams_discussion_comments.go | 20 +- github/teams_discussions.go | 20 +- github/teams_members.go | 20 +- github/users.go | 20 +- github/users_blocking.go | 8 +- github/users_emails.go | 6 +- github/users_followers.go | 16 +- github/users_gpg_keys.go | 10 +- github/users_keys.go | 10 +- github/users_projects.go | 4 +- update-urls/activity-events_test.go | 6619 +++++++++++++++++--- update-urls/main.go | 132 +- update-urls/main_test.go | 47 +- update-urls/reactions_test.go | 8411 +++++++++++++++++--------- 99 files changed, 12083 insertions(+), 4502 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index bd7db848cfc..95eb4317013 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -87,10 +87,10 @@ where to put new methods. Code is organized in files also based pretty closely on the GitHub API documentation, following the format `{service}_{api}.go`. For example, methods -defined at live in +defined at live in [repos_hooks.go][]. -[GitHub API documentation]: https://developer.github.com/v3/ +[GitHub API documentation]: https://docs.github.com/en/rest/reference/ [repos_hooks.go]: https://github.com/google/go-github/blob/master/github/repos_hooks.go diff --git a/README.md b/README.md index 172c55f0ccd..b5e6a8fe080 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,7 @@ repos, _, err := client.Repositories.ListByOrg(context.Background(), "github", o The services of a client divide the API into logical chunks and correspond to the structure of the GitHub API documentation at -https://developer.github.com/v3/. +https://docs.github.com/en/rest/reference/. NOTE: Using the [context](https://godoc.org/context) package, one can easily pass cancelation signals and deadlines to various services of the client for @@ -137,7 +137,7 @@ if _, ok := err.(*github.RateLimitError); ok { ``` Learn more about GitHub rate limiting at -https://developer.github.com/v3/#rate-limiting. +https://docs.github.com/en/rest/reference/rate-limit. ### Accepted Status ### @@ -165,7 +165,7 @@ instead designed to work with a caching `http.Transport`. We recommend using https://github.com/gregjones/httpcache for that. Learn more about GitHub conditional requests at -https://developer.github.com/v3/#conditional-requests. +https://docs.github.com/en/rest/overview/resources-in-the-rest-api#conditional-requests. ### Creating and Updating Resources ### diff --git a/github/actions.go b/github/actions.go index f9f7f8ee867..8996cac5348 100644 --- a/github/actions.go +++ b/github/actions.go @@ -8,5 +8,5 @@ package github // ActionsService handles communication with the actions related // methods of the GitHub API. // -// GitHub API docs: https://developer.github.com/v3/actions/ +// GitHub API docs: https://docs.github.com/en/rest/reference/actions/ type ActionsService service diff --git a/github/actions_artifacts.go b/github/actions_artifacts.go index a236253e36d..98bb65fa642 100644 --- a/github/actions_artifacts.go +++ b/github/actions_artifacts.go @@ -16,7 +16,7 @@ import ( // data between jobs in a workflow and provide storage for data // once a workflow is complete. // -// GitHub API docs: https://developer.github.com/v3/actions/artifacts/ +// GitHub API docs: https://docs.github.com/en/rest/reference/actions/artifacts/ type Artifact struct { ID *int64 `json:"id,omitempty"` NodeID *string `json:"node_id,omitempty"` @@ -30,7 +30,7 @@ type Artifact struct { // ArtifactList represents a list of GitHub artifacts. // -// GitHub API docs: https://developer.github.com/v3/actions/artifacts/ +// GitHub API docs: https://docs.github.com/en/rest/reference/actions/artifacts/ type ArtifactList struct { TotalCount *int64 `json:"total_count,omitempty"` Artifacts []*Artifact `json:"artifacts,omitempty"` @@ -38,7 +38,7 @@ type ArtifactList struct { // ListArtifacts lists all artifacts that belong to a repository. // -// GitHub API docs: https://developer.github.com/v3/actions/artifacts/#list-artifacts-for-a-repository +// GitHub API docs: https://docs.github.com/en/rest/reference/actions/#list-artifacts-for-a-repository func (s *ActionsService) ListArtifacts(ctx context.Context, owner, repo string, opts *ListOptions) (*ArtifactList, *Response, error) { u := fmt.Sprintf("repos/%v/%v/actions/artifacts", owner, repo) u, err := addOptions(u, opts) @@ -62,7 +62,7 @@ func (s *ActionsService) ListArtifacts(ctx context.Context, owner, repo string, // ListWorkflowRunArtifacts lists all artifacts that belong to a workflow run. // -// GitHub API docs: https://developer.github.com/v3/actions/artifacts/#list-workflow-run-artifacts +// GitHub API docs: https://docs.github.com/en/rest/reference/actions/#list-workflow-run-artifacts func (s *ActionsService) ListWorkflowRunArtifacts(ctx context.Context, owner, repo string, runID int64, opts *ListOptions) (*ArtifactList, *Response, error) { u := fmt.Sprintf("repos/%v/%v/actions/runs/%v/artifacts", owner, repo, runID) u, err := addOptions(u, opts) @@ -86,7 +86,7 @@ func (s *ActionsService) ListWorkflowRunArtifacts(ctx context.Context, owner, re // GetArtifact gets a specific artifact for a workflow run. // -// GitHub API docs: https://developer.github.com/v3/actions/artifacts/#get-an-artifact +// GitHub API docs: https://docs.github.com/en/rest/reference/actions/#get-an-artifact func (s *ActionsService) GetArtifact(ctx context.Context, owner, repo string, artifactID int64) (*Artifact, *Response, error) { u := fmt.Sprintf("repos/%v/%v/actions/artifacts/%v", owner, repo, artifactID) @@ -106,7 +106,7 @@ func (s *ActionsService) GetArtifact(ctx context.Context, owner, repo string, ar // DownloadArtifact gets a redirect URL to download an archive for a repository. // -// GitHub API docs: https://developer.github.com/v3/actions/artifacts/#download-an-artifact +// GitHub API docs: https://docs.github.com/en/rest/reference/actions/artifacts/#download-an-artifact func (s *ActionsService) DownloadArtifact(ctx context.Context, owner, repo string, artifactID int64, followRedirects bool) (*url.URL, *Response, error) { u := fmt.Sprintf("repos/%v/%v/actions/artifacts/%v/zip", owner, repo, artifactID) @@ -151,7 +151,7 @@ func (s *ActionsService) getDownloadArtifactFromURL(ctx context.Context, u strin // DeleteArtifact deletes a workflow run artifact. // -// GitHub API docs: https://developer.github.com/v3/actions/artifacts/#delete-an-artifact +// GitHub API docs: https://docs.github.com/en/rest/reference/actions/#delete-an-artifact func (s *ActionsService) DeleteArtifact(ctx context.Context, owner, repo string, artifactID int64) (*Response, error) { u := fmt.Sprintf("repos/%v/%v/actions/artifacts/%v", owner, repo, artifactID) diff --git a/github/actions_runners.go b/github/actions_runners.go index 8960ac8eaa0..f32ed9ac11a 100644 --- a/github/actions_runners.go +++ b/github/actions_runners.go @@ -20,7 +20,7 @@ type RunnerApplicationDownload struct { // ListRunnerApplicationDownloads lists self-hosted runner application binaries that can be downloaded and run. // -// GitHub API docs: https://developer.github.com/v3/actions/self-hosted-runners/#list-runner-applications-for-a-repository +// GitHub API docs: https://docs.github.com/en/rest/reference/actions/#list-runner-applications-for-a-repository func (s *ActionsService) ListRunnerApplicationDownloads(ctx context.Context, owner, repo string) ([]*RunnerApplicationDownload, *Response, error) { u := fmt.Sprintf("repos/%v/%v/actions/runners/downloads", owner, repo) req, err := s.client.NewRequest("GET", u, nil) @@ -45,7 +45,7 @@ type RegistrationToken struct { // CreateRegistrationToken creates a token that can be used to add a self-hosted runner. // -// GitHub API docs: https://developer.github.com/v3/actions/self-hosted-runners/#create-a-registration-token-for-a-repository +// GitHub API docs: https://docs.github.com/en/rest/reference/actions/#create-a-registration-token-for-a-repository func (s *ActionsService) CreateRegistrationToken(ctx context.Context, owner, repo string) (*RegistrationToken, *Response, error) { u := fmt.Sprintf("repos/%v/%v/actions/runners/registration-token", owner, repo) @@ -80,7 +80,7 @@ type Runners struct { // ListRunners lists all the self-hosted runners for a repository. // -// GitHub API docs: https://developer.github.com/v3/actions/self-hosted-runners/#list-self-hosted-runners-for-a-repository +// GitHub API docs: https://docs.github.com/en/rest/reference/actions/#list-self-hosted-runners-for-a-repository func (s *ActionsService) ListRunners(ctx context.Context, owner, repo string, opts *ListOptions) (*Runners, *Response, error) { u := fmt.Sprintf("repos/%v/%v/actions/runners", owner, repo) u, err := addOptions(u, opts) @@ -104,7 +104,7 @@ func (s *ActionsService) ListRunners(ctx context.Context, owner, repo string, op // GetRunner gets a specific self-hosted runner for a repository using its runner ID. // -// GitHub API docs: https://developer.github.com/v3/actions/self-hosted-runners/#get-a-self-hosted-runner-for-a-repository +// GitHub API docs: https://docs.github.com/en/rest/reference/actions/#get-a-self-hosted-runner-for-a-repository func (s *ActionsService) GetRunner(ctx context.Context, owner, repo string, runnerID int64) (*Runner, *Response, error) { u := fmt.Sprintf("repos/%v/%v/actions/runners/%v", owner, repo, runnerID) req, err := s.client.NewRequest("GET", u, nil) @@ -129,7 +129,7 @@ type RemoveToken struct { // CreateRemoveToken creates a token that can be used to remove a self-hosted runner from a repository. // -// GitHub API docs: https://developer.github.com/v3/actions/self-hosted-runners/#create-a-remove-token-for-a-repository +// GitHub API docs: https://docs.github.com/en/rest/reference/actions/#create-a-remove-token-for-a-repository func (s *ActionsService) CreateRemoveToken(ctx context.Context, owner, repo string) (*RemoveToken, *Response, error) { u := fmt.Sprintf("repos/%v/%v/actions/runners/remove-token", owner, repo) @@ -149,7 +149,7 @@ func (s *ActionsService) CreateRemoveToken(ctx context.Context, owner, repo stri // RemoveRunner forces the removal of a self-hosted runner in a repository using the runner id. // -// GitHub API docs: https://developer.github.com/v3/actions/self-hosted-runners/#delete-a-self-hosted-runner-from-a-repository +// GitHub API docs: https://docs.github.com/en/rest/reference/actions/#delete-a-self-hosted-runner-from-a-repository func (s *ActionsService) RemoveRunner(ctx context.Context, owner, repo string, runnerID int64) (*Response, error) { u := fmt.Sprintf("repos/%v/%v/actions/runners/%v", owner, repo, runnerID) @@ -163,7 +163,7 @@ func (s *ActionsService) RemoveRunner(ctx context.Context, owner, repo string, r // ListOrganizationRunnerApplicationDownloads lists self-hosted runner application binaries that can be downloaded and run. // -// GitHub API docs: https://developer.github.com/v3/actions/self-hosted-runners/#list-runner-applications-for-an-organization +// GitHub API docs: https://docs.github.com/en/rest/reference/actions/#list-runner-applications-for-an-organization func (s *ActionsService) ListOrganizationRunnerApplicationDownloads(ctx context.Context, owner string) ([]*RunnerApplicationDownload, *Response, error) { u := fmt.Sprintf("orgs/%v/actions/runners/downloads", owner) req, err := s.client.NewRequest("GET", u, nil) @@ -182,7 +182,7 @@ func (s *ActionsService) ListOrganizationRunnerApplicationDownloads(ctx context. // CreateOrganizationRegistrationToken creates a token that can be used to add a self-hosted runner to an organization. // -// GitHub API docs: https://developer.github.com/v3/actions/self-hosted-runners/#create-a-registration-token-for-an-organization +// GitHub API docs: https://docs.github.com/en/rest/reference/actions/#create-a-registration-token-for-an-organization func (s *ActionsService) CreateOrganizationRegistrationToken(ctx context.Context, owner string) (*RegistrationToken, *Response, error) { u := fmt.Sprintf("orgs/%v/actions/runners/registration-token", owner) @@ -202,7 +202,7 @@ func (s *ActionsService) CreateOrganizationRegistrationToken(ctx context.Context // ListOrganizationRunners lists all the self-hosted runners for an organization. // -// GitHub API docs: https://developer.github.com/v3/actions/self-hosted-runners/#list-self-hosted-runners-for-an-organization +// GitHub API docs: https://docs.github.com/en/rest/reference/actions/#list-self-hosted-runners-for-an-organization func (s *ActionsService) ListOrganizationRunners(ctx context.Context, owner string, opts *ListOptions) (*Runners, *Response, error) { u := fmt.Sprintf("orgs/%v/actions/runners", owner) u, err := addOptions(u, opts) @@ -226,7 +226,7 @@ func (s *ActionsService) ListOrganizationRunners(ctx context.Context, owner stri // GetOrganizationRunner gets a specific self-hosted runner for an organization using its runner ID. // -// GitHub API docs: https://developer.github.com/v3/actions/self-hosted-runners/#get-a-self-hosted-runner-for-an-organization +// GitHub API docs: https://docs.github.com/en/rest/reference/actions/#get-a-self-hosted-runner-for-an-organization func (s *ActionsService) GetOrganizationRunner(ctx context.Context, owner string, runnerID int64) (*Runner, *Response, error) { u := fmt.Sprintf("orgs/%v/actions/runners/%v", owner, runnerID) req, err := s.client.NewRequest("GET", u, nil) @@ -245,7 +245,7 @@ func (s *ActionsService) GetOrganizationRunner(ctx context.Context, owner string // CreateOrganizationRemoveToken creates a token that can be used to remove a self-hosted runner from an organization. // -// GitHub API docs: https://developer.github.com/v3/actions/self-hosted-runners/#create-a-remove-token-for-an-organization +// GitHub API docs: https://docs.github.com/en/rest/reference/actions/#create-a-remove-token-for-an-organization func (s *ActionsService) CreateOrganizationRemoveToken(ctx context.Context, owner string) (*RemoveToken, *Response, error) { u := fmt.Sprintf("orgs/%v/actions/runners/remove-token", owner) @@ -265,7 +265,7 @@ func (s *ActionsService) CreateOrganizationRemoveToken(ctx context.Context, owne // RemoveOrganizationRunner forces the removal of a self-hosted runner from an organization using the runner id. // -// GitHub API docs: https://developer.github.com/v3/actions/self-hosted-runners/#delete-a-self-hosted-runner-from-an-organization +// GitHub API docs: https://docs.github.com/en/rest/reference/actions/#delete-a-self-hosted-runner-from-an-organization func (s *ActionsService) RemoveOrganizationRunner(ctx context.Context, owner string, runnerID int64) (*Response, error) { u := fmt.Sprintf("orgs/%v/actions/runners/%v", owner, runnerID) diff --git a/github/actions_secrets.go b/github/actions_secrets.go index 695accfb67b..1a9828b041e 100644 --- a/github/actions_secrets.go +++ b/github/actions_secrets.go @@ -18,7 +18,7 @@ type PublicKey struct { // GetRepoPublicKey gets a public key that should be used for secret encryption. // -// GitHub API docs: https://developer.github.com/v3/actions/secrets/#get-a-repository-public-key +// GitHub API docs: https://docs.github.com/en/rest/reference/actions/#get-a-repository-public-key func (s *ActionsService) GetRepoPublicKey(ctx context.Context, owner, repo string) (*PublicKey, *Response, error) { u := fmt.Sprintf("repos/%v/%v/actions/secrets/public-key", owner, repo) req, err := s.client.NewRequest("GET", u, nil) @@ -37,7 +37,7 @@ func (s *ActionsService) GetRepoPublicKey(ctx context.Context, owner, repo strin // GetOrgPublicKey gets a public key that should be used for secret encryption. // -// GitHub API docs: https://developer.github.com/v3/actions/secrets/#get-an-organization-public-key +// GitHub API docs: https://docs.github.com/en/rest/reference/actions/#get-an-organization-public-key func (s *ActionsService) GetOrgPublicKey(ctx context.Context, org string) (*PublicKey, *Response, error) { u := fmt.Sprintf("orgs/%v/actions/secrets/public-key", org) req, err := s.client.NewRequest("GET", u, nil) @@ -72,7 +72,7 @@ type Secrets struct { // ListRepoSecrets lists all secrets available in a repository // without revealing their encrypted values. // -// GitHub API docs: https://developer.github.com/v3/actions/secrets/#list-repository-secrets +// GitHub API docs: https://docs.github.com/en/rest/reference/actions/#list-repository-secrets func (s *ActionsService) ListRepoSecrets(ctx context.Context, owner, repo string, opts *ListOptions) (*Secrets, *Response, error) { u := fmt.Sprintf("repos/%v/%v/actions/secrets", owner, repo) u, err := addOptions(u, opts) @@ -96,7 +96,7 @@ func (s *ActionsService) ListRepoSecrets(ctx context.Context, owner, repo string // GetRepoSecret gets a single repository secret without revealing its encrypted value. // -// GitHub API docs: https://developer.github.com/v3/actions/secrets/#get-a-repository-secret +// GitHub API docs: https://docs.github.com/en/rest/reference/actions/#get-a-repository-secret func (s *ActionsService) GetRepoSecret(ctx context.Context, owner, repo, name string) (*Secret, *Response, error) { u := fmt.Sprintf("repos/%v/%v/actions/secrets/%v", owner, repo, name) req, err := s.client.NewRequest("GET", u, nil) @@ -131,7 +131,7 @@ type EncryptedSecret struct { // CreateOrUpdateRepoSecret creates or updates a repository secret with an encrypted value. // -// GitHub API docs: https://developer.github.com/v3/actions/secrets/#create-or-update-a-repository-secret +// GitHub API docs: https://docs.github.com/en/rest/reference/actions/#create-or-update-a-repository-secret func (s *ActionsService) CreateOrUpdateRepoSecret(ctx context.Context, owner, repo string, eSecret *EncryptedSecret) (*Response, error) { u := fmt.Sprintf("repos/%v/%v/actions/secrets/%v", owner, repo, eSecret.Name) @@ -145,7 +145,7 @@ func (s *ActionsService) CreateOrUpdateRepoSecret(ctx context.Context, owner, re // DeleteRepoSecret deletes a secret in a repository using the secret name. // -// GitHub API docs: https://developer.github.com/v3/actions/secrets/#delete-a-repository-secret +// GitHub API docs: https://docs.github.com/en/rest/reference/actions/#delete-a-repository-secret func (s *ActionsService) DeleteRepoSecret(ctx context.Context, owner, repo, name string) (*Response, error) { u := fmt.Sprintf("repos/%v/%v/actions/secrets/%v", owner, repo, name) @@ -160,7 +160,7 @@ func (s *ActionsService) DeleteRepoSecret(ctx context.Context, owner, repo, name // ListOrgSecrets lists all secrets available in an organization // without revealing their encrypted values. // -// GitHub API docs: https://developer.github.com/v3/actions/secrets/#list-organization-secrets +// GitHub API docs: https://docs.github.com/en/rest/reference/actions/#list-organization-secrets func (s *ActionsService) ListOrgSecrets(ctx context.Context, org string, opts *ListOptions) (*Secrets, *Response, error) { u := fmt.Sprintf("orgs/%v/actions/secrets", org) u, err := addOptions(u, opts) @@ -184,7 +184,7 @@ func (s *ActionsService) ListOrgSecrets(ctx context.Context, org string, opts *L // GetOrgSecret gets a single organization secret without revealing its encrypted value. // -// GitHub API docs: https://developer.github.com/v3/actions/secrets/#get-an-organization-secret +// GitHub API docs: https://docs.github.com/en/rest/reference/actions/#get-an-organization-secret func (s *ActionsService) GetOrgSecret(ctx context.Context, org, name string) (*Secret, *Response, error) { u := fmt.Sprintf("orgs/%v/actions/secrets/%v", org, name) req, err := s.client.NewRequest("GET", u, nil) @@ -203,7 +203,7 @@ func (s *ActionsService) GetOrgSecret(ctx context.Context, org, name string) (*S // CreateOrUpdateOrgSecret creates or updates an organization secret with an encrypted value. // -// GitHub API docs: https://developer.github.com/v3/actions/secrets/#create-or-update-an-organization-secret +// GitHub API docs: https://docs.github.com/en/rest/reference/actions/#create-or-update-an-organization-secret func (s *ActionsService) CreateOrUpdateOrgSecret(ctx context.Context, org string, eSecret *EncryptedSecret) (*Response, error) { u := fmt.Sprintf("orgs/%v/actions/secrets/%v", org, eSecret.Name) @@ -223,7 +223,7 @@ type SelectedReposList struct { // ListSelectedReposForOrgSecret lists all repositories that have access to a secret. // -// GitHub API docs: https://developer.github.com/v3/actions/secrets/#list-selected-repositories-for-an-organization-secret +// GitHub API docs: https://docs.github.com/en/rest/reference/actions/#list-selected-repositories-for-an-organization-secret func (s *ActionsService) ListSelectedReposForOrgSecret(ctx context.Context, org, name string) (*SelectedReposList, *Response, error) { u := fmt.Sprintf("orgs/%v/actions/secrets/%v/repositories", org, name) req, err := s.client.NewRequest("GET", u, nil) @@ -242,7 +242,7 @@ func (s *ActionsService) ListSelectedReposForOrgSecret(ctx context.Context, org, // SetSelectedReposForOrgSecret sets the repositories that have access to a secret. // -// GitHub API docs: https://developer.github.com/v3/actions/secrets/#set-selected-repositories-for-an-organization-secret +// GitHub API docs: https://docs.github.com/en/rest/reference/actions/#set-selected-repositories-for-an-organization-secret func (s *ActionsService) SetSelectedReposForOrgSecret(ctx context.Context, org, name string, ids SelectedRepoIDs) (*Response, error) { u := fmt.Sprintf("orgs/%v/actions/secrets/%v/repositories", org, name) @@ -260,7 +260,7 @@ func (s *ActionsService) SetSelectedReposForOrgSecret(ctx context.Context, org, // AddSelectedRepoToOrgSecret adds a repository to an organization secret. // -// GitHub API docs: https://developer.github.com/v3/actions/secrets/#add-selected-repository-to-an-organization-secret +// GitHub API docs: https://docs.github.com/en/rest/reference/actions/#add-selected-repository-to-an-organization-secret func (s *ActionsService) AddSelectedRepoToOrgSecret(ctx context.Context, org, name string, repo *Repository) (*Response, error) { u := fmt.Sprintf("orgs/%v/actions/secrets/%v/repositories/%v", org, name, *repo.ID) req, err := s.client.NewRequest("PUT", u, nil) @@ -273,7 +273,7 @@ func (s *ActionsService) AddSelectedRepoToOrgSecret(ctx context.Context, org, na // RemoveSelectedRepoFromOrgSecret removes a repository from an organization secret. // -// GitHub API docs: https://developer.github.com/v3/actions/secrets/#remove-selected-repository-from-an-organization-secret +// GitHub API docs: https://docs.github.com/en/rest/reference/actions/#remove-selected-repository-from-an-organization-secret func (s *ActionsService) RemoveSelectedRepoFromOrgSecret(ctx context.Context, org, name string, repo *Repository) (*Response, error) { u := fmt.Sprintf("orgs/%v/actions/secrets/%v/repositories/%v", org, name, *repo.ID) req, err := s.client.NewRequest("DELETE", u, nil) @@ -286,7 +286,7 @@ func (s *ActionsService) RemoveSelectedRepoFromOrgSecret(ctx context.Context, or // DeleteOrgSecret deletes a secret in an organization using the secret name. // -// GitHub API docs: https://developer.github.com/v3/actions/secrets/#delete-an-organization-secret +// GitHub API docs: https://docs.github.com/en/rest/reference/actions/#delete-an-organization-secret func (s *ActionsService) DeleteOrgSecret(ctx context.Context, org, name string) (*Response, error) { u := fmt.Sprintf("orgs/%v/actions/secrets/%v", org, name) diff --git a/github/actions_workflow_jobs.go b/github/actions_workflow_jobs.go index f1506ffecfd..373f3d46e85 100644 --- a/github/actions_workflow_jobs.go +++ b/github/actions_workflow_jobs.go @@ -60,7 +60,7 @@ type ListWorkflowJobsOptions struct { // ListWorkflowJobs lists all jobs for a workflow run. // -// GitHub API docs: https://developer.github.com/v3/actions/workflow-jobs/#list-jobs-for-a-workflow-run +// GitHub API docs: https://docs.github.com/en/rest/reference/actions/#list-jobs-for-a-workflow-run func (s *ActionsService) ListWorkflowJobs(ctx context.Context, owner, repo string, runID int64, opts *ListWorkflowJobsOptions) (*Jobs, *Response, error) { u := fmt.Sprintf("repos/%s/%s/actions/runs/%v/jobs", owner, repo, runID) u, err := addOptions(u, opts) @@ -84,7 +84,7 @@ func (s *ActionsService) ListWorkflowJobs(ctx context.Context, owner, repo strin // GetWorkflowJobByID gets a specific job in a workflow run by ID. // -// GitHub API docs: https://developer.github.com/v3/actions/workflow-jobs/#get-a-job-for-a-workflow-run +// GitHub API docs: https://docs.github.com/en/rest/reference/actions/#get-a-job-for-a-workflow-run func (s *ActionsService) GetWorkflowJobByID(ctx context.Context, owner, repo string, jobID int64) (*WorkflowJob, *Response, error) { u := fmt.Sprintf("repos/%v/%v/actions/jobs/%v", owner, repo, jobID) @@ -104,7 +104,7 @@ func (s *ActionsService) GetWorkflowJobByID(ctx context.Context, owner, repo str // GetWorkflowJobLogs gets a redirect URL to download a plain text file of logs for a workflow job. // -// GitHub API docs: https://developer.github.com/v3/actions/workflow-jobs/#download-job-logs-for-a-workflow-run +// GitHub API docs: https://docs.github.com/en/rest/reference/actions/#download-job-logs-for-a-workflow-run func (s *ActionsService) GetWorkflowJobLogs(ctx context.Context, owner, repo string, jobID int64, followRedirects bool) (*url.URL, *Response, error) { u := fmt.Sprintf("repos/%v/%v/actions/jobs/%v/logs", owner, repo, jobID) diff --git a/github/actions_workflow_runs.go b/github/actions_workflow_runs.go index 9d4c00ea39c..de9a34aaf32 100644 --- a/github/actions_workflow_runs.go +++ b/github/actions_workflow_runs.go @@ -96,7 +96,7 @@ func (s *ActionsService) listWorkflowRuns(ctx context.Context, endpoint string, // ListWorkflowRunsByID lists all workflow runs by workflow ID. // -// GitHub API docs: https://developer.github.com/v3/actions/workflow-runs/#list-workflow-runs +// GitHub API docs: https://docs.github.com/en/rest/reference/actions/#list-workflow-runs func (s *ActionsService) ListWorkflowRunsByID(ctx context.Context, owner, repo string, workflowID int64, opts *ListWorkflowRunsOptions) (*WorkflowRuns, *Response, error) { u := fmt.Sprintf("repos/%s/%s/actions/workflows/%v/runs", owner, repo, workflowID) return s.listWorkflowRuns(ctx, u, opts) @@ -104,7 +104,7 @@ func (s *ActionsService) ListWorkflowRunsByID(ctx context.Context, owner, repo s // ListWorkflowRunsByFileName lists all workflow runs by workflow file name. // -// GitHub API docs: https://developer.github.com/v3/actions/workflow-runs/#list-workflow-runs +// GitHub API docs: https://docs.github.com/en/rest/reference/actions/#list-workflow-runs func (s *ActionsService) ListWorkflowRunsByFileName(ctx context.Context, owner, repo, workflowFileName string, opts *ListWorkflowRunsOptions) (*WorkflowRuns, *Response, error) { u := fmt.Sprintf("repos/%s/%s/actions/workflows/%v/runs", owner, repo, workflowFileName) return s.listWorkflowRuns(ctx, u, opts) @@ -112,7 +112,7 @@ func (s *ActionsService) ListWorkflowRunsByFileName(ctx context.Context, owner, // ListRepositoryWorkflowRuns lists all workflow runs for a repository. // -// GitHub API docs: https://developer.github.com/v3/actions/workflow-runs/#list-workflow-runs-for-a-repository +// GitHub API docs: https://docs.github.com/en/rest/reference/actions/#list-workflow-runs-for-a-repository func (s *ActionsService) ListRepositoryWorkflowRuns(ctx context.Context, owner, repo string, opts *ListWorkflowRunsOptions) (*WorkflowRuns, *Response, error) { u := fmt.Sprintf("repos/%s/%s/actions/runs", owner, repo) u, err := addOptions(u, opts) @@ -136,7 +136,7 @@ func (s *ActionsService) ListRepositoryWorkflowRuns(ctx context.Context, owner, // GetWorkflowRunByID gets a specific workflow run by ID. // -// GitHub API docs: https://developer.github.com/v3/actions/workflow-runs/#get-a-workflow-run +// GitHub API docs: https://docs.github.com/en/rest/reference/actions/#get-a-workflow-run func (s *ActionsService) GetWorkflowRunByID(ctx context.Context, owner, repo string, runID int64) (*WorkflowRun, *Response, error) { u := fmt.Sprintf("repos/%v/%v/actions/runs/%v", owner, repo, runID) @@ -156,7 +156,7 @@ func (s *ActionsService) GetWorkflowRunByID(ctx context.Context, owner, repo str // RerunWorkflowByID re-runs a workflow by ID. // -// GitHub API docs: https://developer.github.com/v3/actions/workflow-runs/#re-run-a-workflow +// GitHub API docs: https://docs.github.com/en/rest/reference/actions/#re-run-a-workflow func (s *ActionsService) RerunWorkflowByID(ctx context.Context, owner, repo string, runID int64) (*Response, error) { u := fmt.Sprintf("repos/%v/%v/actions/runs/%v/rerun", owner, repo, runID) @@ -170,7 +170,7 @@ func (s *ActionsService) RerunWorkflowByID(ctx context.Context, owner, repo stri // CancelWorkflowRunByID cancels a workflow run by ID. // -// GitHub API docs: https://developer.github.com/v3/actions/workflow-runs/#cancel-a-workflow-run +// GitHub API docs: https://docs.github.com/en/rest/reference/actions/#cancel-a-workflow-run func (s *ActionsService) CancelWorkflowRunByID(ctx context.Context, owner, repo string, runID int64) (*Response, error) { u := fmt.Sprintf("repos/%v/%v/actions/runs/%v/cancel", owner, repo, runID) @@ -184,7 +184,7 @@ func (s *ActionsService) CancelWorkflowRunByID(ctx context.Context, owner, repo // GetWorkflowRunLogs gets a redirect URL to download a plain text file of logs for a workflow run. // -// GitHub API docs: https://developer.github.com/v3/actions/workflow-runs/#download-workflow-run-logs +// GitHub API docs: https://docs.github.com/en/rest/reference/actions/#download-workflow-run-logs func (s *ActionsService) GetWorkflowRunLogs(ctx context.Context, owner, repo string, runID int64, followRedirects bool) (*url.URL, *Response, error) { u := fmt.Sprintf("repos/%v/%v/actions/runs/%v/logs", owner, repo, runID) @@ -202,7 +202,7 @@ func (s *ActionsService) GetWorkflowRunLogs(ctx context.Context, owner, repo str // DeleteWorkflowRunLogs deletes all logs for a workflow run. // -// GitHub API docs: https://developer.github.com/v3/actions/workflow-runs/#delete-workflow-run-logs +// GitHub API docs: https://docs.github.com/en/rest/reference/actions/#delete-workflow-run-logs func (s *ActionsService) DeleteWorkflowRunLogs(ctx context.Context, owner, repo string, runID int64) (*Response, error) { u := fmt.Sprintf("repos/%v/%v/actions/runs/%v/logs", owner, repo, runID) @@ -216,7 +216,7 @@ func (s *ActionsService) DeleteWorkflowRunLogs(ctx context.Context, owner, repo // GetWorkflowRunUsageByID gets a specific workflow usage run by run ID in the unit of billable milliseconds. // -// GitHub API docs: https://developer.github.com/v3/actions/workflow-runs/#get-workflow-run-usage +// GitHub API docs: https://docs.github.com/en/rest/reference/actions/#get-workflow-run-usage func (s *ActionsService) GetWorkflowRunUsageByID(ctx context.Context, owner, repo string, runID int64) (*WorkflowRunUsage, *Response, error) { u := fmt.Sprintf("repos/%v/%v/actions/runs/%v/timing", owner, repo, runID) diff --git a/github/actions_workflows.go b/github/actions_workflows.go index 6dd02feb67d..d72e40fa7a6 100644 --- a/github/actions_workflows.go +++ b/github/actions_workflows.go @@ -49,7 +49,7 @@ type WorkflowBill struct { // ListWorkflows lists all workflows in a repository. // -// GitHub API docs: https://developer.github.com/v3/actions/workflows/#list-repository-workflows +// GitHub API docs: https://docs.github.com/en/rest/reference/actions/#list-repository-workflows func (s *ActionsService) ListWorkflows(ctx context.Context, owner, repo string, opts *ListOptions) (*Workflows, *Response, error) { u := fmt.Sprintf("repos/%s/%s/actions/workflows", owner, repo) u, err := addOptions(u, opts) @@ -73,7 +73,7 @@ func (s *ActionsService) ListWorkflows(ctx context.Context, owner, repo string, // GetWorkflowByID gets a specific workflow by ID. // -// GitHub API docs: https://developer.github.com/v3/actions/workflows/#get-a-workflow +// GitHub API docs: https://docs.github.com/en/rest/reference/actions/#get-a-workflow func (s *ActionsService) GetWorkflowByID(ctx context.Context, owner, repo string, workflowID int64) (*Workflow, *Response, error) { u := fmt.Sprintf("repos/%v/%v/actions/workflows/%v", owner, repo, workflowID) @@ -82,7 +82,7 @@ func (s *ActionsService) GetWorkflowByID(ctx context.Context, owner, repo string // GetWorkflowByFileName gets a specific workflow by file name. // -// GitHub API docs: https://developer.github.com/v3/actions/workflows/#get-a-workflow +// GitHub API docs: https://docs.github.com/en/rest/reference/actions/#get-a-workflow func (s *ActionsService) GetWorkflowByFileName(ctx context.Context, owner, repo, workflowFileName string) (*Workflow, *Response, error) { u := fmt.Sprintf("repos/%v/%v/actions/workflows/%v", owner, repo, workflowFileName) @@ -106,7 +106,7 @@ func (s *ActionsService) getWorkflow(ctx context.Context, url string) (*Workflow // GetWorkflowUsageByID gets a specific workflow usage by ID in the unit of billable milliseconds. // -// GitHub API docs: https://developer.github.com/v3/actions/workflows/#get-workflow-usage +// GitHub API docs: https://docs.github.com/en/rest/reference/actions/#get-workflow-usage func (s *ActionsService) GetWorkflowUsageByID(ctx context.Context, owner, repo string, workflowID int64) (*WorkflowUsage, *Response, error) { u := fmt.Sprintf("repos/%v/%v/actions/workflows/%v/timing", owner, repo, workflowID) @@ -115,7 +115,7 @@ func (s *ActionsService) GetWorkflowUsageByID(ctx context.Context, owner, repo s // GetWorkflowUsageByFileName gets a specific workflow usage by file name in the unit of billable milliseconds. // -// GitHub API docs: https://developer.github.com/v3/actions/workflows/#get-workflow-usage +// GitHub API docs: https://docs.github.com/en/rest/reference/actions/#get-workflow-usage func (s *ActionsService) GetWorkflowUsageByFileName(ctx context.Context, owner, repo, workflowFileName string) (*WorkflowUsage, *Response, error) { u := fmt.Sprintf("repos/%v/%v/actions/workflows/%v/timing", owner, repo, workflowFileName) diff --git a/github/activity.go b/github/activity.go index f6336fcc99a..6a93980d145 100644 --- a/github/activity.go +++ b/github/activity.go @@ -10,7 +10,7 @@ import "context" // ActivityService handles communication with the activity related // methods of the GitHub API. // -// GitHub API docs: https://developer.github.com/v3/activity/ +// GitHub API docs: https://docs.github.com/en/rest/reference/activity/ type ActivityService service // FeedLink represents a link to a related resource. diff --git a/github/activity_events.go b/github/activity_events.go index e795b9f0ae2..34951112873 100644 --- a/github/activity_events.go +++ b/github/activity_events.go @@ -12,7 +12,7 @@ import ( // ListEvents drinks from the firehose of all public events across GitHub. // -// GitHub API docs: https://developer.github.com/v3/activity/events/#list-public-events +// GitHub API docs: https://docs.github.com/en/rest/reference/activity/#list-public-events func (s *ActivityService) ListEvents(ctx context.Context, opts *ListOptions) ([]*Event, *Response, error) { u, err := addOptions("events", opts) if err != nil { @@ -35,7 +35,7 @@ func (s *ActivityService) ListEvents(ctx context.Context, opts *ListOptions) ([] // ListRepositoryEvents lists events for a repository. // -// GitHub API docs: https://developer.github.com/v3/activity/events/#list-repository-events +// GitHub API docs: https://docs.github.com/en/rest/reference/activity/#list-repository-events func (s *ActivityService) ListRepositoryEvents(ctx context.Context, owner, repo string, opts *ListOptions) ([]*Event, *Response, error) { u := fmt.Sprintf("repos/%v/%v/events", owner, repo) u, err := addOptions(u, opts) @@ -59,7 +59,7 @@ func (s *ActivityService) ListRepositoryEvents(ctx context.Context, owner, repo // ListIssueEventsForRepository lists issue events for a repository. // -// GitHub API docs: https://developer.github.com/v3/issues/events/#list-issue-events-for-a-repository +// GitHub API docs: https://docs.github.com/en/rest/reference/issues/#list-issue-events-for-a-repository func (s *ActivityService) ListIssueEventsForRepository(ctx context.Context, owner, repo string, opts *ListOptions) ([]*IssueEvent, *Response, error) { u := fmt.Sprintf("repos/%v/%v/issues/events", owner, repo) u, err := addOptions(u, opts) @@ -83,7 +83,7 @@ func (s *ActivityService) ListIssueEventsForRepository(ctx context.Context, owne // ListEventsForRepoNetwork lists public events for a network of repositories. // -// GitHub API docs: https://developer.github.com/v3/activity/events/#list-public-events-for-a-network-of-repositories +// GitHub API docs: https://docs.github.com/en/rest/reference/activity/#list-public-events-for-a-network-of-repositories func (s *ActivityService) ListEventsForRepoNetwork(ctx context.Context, owner, repo string, opts *ListOptions) ([]*Event, *Response, error) { u := fmt.Sprintf("networks/%v/%v/events", owner, repo) u, err := addOptions(u, opts) @@ -107,7 +107,7 @@ func (s *ActivityService) ListEventsForRepoNetwork(ctx context.Context, owner, r // ListEventsForOrganization lists public events for an organization. // -// GitHub API docs: https://developer.github.com/v3/activity/events/#list-public-organization-events +// GitHub API docs: https://docs.github.com/en/rest/reference/activity/#list-public-organization-events func (s *ActivityService) ListEventsForOrganization(ctx context.Context, org string, opts *ListOptions) ([]*Event, *Response, error) { u := fmt.Sprintf("orgs/%v/events", org) u, err := addOptions(u, opts) @@ -132,8 +132,8 @@ func (s *ActivityService) ListEventsForOrganization(ctx context.Context, org str // ListEventsPerformedByUser lists the events performed by a user. If publicOnly is // true, only public events will be returned. // -// GitHub API docs: https://developer.github.com/v3/activity/events/#list-events-for-the-authenticated-user -// GitHub API docs: https://developer.github.com/v3/activity/events/#list-public-events-for-a-user +// GitHub API docs: https://docs.github.com/en/rest/reference/activity/#list-events-for-the-authenticated-user +// GitHub API docs: https://docs.github.com/en/rest/reference/activity/#list-public-events-for-a-user func (s *ActivityService) ListEventsPerformedByUser(ctx context.Context, user string, publicOnly bool, opts *ListOptions) ([]*Event, *Response, error) { var u string if publicOnly { @@ -163,8 +163,8 @@ func (s *ActivityService) ListEventsPerformedByUser(ctx context.Context, user st // ListEventsReceivedByUser lists the events received by a user. If publicOnly is // true, only public events will be returned. // -// GitHub API docs: https://developer.github.com/v3/activity/events/#list-events-received-by-the-authenticated-user -// GitHub API docs: https://developer.github.com/v3/activity/events/#list-public-events-received-by-a-user +// GitHub API docs: https://docs.github.com/en/rest/reference/activity/#list-events-received-by-the-authenticated-user +// GitHub API docs: https://docs.github.com/en/rest/reference/activity/#list-public-events-received-by-a-user func (s *ActivityService) ListEventsReceivedByUser(ctx context.Context, user string, publicOnly bool, opts *ListOptions) ([]*Event, *Response, error) { var u string if publicOnly { @@ -194,7 +194,7 @@ func (s *ActivityService) ListEventsReceivedByUser(ctx context.Context, user str // ListUserEventsForOrganization provides the user’s organization dashboard. You // must be authenticated as the user to view this. // -// GitHub API docs: https://developer.github.com/v3/activity/events/#list-organization-events-for-the-authenticated-user +// GitHub API docs: https://docs.github.com/en/rest/reference/activity/#list-organization-events-for-the-authenticated-user func (s *ActivityService) ListUserEventsForOrganization(ctx context.Context, org, user string, opts *ListOptions) ([]*Event, *Response, error) { u := fmt.Sprintf("users/%v/events/orgs/%v", user, org) u, err := addOptions(u, opts) diff --git a/github/activity_notifications.go b/github/activity_notifications.go index 9c19922bb30..8389de8243c 100644 --- a/github/activity_notifications.go +++ b/github/activity_notifications.go @@ -19,7 +19,7 @@ type Notification struct { // Reason identifies the event that triggered the notification. // - // GitHub API docs: https://developer.github.com/v3/activity/notifications/#notification-reasons + // GitHub API docs: https://docs.github.com/en/rest/reference/activity/notifications/#notification-reasons Reason *string `json:"reason,omitempty"` Unread *bool `json:"unread,omitempty"` @@ -49,7 +49,7 @@ type NotificationListOptions struct { // ListNotifications lists all notifications for the authenticated user. // -// GitHub API docs: https://developer.github.com/v3/activity/notifications/#list-notifications-for-the-authenticated-user +// GitHub API docs: https://docs.github.com/en/rest/reference/activity/#list-notifications-for-the-authenticated-user func (s *ActivityService) ListNotifications(ctx context.Context, opts *NotificationListOptions) ([]*Notification, *Response, error) { u := fmt.Sprintf("notifications") u, err := addOptions(u, opts) @@ -74,7 +74,7 @@ func (s *ActivityService) ListNotifications(ctx context.Context, opts *Notificat // ListRepositoryNotifications lists all notifications in a given repository // for the authenticated user. // -// GitHub API docs: https://developer.github.com/v3/activity/notifications/#list-repository-notifications-for-the-authenticated-user +// GitHub API docs: https://docs.github.com/en/rest/reference/activity/#list-repository-notifications-for-the-authenticated-user func (s *ActivityService) ListRepositoryNotifications(ctx context.Context, owner, repo string, opts *NotificationListOptions) ([]*Notification, *Response, error) { u := fmt.Sprintf("repos/%v/%v/notifications", owner, repo) u, err := addOptions(u, opts) @@ -102,7 +102,7 @@ type markReadOptions struct { // MarkNotificationsRead marks all notifications up to lastRead as read. // -// GitHub API docs: https://developer.github.com/v3/activity/notifications/#mark-as-read +// GitHub API docs: https://docs.github.com/en/rest/reference/activity/notifications/#mark-as-read func (s *ActivityService) MarkNotificationsRead(ctx context.Context, lastRead time.Time) (*Response, error) { opts := &markReadOptions{ LastReadAt: lastRead, @@ -118,7 +118,7 @@ func (s *ActivityService) MarkNotificationsRead(ctx context.Context, lastRead ti // MarkRepositoryNotificationsRead marks all notifications up to lastRead in // the specified repository as read. // -// GitHub API docs: https://developer.github.com/v3/activity/notifications/#mark-repository-notifications-as-read +// GitHub API docs: https://docs.github.com/en/rest/reference/activity/#mark-repository-notifications-as-read func (s *ActivityService) MarkRepositoryNotificationsRead(ctx context.Context, owner, repo string, lastRead time.Time) (*Response, error) { opts := &markReadOptions{ LastReadAt: lastRead, @@ -134,7 +134,7 @@ func (s *ActivityService) MarkRepositoryNotificationsRead(ctx context.Context, o // GetThread gets the specified notification thread. // -// GitHub API docs: https://developer.github.com/v3/activity/notifications/#get-a-thread +// GitHub API docs: https://docs.github.com/en/rest/reference/activity/#get-a-thread func (s *ActivityService) GetThread(ctx context.Context, id string) (*Notification, *Response, error) { u := fmt.Sprintf("notifications/threads/%v", id) @@ -154,7 +154,7 @@ func (s *ActivityService) GetThread(ctx context.Context, id string) (*Notificati // MarkThreadRead marks the specified thread as read. // -// GitHub API docs: https://developer.github.com/v3/activity/notifications/#mark-a-thread-as-read +// GitHub API docs: https://docs.github.com/en/rest/reference/activity/#mark-a-thread-as-read func (s *ActivityService) MarkThreadRead(ctx context.Context, id string) (*Response, error) { u := fmt.Sprintf("notifications/threads/%v", id) @@ -169,7 +169,7 @@ func (s *ActivityService) MarkThreadRead(ctx context.Context, id string) (*Respo // GetThreadSubscription checks to see if the authenticated user is subscribed // to a thread. // -// GitHub API docs: https://developer.github.com/v3/activity/notifications/#get-a-thread-subscription-for-the-authenticated-user +// GitHub API docs: https://docs.github.com/en/rest/reference/activity/#get-a-thread-subscription-for-the-authenticated-user func (s *ActivityService) GetThreadSubscription(ctx context.Context, id string) (*Subscription, *Response, error) { u := fmt.Sprintf("notifications/threads/%v/subscription", id) @@ -190,7 +190,7 @@ func (s *ActivityService) GetThreadSubscription(ctx context.Context, id string) // SetThreadSubscription sets the subscription for the specified thread for the // authenticated user. // -// GitHub API docs: https://developer.github.com/v3/activity/notifications/#set-a-thread-subscription +// GitHub API docs: https://docs.github.com/en/rest/reference/activity/#set-a-thread-subscription func (s *ActivityService) SetThreadSubscription(ctx context.Context, id string, subscription *Subscription) (*Subscription, *Response, error) { u := fmt.Sprintf("notifications/threads/%v/subscription", id) @@ -211,7 +211,7 @@ func (s *ActivityService) SetThreadSubscription(ctx context.Context, id string, // DeleteThreadSubscription deletes the subscription for the specified thread // for the authenticated user. // -// GitHub API docs: https://developer.github.com/v3/activity/notifications/#delete-a-thread-subscription +// GitHub API docs: https://docs.github.com/en/rest/reference/activity/#delete-a-thread-subscription func (s *ActivityService) DeleteThreadSubscription(ctx context.Context, id string) (*Response, error) { u := fmt.Sprintf("notifications/threads/%v/subscription", id) req, err := s.client.NewRequest("DELETE", u, nil) diff --git a/github/activity_star.go b/github/activity_star.go index 158f395210a..11f362e444f 100644 --- a/github/activity_star.go +++ b/github/activity_star.go @@ -25,7 +25,7 @@ type Stargazer struct { // ListStargazers lists people who have starred the specified repo. // -// GitHub API docs: https://developer.github.com/v3/activity/starring/#list-stargazers +// GitHub API docs: https://docs.github.com/en/rest/reference/activity/#list-stargazers func (s *ActivityService) ListStargazers(ctx context.Context, owner, repo string, opts *ListOptions) ([]*Stargazer, *Response, error) { u := fmt.Sprintf("repos/%s/%s/stargazers", owner, repo) u, err := addOptions(u, opts) @@ -67,8 +67,8 @@ type ActivityListStarredOptions struct { // ListStarred lists all the repos starred by a user. Passing the empty string // will list the starred repositories for the authenticated user. // -// GitHub API docs: https://developer.github.com/v3/activity/starring/#list-repositories-starred-by-a-user -// GitHub API docs: https://developer.github.com/v3/activity/starring/#list-repositories-starred-by-the-authenticated-user +// GitHub API docs: https://docs.github.com/en/rest/reference/activity/#list-repositories-starred-by-the-authenticated-user +// GitHub API docs: https://docs.github.com/en/rest/reference/activity/#list-repositories-starred-by-a-user func (s *ActivityService) ListStarred(ctx context.Context, user string, opts *ActivityListStarredOptions) ([]*StarredRepository, *Response, error) { var u string if user != "" { @@ -101,7 +101,7 @@ func (s *ActivityService) ListStarred(ctx context.Context, user string, opts *Ac // IsStarred checks if a repository is starred by authenticated user. // -// GitHub API docs: https://developer.github.com/v3/activity/starring/#check-if-a-repository-is-starred-by-the-authenticated-user +// GitHub API docs: https://docs.github.com/en/rest/reference/activity/#check-if-a-repository-is-starred-by-the-authenticated-user func (s *ActivityService) IsStarred(ctx context.Context, owner, repo string) (bool, *Response, error) { u := fmt.Sprintf("user/starred/%v/%v", owner, repo) req, err := s.client.NewRequest("GET", u, nil) @@ -115,7 +115,7 @@ func (s *ActivityService) IsStarred(ctx context.Context, owner, repo string) (bo // Star a repository as the authenticated user. // -// GitHub API docs: https://developer.github.com/v3/activity/starring/#star-a-repository-for-the-authenticated-user +// GitHub API docs: https://docs.github.com/en/rest/reference/activity/#star-a-repository-for-the-authenticated-user func (s *ActivityService) Star(ctx context.Context, owner, repo string) (*Response, error) { u := fmt.Sprintf("user/starred/%v/%v", owner, repo) req, err := s.client.NewRequest("PUT", u, nil) @@ -127,7 +127,7 @@ func (s *ActivityService) Star(ctx context.Context, owner, repo string) (*Respon // Unstar a repository as the authenticated user. // -// GitHub API docs: https://developer.github.com/v3/activity/starring/#unstar-a-repository-for-the-authenticated-user +// GitHub API docs: https://docs.github.com/en/rest/reference/activity/#unstar-a-repository-for-the-authenticated-user func (s *ActivityService) Unstar(ctx context.Context, owner, repo string) (*Response, error) { u := fmt.Sprintf("user/starred/%v/%v", owner, repo) req, err := s.client.NewRequest("DELETE", u, nil) diff --git a/github/activity_watching.go b/github/activity_watching.go index 0265a08d0d9..1ac731ef18a 100644 --- a/github/activity_watching.go +++ b/github/activity_watching.go @@ -27,7 +27,7 @@ type Subscription struct { // ListWatchers lists watchers of a particular repo. // -// GitHub API docs: https://developer.github.com/v3/activity/watching/#list-watchers +// GitHub API docs: https://docs.github.com/en/rest/reference/activity/#list-watchers func (s *ActivityService) ListWatchers(ctx context.Context, owner, repo string, opts *ListOptions) ([]*User, *Response, error) { u := fmt.Sprintf("repos/%s/%s/subscribers", owner, repo) u, err := addOptions(u, opts) @@ -52,8 +52,8 @@ func (s *ActivityService) ListWatchers(ctx context.Context, owner, repo string, // ListWatched lists the repositories the specified user is watching. Passing // the empty string will fetch watched repos for the authenticated user. // -// GitHub API docs: https://developer.github.com/v3/activity/watching/#list-repositories-watched-by-a-user -// GitHub API docs: https://developer.github.com/v3/activity/watching/#list-repositories-watched-by-the-authenticated-user +// GitHub API docs: https://docs.github.com/en/rest/reference/activity/#list-repositories-watched-by-the-authenticated-user +// GitHub API docs: https://docs.github.com/en/rest/reference/activity/#list-repositories-watched-by-a-user func (s *ActivityService) ListWatched(ctx context.Context, user string, opts *ListOptions) ([]*Repository, *Response, error) { var u string if user != "" { @@ -84,7 +84,7 @@ func (s *ActivityService) ListWatched(ctx context.Context, user string, opts *Li // repository for the authenticated user. If the authenticated user is not // watching the repository, a nil Subscription is returned. // -// GitHub API docs: https://developer.github.com/v3/activity/watching/#get-a-repository-subscription +// GitHub API docs: https://docs.github.com/en/rest/reference/activity/#get-a-repository-subscription func (s *ActivityService) GetRepositorySubscription(ctx context.Context, owner, repo string) (*Subscription, *Response, error) { u := fmt.Sprintf("repos/%s/%s/subscription", owner, repo) @@ -111,7 +111,7 @@ func (s *ActivityService) GetRepositorySubscription(ctx context.Context, owner, // To ignore notifications made within a repository, set subscription.Ignored to true. // To stop watching a repository, use DeleteRepositorySubscription. // -// GitHub API docs: https://developer.github.com/v3/activity/watching/#set-a-repository-subscription +// GitHub API docs: https://docs.github.com/en/rest/reference/activity/#set-a-repository-subscription func (s *ActivityService) SetRepositorySubscription(ctx context.Context, owner, repo string, subscription *Subscription) (*Subscription, *Response, error) { u := fmt.Sprintf("repos/%s/%s/subscription", owner, repo) @@ -135,7 +135,7 @@ func (s *ActivityService) SetRepositorySubscription(ctx context.Context, owner, // This is used to stop watching a repository. To control whether or not to // receive notifications from a repository, use SetRepositorySubscription. // -// GitHub API docs: https://developer.github.com/v3/activity/watching/#delete-a-repository-subscription +// GitHub API docs: https://docs.github.com/en/rest/reference/activity/#delete-a-repository-subscription func (s *ActivityService) DeleteRepositorySubscription(ctx context.Context, owner, repo string) (*Response, error) { u := fmt.Sprintf("repos/%s/%s/subscription", owner, repo) req, err := s.client.NewRequest("DELETE", u, nil) diff --git a/github/admin.go b/github/admin.go index 31cd1fa2a48..50672eb5ae4 100644 --- a/github/admin.go +++ b/github/admin.go @@ -14,7 +14,7 @@ import ( // GitHub API. These API routes are normally only accessible for GitHub // Enterprise installations. // -// GitHub API docs: https://developer.github.com/v3/enterprise/ +// GitHub API docs: https://docs.github.com/en/rest/reference/enterprise/ type AdminService service // TeamLDAPMapping represents the mapping between a GitHub team and an LDAP group. @@ -82,7 +82,7 @@ func (m Enterprise) String() string { // UpdateUserLDAPMapping updates the mapping between a GitHub user and an LDAP user. // -// GitHub API docs: https://developer.github.com/v3/enterprise/ldap/#update-ldap-mapping-for-a-user +// GitHub API docs: https://docs.github.com/en/rest/reference/enterprise/ldap/#update-ldap-mapping-for-a-user func (s *AdminService) UpdateUserLDAPMapping(ctx context.Context, user string, mapping *UserLDAPMapping) (*UserLDAPMapping, *Response, error) { u := fmt.Sprintf("admin/ldap/users/%v/mapping", user) req, err := s.client.NewRequest("PATCH", u, mapping) @@ -101,7 +101,7 @@ func (s *AdminService) UpdateUserLDAPMapping(ctx context.Context, user string, m // UpdateTeamLDAPMapping updates the mapping between a GitHub team and an LDAP group. // -// GitHub API docs: https://developer.github.com/v3/enterprise/ldap/#update-ldap-mapping-for-a-team +// GitHub API docs: https://docs.github.com/en/rest/reference/enterprise/ldap/#update-ldap-mapping-for-a-team func (s *AdminService) UpdateTeamLDAPMapping(ctx context.Context, team int64, mapping *TeamLDAPMapping) (*TeamLDAPMapping, *Response, error) { u := fmt.Sprintf("admin/ldap/teams/%v/mapping", team) req, err := s.client.NewRequest("PATCH", u, mapping) diff --git a/github/admin_stats.go b/github/admin_stats.go index dabefde3e7b..5f347e41442 100644 --- a/github/admin_stats.go +++ b/github/admin_stats.go @@ -153,7 +153,7 @@ func (s RepoStats) String() string { // Please note that this is only available to site administrators, // otherwise it will error with a 404 not found (instead of 401 or 403). // -// GitHub API docs: https://developer.github.com/v3/enterprise-admin/admin_stats/ +// GitHub API docs: https://docs.github.com/en/rest/reference/enterprise-admin/admin_stats/ func (s *AdminService) GetAdminStats(ctx context.Context) (*AdminStats, *Response, error) { u := fmt.Sprintf("enterprise/stats/all") req, err := s.client.NewRequest("GET", u, nil) diff --git a/github/admin_users_test.go b/github/admin_users_test.go index 2c3b6d7ac2d..ed2ee05754a 100644 --- a/github/admin_users_test.go +++ b/github/admin_users_test.go @@ -68,7 +68,7 @@ func TestUserImpersonation_Create(t *testing.T) { "url": "https://git.company.com/api/v3/authorizations/1234", "app": { "name": "GitHub Site Administrator", - "url": "https://developer.github.com/v3/enterprise/users/", + "url": "https://docs.github.com/en/rest/reference/enterprise/users/", "client_id": "1234" }, "token": "1234", @@ -96,7 +96,7 @@ func TestUserImpersonation_Create(t *testing.T) { URL: String("https://git.company.com/api/v3/authorizations/1234"), App: &OAuthAPP{ Name: String("GitHub Site Administrator"), - URL: String("https://developer.github.com/v3/enterprise/users/"), + URL: String("https://docs.github.com/en/rest/reference/enterprise/users/"), ClientID: String("1234"), }, Token: String("1234"), diff --git a/github/apps.go b/github/apps.go index c50bb0daaef..c8d828fa5d9 100644 --- a/github/apps.go +++ b/github/apps.go @@ -14,7 +14,7 @@ import ( // AppsService provides access to the installation related functions // in the GitHub API. // -// GitHub API docs: https://developer.github.com/v3/apps/ +// GitHub API docs: https://docs.github.com/en/rest/reference/apps/ type AppsService service // App represents a GitHub App. @@ -55,7 +55,7 @@ type InstallationTokenOptions struct { // InstallationPermissions lists the repository and organization permissions for an installation. // // Permission names taken from: -// https://developer.github.com/v3/apps/permissions/ +// https://docs.github.com/en/rest/reference/apps/permissions/ // https://developer.github.com/enterprise/v3/apps/permissions/ type InstallationPermissions struct { Administration *string `json:"administration,omitempty"` @@ -130,8 +130,8 @@ func (i Installation) String() string { // You can find this on the settings page for your GitHub App // (e.g., https://github.com/settings/apps/:app_slug). // -// GitHub API docs: https://developer.github.com/v3/apps/#get-the-authenticated-app -// GitHub API docs: https://developer.github.com/v3/apps/#get-an-app +// GitHub API docs: https://docs.github.com/en/rest/reference/apps/#get-the-authenticated-app +// GitHub API docs: https://docs.github.com/en/rest/reference/apps/#get-an-app func (s *AppsService) Get(ctx context.Context, appSlug string) (*App, *Response, error) { var u string if appSlug != "" { @@ -159,7 +159,7 @@ func (s *AppsService) Get(ctx context.Context, appSlug string) (*App, *Response, // ListInstallations lists the installations that the current GitHub App has. // -// GitHub API docs: https://developer.github.com/v3/apps/#list-installations-for-the-authenticated-app +// GitHub API docs: https://docs.github.com/en/rest/reference/apps/#list-installations-for-the-authenticated-app func (s *AppsService) ListInstallations(ctx context.Context, opts *ListOptions) ([]*Installation, *Response, error) { u, err := addOptions("app/installations", opts) if err != nil { @@ -185,14 +185,14 @@ func (s *AppsService) ListInstallations(ctx context.Context, opts *ListOptions) // GetInstallation returns the specified installation. // -// GitHub API docs: https://developer.github.com/v3/apps/#get-an-installation-for-the-authenticated-app +// GitHub API docs: https://docs.github.com/en/rest/reference/apps/#get-an-installation-for-the-authenticated-app func (s *AppsService) GetInstallation(ctx context.Context, id int64) (*Installation, *Response, error) { return s.getInstallation(ctx, fmt.Sprintf("app/installations/%v", id)) } // ListUserInstallations lists installations that are accessible to the authenticated user. // -// GitHub API docs: https://developer.github.com/v3/apps/installations/#list-app-installations-accessible-to-the-user-access-token +// GitHub API docs: https://docs.github.com/en/rest/reference/apps/#list-app-installations-accessible-to-the-user-access-token func (s *AppsService) ListUserInstallations(ctx context.Context, opts *ListOptions) ([]*Installation, *Response, error) { u, err := addOptions("user/installations", opts) if err != nil { @@ -220,7 +220,7 @@ func (s *AppsService) ListUserInstallations(ctx context.Context, opts *ListOptio // SuspendInstallation suspends the specified installation. // -// GitHub API docs: https://developer.github.com/v3/apps/#suspend-an-app-installation +// GitHub API docs: https://docs.github.com/en/rest/reference/apps/#suspend-an-app-installation func (s *AppsService) SuspendInstallation(ctx context.Context, id int64) (*Response, error) { u := fmt.Sprintf("app/installations/%v/suspended", id) @@ -234,7 +234,7 @@ func (s *AppsService) SuspendInstallation(ctx context.Context, id int64) (*Respo // UnsuspendInstallation unsuspends the specified installation. // -// GitHub API docs: https://developer.github.com/v3/apps/#unsuspend-an-app-installation +// GitHub API docs: https://docs.github.com/en/rest/reference/apps/#unsuspend-an-app-installation func (s *AppsService) UnsuspendInstallation(ctx context.Context, id int64) (*Response, error) { u := fmt.Sprintf("app/installations/%v/suspended", id) @@ -248,7 +248,7 @@ func (s *AppsService) UnsuspendInstallation(ctx context.Context, id int64) (*Res // DeleteInstallation deletes the specified installation. // -// GitHub API docs: https://developer.github.com/v3/apps/#delete-an-installation-for-the-authenticated-app +// GitHub API docs: https://docs.github.com/en/rest/reference/apps/#delete-an-installation-for-the-authenticated-app func (s *AppsService) DeleteInstallation(ctx context.Context, id int64) (*Response, error) { u := fmt.Sprintf("app/installations/%v", id) @@ -265,7 +265,7 @@ func (s *AppsService) DeleteInstallation(ctx context.Context, id int64) (*Respon // CreateInstallationToken creates a new installation token. // -// GitHub API docs: https://developer.github.com/v3/apps/#create-an-installation-access-token-for-an-app +// GitHub API docs: https://docs.github.com/en/rest/reference/apps/#create-an-installation-access-token-for-an-app func (s *AppsService) CreateInstallationToken(ctx context.Context, id int64, opts *InstallationTokenOptions) (*InstallationToken, *Response, error) { u := fmt.Sprintf("app/installations/%v/access_tokens", id) @@ -288,7 +288,7 @@ func (s *AppsService) CreateInstallationToken(ctx context.Context, id int64, opt // CreateAttachment creates a new attachment on user comment containing a url. // -// GitHub API docs: https://developer.github.com/v3/apps/installations/#create-a-content-attachment +// GitHub API docs: https://docs.github.com/en/rest/reference/apps/#create-a-content-attachment func (s *AppsService) CreateAttachment(ctx context.Context, contentReferenceID int64, title, body string) (*Attachment, *Response, error) { u := fmt.Sprintf("content_references/%v/attachments", contentReferenceID) payload := &Attachment{Title: String(title), Body: String(body)} @@ -311,14 +311,14 @@ func (s *AppsService) CreateAttachment(ctx context.Context, contentReferenceID i // FindOrganizationInstallation finds the organization's installation information. // -// GitHub API docs: https://developer.github.com/v3/apps/#get-an-organization-installation-for-the-authenticated-app +// GitHub API docs: https://docs.github.com/en/rest/reference/apps/#get-an-organization-installation-for-the-authenticated-app func (s *AppsService) FindOrganizationInstallation(ctx context.Context, org string) (*Installation, *Response, error) { return s.getInstallation(ctx, fmt.Sprintf("orgs/%v/installation", org)) } // FindRepositoryInstallation finds the repository's installation information. // -// GitHub API docs: https://developer.github.com/v3/apps/#get-a-repository-installation-for-the-authenticated-app +// GitHub API docs: https://docs.github.com/en/rest/reference/apps/#get-a-repository-installation-for-the-authenticated-app func (s *AppsService) FindRepositoryInstallation(ctx context.Context, owner, repo string) (*Installation, *Response, error) { return s.getInstallation(ctx, fmt.Sprintf("repos/%v/%v/installation", owner, repo)) } @@ -332,7 +332,7 @@ func (s *AppsService) FindRepositoryInstallationByID(ctx context.Context, id int // FindUserInstallation finds the user's installation information. // -// GitHub API docs: https://developer.github.com/v3/apps/#get-a-user-installation-for-the-authenticated-app +// GitHub API docs: https://docs.github.com/en/rest/reference/apps/#get-a-user-installation-for-the-authenticated-app func (s *AppsService) FindUserInstallation(ctx context.Context, user string) (*Installation, *Response, error) { return s.getInstallation(ctx, fmt.Sprintf("users/%v/installation", user)) } diff --git a/github/apps_installation.go b/github/apps_installation.go index b6864e0381b..a2304cc9ce7 100644 --- a/github/apps_installation.go +++ b/github/apps_installation.go @@ -12,7 +12,7 @@ import ( // ListRepos lists the repositories that are accessible to the authenticated installation. // -// GitHub API docs: https://developer.github.com/v3/apps/installations/#list-repositories-accessible-to-the-app-installation +// GitHub API docs: https://docs.github.com/en/rest/reference/apps/#list-repositories-accessible-to-the-app-installation func (s *AppsService) ListRepos(ctx context.Context, opts *ListOptions) ([]*Repository, *Response, error) { u, err := addOptions("installation/repositories", opts) if err != nil { @@ -41,7 +41,7 @@ func (s *AppsService) ListRepos(ctx context.Context, opts *ListOptions) ([]*Repo // ListUserRepos lists repositories that are accessible // to the authenticated user for an installation. // -// GitHub API docs: https://developer.github.com/v3/apps/installations/#list-repositories-accessible-to-the-user-access-token +// GitHub API docs: https://docs.github.com/en/rest/reference/apps/#list-repositories-accessible-to-the-user-access-token func (s *AppsService) ListUserRepos(ctx context.Context, id int64, opts *ListOptions) ([]*Repository, *Response, error) { u := fmt.Sprintf("user/installations/%v/repositories", id) u, err := addOptions(u, opts) @@ -70,7 +70,7 @@ func (s *AppsService) ListUserRepos(ctx context.Context, id int64, opts *ListOpt // AddRepository adds a single repository to an installation. // -// GitHub API docs: https://developer.github.com/v3/apps/installations/#add-a-repository-to-an-app-installation +// GitHub API docs: https://docs.github.com/en/rest/reference/apps/#add-a-repository-to-an-app-installation func (s *AppsService) AddRepository(ctx context.Context, instID, repoID int64) (*Repository, *Response, error) { u := fmt.Sprintf("user/installations/%v/repositories/%v", instID, repoID) req, err := s.client.NewRequest("PUT", u, nil) @@ -90,7 +90,7 @@ func (s *AppsService) AddRepository(ctx context.Context, instID, repoID int64) ( // RemoveRepository removes a single repository from an installation. // -// GitHub API docs: https://developer.github.com/v3/apps/installations/#remove-a-repository-from-an-app-installation +// GitHub API docs: https://docs.github.com/en/rest/reference/apps/#remove-a-repository-from-an-app-installation func (s *AppsService) RemoveRepository(ctx context.Context, instID, repoID int64) (*Response, error) { u := fmt.Sprintf("user/installations/%v/repositories/%v", instID, repoID) req, err := s.client.NewRequest("DELETE", u, nil) @@ -104,7 +104,7 @@ func (s *AppsService) RemoveRepository(ctx context.Context, instID, repoID int64 // RevokeInstallationToken revokes an installation token. // -// GitHub API docs: https://developer.github.com/v3/apps/installations/#revoke-an-installation-access-token +// GitHub API docs: https://docs.github.com/en/rest/reference/apps/#revoke-an-installation-access-token func (s *AppsService) RevokeInstallationToken(ctx context.Context) (*Response, error) { u := "installation/token" req, err := s.client.NewRequest("DELETE", u, nil) diff --git a/github/apps_manifest.go b/github/apps_manifest.go index 9db76a30457..a0f6e8868dc 100644 --- a/github/apps_manifest.go +++ b/github/apps_manifest.go @@ -34,7 +34,7 @@ type AppConfig struct { // CompleteAppManifest completes the App manifest handshake flow for the given // code. // -// GitHub API docs: https://developer.github.com/v3/apps/#create-a-github-app-from-a-manifest +// GitHub API docs: https://docs.github.com/en/rest/reference/apps/#create-a-github-app-from-a-manifest func (s *AppsService) CompleteAppManifest(ctx context.Context, code string) (*AppConfig, *Response, error) { u := fmt.Sprintf("app-manifests/%s/conversions", code) req, err := s.client.NewRequest("POST", u, nil) diff --git a/github/apps_marketplace.go b/github/apps_marketplace.go index 9026633e7aa..e401cb56ecb 100644 --- a/github/apps_marketplace.go +++ b/github/apps_marketplace.go @@ -13,7 +13,7 @@ import ( // MarketplaceService handles communication with the marketplace related // methods of the GitHub API. // -// GitHub API docs: https://developer.github.com/v3/apps/marketplace/ +// GitHub API docs: https://docs.github.com/en/rest/reference/apps/marketplace/ type MarketplaceService struct { client *Client // Stubbed controls whether endpoints that return stubbed data are used @@ -21,7 +21,7 @@ type MarketplaceService struct { // for testing your GitHub Apps. Stubbed data is hard-coded and will not // change based on actual subscriptions. // - // GitHub API docs: https://developer.github.com/v3/apps/marketplace/ + // GitHub API docs: https://docs.github.com/en/rest/reference/apps/marketplace/ Stubbed bool } @@ -78,7 +78,7 @@ type MarketplacePlanAccount struct { // ListPlans lists all plans for your Marketplace listing. // -// GitHub API docs: https://developer.github.com/v3/apps/marketplace/#list-all-plans-for-your-marketplace-listing +// GitHub API docs: https://docs.github.com/en/rest/reference/apps/marketplace/#list-all-plans-for-your-marketplace-listing func (s *MarketplaceService) ListPlans(ctx context.Context, opts *ListOptions) ([]*MarketplacePlan, *Response, error) { uri := s.marketplaceURI("plans") u, err := addOptions(uri, opts) @@ -102,7 +102,7 @@ func (s *MarketplaceService) ListPlans(ctx context.Context, opts *ListOptions) ( // ListPlanAccountsForPlan lists all GitHub accounts (user or organization) on a specific plan. // -// GitHub API docs: https://developer.github.com/v3/apps/marketplace/#list-all-github-accounts-user-or-organization-on-a-specific-plan +// GitHub API docs: https://docs.github.com/en/rest/reference/apps/marketplace/#list-all-github-accounts-user-or-organization-on-a-specific-plan func (s *MarketplaceService) ListPlanAccountsForPlan(ctx context.Context, planID int64, opts *ListOptions) ([]*MarketplacePlanAccount, *Response, error) { uri := s.marketplaceURI(fmt.Sprintf("plans/%v/accounts", planID)) u, err := addOptions(uri, opts) @@ -126,7 +126,7 @@ func (s *MarketplaceService) ListPlanAccountsForPlan(ctx context.Context, planID // ListPlanAccountsForAccount lists all GitHub accounts (user or organization) associated with an account. // -// GitHub API docs: https://developer.github.com/v3/apps/marketplace/#check-if-a-github-account-is-associated-with-any-marketplace-listing +// GitHub API docs: https://docs.github.com/en/rest/reference/apps/marketplace/#check-if-a-github-account-is-associated-with-any-marketplace-listing func (s *MarketplaceService) ListPlanAccountsForAccount(ctx context.Context, accountID int64, opts *ListOptions) ([]*MarketplacePlanAccount, *Response, error) { uri := s.marketplaceURI(fmt.Sprintf("accounts/%v", accountID)) u, err := addOptions(uri, opts) @@ -150,8 +150,8 @@ func (s *MarketplaceService) ListPlanAccountsForAccount(ctx context.Context, acc // ListMarketplacePurchasesForUser lists all GitHub marketplace purchases made by a user. // -// GitHub API docs: https://developer.github.com/v3/apps/marketplace/#list-subscriptions-for-the-authenticated-user -// GitHub API docs: https://developer.github.com/v3/apps/marketplace/#list-subscriptions-for-the-authenticated-user-stubbed +// GitHub API docs: https://docs.github.com/en/rest/reference/apps/#list-subscriptions-for-the-authenticated-user-stubbed +// GitHub API docs: https://docs.github.com/en/rest/reference/apps/#list-subscriptions-for-the-authenticated-user func (s *MarketplaceService) ListMarketplacePurchasesForUser(ctx context.Context, opts *ListOptions) ([]*MarketplacePurchase, *Response, error) { uri := "user/marketplace_purchases" if s.Stubbed { diff --git a/github/authorizations.go b/github/authorizations.go index ad31ebf2082..2193f646279 100644 --- a/github/authorizations.go +++ b/github/authorizations.go @@ -12,7 +12,7 @@ import ( // Scope models a GitHub authorization scope. // -// GitHub API docs: https://developer.github.com/v3/oauth/#scopes +// GitHub API docs: https://docs.github.com/en/rest/reference/oauth/#scopes type Scope string // This is the set of scopes for GitHub API V3 @@ -50,7 +50,7 @@ const ( // This service requires HTTP Basic Authentication; it cannot be accessed using // an OAuth token. // -// GitHub API docs: https://developer.github.com/v3/oauth_authorizations/ +// GitHub API docs: https://docs.github.com/en/rest/reference/oauth_authorizations/ type AuthorizationsService service // Authorization represents an individual GitHub authorization. @@ -121,7 +121,7 @@ func (a AuthorizationRequest) String() string { // fields. That is, you may provide only one of "Scopes", or "AddScopes", or // "RemoveScopes". // -// GitHub API docs: https://developer.github.com/v3/oauth_authorizations/#update-an-existing-authorization +// GitHub API docs: https://docs.github.com/en/rest/reference/oauth_authorizations/#update-an-existing-authorization type AuthorizationUpdateRequest struct { Scopes []string `json:"scopes,omitempty"` AddScopes []string `json:"add_scopes,omitempty"` @@ -143,7 +143,7 @@ func (a AuthorizationUpdateRequest) String() string { // // The returned Authorization.User field will be populated. // -// GitHub API docs: https://developer.github.com/v3/apps/oauth_applications/#check-a-token +// GitHub API docs: https://docs.github.com/en/rest/reference/apps/#check-a-token func (s *AuthorizationsService) Check(ctx context.Context, clientID, accessToken string) (*Authorization, *Response, error) { u := fmt.Sprintf("applications/%v/token", clientID) @@ -176,7 +176,7 @@ func (s *AuthorizationsService) Check(ctx context.Context, clientID, accessToken // // The returned Authorization.User field will be populated. // -// GitHub API docs: https://developer.github.com/v3/apps/oauth_applications/#reset-a-token +// GitHub API docs: https://docs.github.com/en/rest/reference/apps/#reset-a-token func (s *AuthorizationsService) Reset(ctx context.Context, clientID, accessToken string) (*Authorization, *Response, error) { u := fmt.Sprintf("applications/%v/token", clientID) @@ -205,7 +205,7 @@ func (s *AuthorizationsService) Reset(ctx context.Context, clientID, accessToken // username is the OAuth application clientID, and the password is its // clientSecret. Invalid tokens will return a 404 Not Found. // -// GitHub API docs: https://developer.github.com/v3/apps/oauth_applications/#delete-an-app-token +// GitHub API docs: https://docs.github.com/en/rest/reference/apps/#delete-an-app-token func (s *AuthorizationsService) Revoke(ctx context.Context, clientID, accessToken string) (*Response, error) { u := fmt.Sprintf("applications/%v/token", clientID) @@ -226,7 +226,7 @@ func (s *AuthorizationsService) Revoke(ctx context.Context, clientID, accessToke // grant will also delete all OAuth tokens associated with the application for // the user. // -// GitHub API docs: https://developer.github.com/v3/apps/oauth_applications/#delete-an-app-authorization +// GitHub API docs: https://docs.github.com/en/rest/reference/apps/#delete-an-app-authorization func (s *AuthorizationsService) DeleteGrant(ctx context.Context, clientID, accessToken string) (*Response, error) { u := fmt.Sprintf("applications/%v/grant", clientID) diff --git a/github/checks.go b/github/checks.go index 55b69ab7e1d..3bdbc5c7e62 100644 --- a/github/checks.go +++ b/github/checks.go @@ -13,7 +13,7 @@ import ( // ChecksService provides access to the Checks API in the // GitHub API. // -// GitHub API docs: https://developer.github.com/v3/checks/ +// GitHub API docs: https://docs.github.com/en/rest/reference/checks/ type ChecksService service // CheckRun represents a GitHub check run on a repository associated with a GitHub app. @@ -96,7 +96,7 @@ func (c CheckSuite) String() string { // GetCheckRun gets a check-run for a repository. // -// GitHub API docs: https://developer.github.com/v3/checks/runs/#get-a-check-run +// GitHub API docs: https://docs.github.com/en/rest/reference/checks/#get-a-check-run func (s *ChecksService) GetCheckRun(ctx context.Context, owner, repo string, checkRunID int64) (*CheckRun, *Response, error) { u := fmt.Sprintf("repos/%v/%v/check-runs/%v", owner, repo, checkRunID) req, err := s.client.NewRequest("GET", u, nil) @@ -117,7 +117,7 @@ func (s *ChecksService) GetCheckRun(ctx context.Context, owner, repo string, che // GetCheckSuite gets a single check suite. // -// GitHub API docs: https://developer.github.com/v3/checks/suites/#get-a-check-suite +// GitHub API docs: https://docs.github.com/en/rest/reference/checks/#get-a-check-suite func (s *ChecksService) GetCheckSuite(ctx context.Context, owner, repo string, checkSuiteID int64) (*CheckSuite, *Response, error) { u := fmt.Sprintf("repos/%v/%v/check-suites/%v", owner, repo, checkSuiteID) req, err := s.client.NewRequest("GET", u, nil) @@ -159,7 +159,7 @@ type CheckRunAction struct { // CreateCheckRun creates a check run for repository. // -// GitHub API docs: https://developer.github.com/v3/checks/runs/#create-a-check-run +// GitHub API docs: https://docs.github.com/en/rest/reference/checks/#create-a-check-run func (s *ChecksService) CreateCheckRun(ctx context.Context, owner, repo string, opts CreateCheckRunOptions) (*CheckRun, *Response, error) { u := fmt.Sprintf("repos/%v/%v/check-runs", owner, repo) req, err := s.client.NewRequest("POST", u, opts) @@ -193,7 +193,7 @@ type UpdateCheckRunOptions struct { // UpdateCheckRun updates a check run for a specific commit in a repository. // -// GitHub API docs: https://developer.github.com/v3/checks/runs/#update-a-check-run +// GitHub API docs: https://docs.github.com/en/rest/reference/checks/#update-a-check-run func (s *ChecksService) UpdateCheckRun(ctx context.Context, owner, repo string, checkRunID int64, opts UpdateCheckRunOptions) (*CheckRun, *Response, error) { u := fmt.Sprintf("repos/%v/%v/check-runs/%v", owner, repo, checkRunID) req, err := s.client.NewRequest("PATCH", u, opts) @@ -214,7 +214,7 @@ func (s *ChecksService) UpdateCheckRun(ctx context.Context, owner, repo string, // ListCheckRunAnnotations lists the annotations for a check run. // -// GitHub API docs: https://developer.github.com/v3/checks/runs/#list-check-run-annotations +// GitHub API docs: https://docs.github.com/en/rest/reference/checks/#list-check-run-annotations func (s *ChecksService) ListCheckRunAnnotations(ctx context.Context, owner, repo string, checkRunID int64, opts *ListOptions) ([]*CheckRunAnnotation, *Response, error) { u := fmt.Sprintf("repos/%v/%v/check-runs/%v/annotations", owner, repo, checkRunID) u, err := addOptions(u, opts) @@ -255,7 +255,7 @@ type ListCheckRunsResults struct { // ListCheckRunsForRef lists check runs for a specific ref. // -// GitHub API docs: https://developer.github.com/v3/checks/runs/#list-check-runs-for-a-git-reference +// GitHub API docs: https://docs.github.com/en/rest/reference/checks/#list-check-runs-for-a-git-reference func (s *ChecksService) ListCheckRunsForRef(ctx context.Context, owner, repo, ref string, opts *ListCheckRunsOptions) (*ListCheckRunsResults, *Response, error) { u := fmt.Sprintf("repos/%v/%v/commits/%v/check-runs", owner, repo, refURLEscape(ref)) u, err := addOptions(u, opts) @@ -281,7 +281,7 @@ func (s *ChecksService) ListCheckRunsForRef(ctx context.Context, owner, repo, re // ListCheckRunsCheckSuite lists check runs for a check suite. // -// GitHub API docs: https://developer.github.com/v3/checks/runs/#list-check-runs-in-a-check-suite +// GitHub API docs: https://docs.github.com/en/rest/reference/checks/#list-check-runs-in-a-check-suite func (s *ChecksService) ListCheckRunsCheckSuite(ctx context.Context, owner, repo string, checkSuiteID int64, opts *ListCheckRunsOptions) (*ListCheckRunsResults, *Response, error) { u := fmt.Sprintf("repos/%v/%v/check-suites/%v/check-runs", owner, repo, checkSuiteID) u, err := addOptions(u, opts) @@ -321,7 +321,7 @@ type ListCheckSuiteResults struct { // ListCheckSuitesForRef lists check suite for a specific ref. // -// GitHub API docs: https://developer.github.com/v3/checks/suites/#list-check-suites-for-a-git-reference +// GitHub API docs: https://docs.github.com/en/rest/reference/checks/#list-check-suites-for-a-git-reference func (s *ChecksService) ListCheckSuitesForRef(ctx context.Context, owner, repo, ref string, opts *ListCheckSuiteOptions) (*ListCheckSuiteResults, *Response, error) { u := fmt.Sprintf("repos/%v/%v/commits/%v/check-suites", owner, repo, refURLEscape(ref)) u, err := addOptions(u, opts) @@ -369,7 +369,7 @@ type PreferenceList struct { // SetCheckSuitePreferences changes the default automatic flow when creating check suites. // -// GitHub API docs: https://developer.github.com/v3/checks/suites/#update-repository-preferences-for-check-suites +// GitHub API docs: https://docs.github.com/en/rest/reference/checks/#update-repository-preferences-for-check-suites func (s *ChecksService) SetCheckSuitePreferences(ctx context.Context, owner, repo string, opts CheckSuitePreferenceOptions) (*CheckSuitePreferenceResults, *Response, error) { u := fmt.Sprintf("repos/%v/%v/check-suites/preferences", owner, repo) req, err := s.client.NewRequest("PATCH", u, opts) @@ -396,7 +396,7 @@ type CreateCheckSuiteOptions struct { // CreateCheckSuite manually creates a check suite for a repository. // -// GitHub API docs: https://developer.github.com/v3/checks/suites/#create-a-check-suite +// GitHub API docs: https://docs.github.com/en/rest/reference/checks/#create-a-check-suite func (s *ChecksService) CreateCheckSuite(ctx context.Context, owner, repo string, opts CreateCheckSuiteOptions) (*CheckSuite, *Response, error) { u := fmt.Sprintf("repos/%v/%v/check-suites", owner, repo) req, err := s.client.NewRequest("POST", u, opts) @@ -417,7 +417,7 @@ func (s *ChecksService) CreateCheckSuite(ctx context.Context, owner, repo string // ReRequestCheckSuite triggers GitHub to rerequest an existing check suite, without pushing new code to a repository. // -// GitHub API docs: https://developer.github.com/v3/checks/suites/#rerequest-a-check-suite +// GitHub API docs: https://docs.github.com/en/rest/reference/checks/#rerequest-a-check-suite func (s *ChecksService) ReRequestCheckSuite(ctx context.Context, owner, repo string, checkSuiteID int64) (*Response, error) { u := fmt.Sprintf("repos/%v/%v/check-suites/%v/rerequest", owner, repo, checkSuiteID) diff --git a/github/code-scanning.go b/github/code-scanning.go index dc57a890250..34c047e5340 100644 --- a/github/code-scanning.go +++ b/github/code-scanning.go @@ -15,7 +15,7 @@ import ( // CodeScanningService handles communication with the code scanning related // methods of the GitHub API. // -// GitHub API docs: https://developer.github.com/v3/code-scanning/ +// GitHub API docs: https://docs.github.com/en/rest/reference/code-scanning/ type CodeScanningService service type Alert struct { @@ -69,7 +69,7 @@ type AlertListOptions struct { // You must use an access token with the security_events scope to use this endpoint. GitHub Apps must have the security_events // read permission to use this endpoint. // -// GitHub API docs: https://developer.github.com/v3/code-scanning/#list-code-scanning-alerts-for-a-repository +// GitHub API docs: https://docs.github.com/en/rest/reference/code-scanning/#list-code-scanning-alerts-for-a-repository func (s *CodeScanningService) ListAlertsForRepo(ctx context.Context, owner, repo string, opts *AlertListOptions) ([]*Alert, *Response, error) { u := fmt.Sprintf("repos/%v/%v/code-scanning/alerts", owner, repo) u, err := addOptions(u, opts) @@ -98,7 +98,7 @@ func (s *CodeScanningService) ListAlertsForRepo(ctx context.Context, owner, repo // // The security alert_id is the number at the end of the security alert's URL. // -// GitHub API docs: https://developer.github.com/v3/code-scanning/#get-a-code-scanning-alert +// GitHub API docs: https://docs.github.com/en/rest/reference/code-scanning/#get-a-code-scanning-alert func (s *CodeScanningService) GetAlert(ctx context.Context, owner, repo string, id int64) (*Alert, *Response, error) { u := fmt.Sprintf("repos/%v/%v/code-scanning/alerts/%v", owner, repo, id) diff --git a/github/doc.go b/github/doc.go index d1aa009a1af..614de9d3b67 100644 --- a/github/doc.go +++ b/github/doc.go @@ -29,7 +29,7 @@ Some API methods have optional parameters that can be passed. For example: The services of a client divide the API into logical chunks and correspond to the structure of the GitHub API documentation at -https://developer.github.com/v3/. +https://docs.github.com/en/rest/reference/. NOTE: Using the https://godoc.org/context package, one can easily pass cancelation signals and deadlines to various services of the client for @@ -112,7 +112,7 @@ To detect an API rate limit error, you can check if its type is *github.RateLimi } Learn more about GitHub rate limiting at -https://developer.github.com/v3/#rate-limiting. +https://docs.github.com/en/rest/reference/#rate-limiting. Accepted Status @@ -138,7 +138,7 @@ instead designed to work with a caching http.Transport. We recommend using https://github.com/gregjones/httpcache for that. Learn more about GitHub conditional requests at -https://developer.github.com/v3/#conditional-requests. +https://docs.github.com/en/rest/reference/#conditional-requests. Creating and Updating Resources diff --git a/github/event_types.go b/github/event_types.go index cdfd6e8831d..bf477113898 100644 --- a/github/event_types.go +++ b/github/event_types.go @@ -18,7 +18,7 @@ type RequestedAction struct { // CheckRunEvent is triggered when a check run is "created", "updated", or "rerequested". // The Webhook event name is "check_run". // -// GitHub API docs: https://developer.github.com/v3/activity/events/types/#checkrunevent +// GitHub API docs: https://docs.github.com/en/rest/reference/activity/events/types/#checkrunevent type CheckRunEvent struct { CheckRun *CheckRun `json:"check_run,omitempty"` // The action performed. Possible values are: "created", "updated", "rerequested" or "requested_action". @@ -37,7 +37,7 @@ type CheckRunEvent struct { // CheckSuiteEvent is triggered when a check suite is "completed", "requested", or "rerequested". // The Webhook event name is "check_suite". // -// GitHub API docs: https://developer.github.com/v3/activity/events/types/#checksuiteevent +// GitHub API docs: https://docs.github.com/en/rest/reference/activity/events/types/#checksuiteevent type CheckSuiteEvent struct { CheckSuite *CheckSuite `json:"check_suite,omitempty"` // The action performed. Possible values are: "completed", "requested" or "rerequested". @@ -53,7 +53,7 @@ type CheckSuiteEvent struct { // CommitCommentEvent is triggered when a commit comment is created. // The Webhook event name is "commit_comment". // -// GitHub API docs: https://developer.github.com/v3/activity/events/types/#commitcommentevent +// GitHub API docs: https://docs.github.com/en/rest/reference/activity/events/types/#commitcommentevent type CommitCommentEvent struct { Comment *RepositoryComment `json:"comment,omitempty"` @@ -85,7 +85,7 @@ type ContentReferenceEvent struct { // Additionally, webhooks will not receive this event for tags if more // than three tags are pushed at once. // -// GitHub API docs: https://developer.github.com/v3/activity/events/types/#createevent +// GitHub API docs: https://docs.github.com/en/rest/reference/activity/events/types/#createevent type CreateEvent struct { Ref *string `json:"ref,omitempty"` // RefType is the object that was created. Possible values are: "repository", "branch", "tag". @@ -106,7 +106,7 @@ type CreateEvent struct { // Note: webhooks will not receive this event for tags if more than three tags // are deleted at once. // -// GitHub API docs: https://developer.github.com/v3/activity/events/types/#deleteevent +// GitHub API docs: https://docs.github.com/en/rest/reference/activity/events/types/#deleteevent type DeleteEvent struct { Ref *string `json:"ref,omitempty"` // RefType is the object that was deleted. Possible values are: "branch", "tag". @@ -122,7 +122,7 @@ type DeleteEvent struct { // DeployKeyEvent is triggered when a deploy key is added or removed from a repository. // The Webhook event name is "deploy_key". // -// GitHub API docs: https://developer.github.com/v3/activity/events/types/#deploykeyevent +// GitHub API docs: https://docs.github.com/en/rest/reference/activity/events/types/#deploykeyevent type DeployKeyEvent struct { // Action is the action that was performed. Possible values are: // "created" or "deleted". @@ -137,7 +137,7 @@ type DeployKeyEvent struct { // // Events of this type are not visible in timelines, they are only used to trigger hooks. // -// GitHub API docs: https://developer.github.com/v3/activity/events/types/#deploymentevent +// GitHub API docs: https://docs.github.com/en/rest/reference/activity/events/types/#deploymentevent type DeploymentEvent struct { Deployment *Deployment `json:"deployment,omitempty"` Repo *Repository `json:"repository,omitempty"` @@ -152,7 +152,7 @@ type DeploymentEvent struct { // // Events of this type are not visible in timelines, they are only used to trigger hooks. // -// GitHub API docs: https://developer.github.com/v3/activity/events/types/#deploymentstatusevent +// GitHub API docs: https://docs.github.com/en/rest/reference/activity/events/types/#deploymentstatusevent type DeploymentStatusEvent struct { Deployment *Deployment `json:"deployment,omitempty"` DeploymentStatus *DeploymentStatus `json:"deployment_status,omitempty"` @@ -166,7 +166,7 @@ type DeploymentStatusEvent struct { // ForkEvent is triggered when a user forks a repository. // The Webhook event name is "fork". // -// GitHub API docs: https://developer.github.com/v3/activity/events/types/#forkevent +// GitHub API docs: https://docs.github.com/en/rest/reference/activity/events/types/#forkevent type ForkEvent struct { // Forkee is the created repository. Forkee *Repository `json:"forkee,omitempty"` @@ -180,7 +180,7 @@ type ForkEvent struct { // GitHubAppAuthorizationEvent is triggered when a user's authorization for a // GitHub Application is revoked. // -// GitHub API docs: https://developer.github.com/v3/activity/events/types/#githubappauthorizationevent +// GitHub API docs: https://docs.github.com/en/rest/reference/activity/events/types/#githubappauthorizationevent type GitHubAppAuthorizationEvent struct { // The action performed. Possible value is: "revoked". Action *string `json:"action,omitempty"` @@ -202,7 +202,7 @@ type Page struct { // GollumEvent is triggered when a Wiki page is created or updated. // The Webhook event name is "gollum". // -// GitHub API docs: https://developer.github.com/v3/activity/events/types/#gollumevent +// GitHub API docs: https://docs.github.com/en/rest/reference/activity/events/types/#gollumevent type GollumEvent struct { Pages []*Page `json:"pages,omitempty"` @@ -272,7 +272,7 @@ type TeamChange struct { // InstallationEvent is triggered when a GitHub App has been installed or uninstalled. // The Webhook event name is "installation". // -// GitHub API docs: https://developer.github.com/v3/activity/events/types/#installationevent +// GitHub API docs: https://docs.github.com/en/rest/reference/activity/events/types/#installationevent type InstallationEvent struct { // The action that was performed. Can be either "created" or "deleted". Action *string `json:"action,omitempty"` @@ -284,7 +284,7 @@ type InstallationEvent struct { // InstallationRepositoriesEvent is triggered when a repository is added or // removed from an installation. The Webhook event name is "installation_repositories". // -// GitHub API docs: https://developer.github.com/v3/activity/events/types/#installationrepositoriesevent +// GitHub API docs: https://docs.github.com/en/rest/reference/activity/events/types/#installationrepositoriesevent type InstallationRepositoriesEvent struct { // The action that was performed. Can be either "added" or "removed". Action *string `json:"action,omitempty"` @@ -299,7 +299,7 @@ type InstallationRepositoriesEvent struct { // or pull request. // The Webhook event name is "issue_comment". // -// GitHub API docs: https://developer.github.com/v3/activity/events/types/#issuecommentevent +// GitHub API docs: https://docs.github.com/en/rest/reference/activity/events/types/#issuecommentevent type IssueCommentEvent struct { // Action is the action that was performed on the comment. // Possible values are: "created", "edited", "deleted". @@ -319,7 +319,7 @@ type IssueCommentEvent struct { // locked, unlocked, milestoned, or demilestoned. // The Webhook event name is "issues". // -// GitHub API docs: https://developer.github.com/v3/activity/events/types/#issuesevent +// GitHub API docs: https://docs.github.com/en/rest/reference/activity/events/types/#issuesevent type IssuesEvent struct { // Action is the action that was performed. Possible values are: "opened", // "edited", "deleted", "transferred", "pinned", "unpinned", "closed", "reopened", @@ -340,7 +340,7 @@ type IssuesEvent struct { // LabelEvent is triggered when a repository's label is created, edited, or deleted. // The Webhook event name is "label" // -// GitHub API docs: https://developer.github.com/v3/activity/events/types/#labelevent +// GitHub API docs: https://docs.github.com/en/rest/reference/activity/events/types/#labelevent type LabelEvent struct { // Action is the action that was performed. Possible values are: // "created", "edited", "deleted" @@ -358,7 +358,7 @@ type LabelEvent struct { // their GitHub Marketplace plan. // Webhook event name "marketplace_purchase". // -// GitHub API docs: https://developer.github.com/v3/activity/events/types/#marketplacepurchaseevent +// GitHub API docs: https://docs.github.com/en/rest/reference/activity/events/types/#marketplacepurchaseevent type MarketplacePurchaseEvent struct { // Action is the action that was performed. Possible values are: // "purchased", "cancelled", "pending_change", "pending_change_cancelled", "changed". @@ -375,7 +375,7 @@ type MarketplacePurchaseEvent struct { // MemberEvent is triggered when a user is added as a collaborator to a repository. // The Webhook event name is "member". // -// GitHub API docs: https://developer.github.com/v3/activity/events/types/#memberevent +// GitHub API docs: https://docs.github.com/en/rest/reference/activity/events/types/#memberevent type MemberEvent struct { // Action is the action that was performed. Possible value is: "added". Action *string `json:"action,omitempty"` @@ -393,7 +393,7 @@ type MemberEvent struct { // Events of this type are not visible in timelines, they are only used to // trigger organization webhooks. // -// GitHub API docs: https://developer.github.com/v3/activity/events/types/#membershipevent +// GitHub API docs: https://docs.github.com/en/rest/reference/activity/events/types/#membershipevent type MembershipEvent struct { // Action is the action that was performed. Possible values are: "added", "removed". Action *string `json:"action,omitempty"` @@ -413,7 +413,7 @@ type MembershipEvent struct { // Therefore, it must be selected for each hook that you'd like to receive meta events for. // The Webhook event name is "meta". // -// GitHub API docs: https://developer.github.com/v3/activity/events/types/#metaevent +// GitHub API docs: https://docs.github.com/en/rest/reference/activity/events/types/#metaevent type MetaEvent struct { // Action is the action that was performed. Possible value is: "deleted". Action *string `json:"action,omitempty"` @@ -428,7 +428,7 @@ type MetaEvent struct { // MilestoneEvent is triggered when a milestone is created, closed, opened, edited, or deleted. // The Webhook event name is "milestone". // -// GitHub API docs: https://developer.github.com/v3/activity/events/types/#milestoneevent +// GitHub API docs: https://docs.github.com/en/rest/reference/activity/events/types/#milestoneevent type MilestoneEvent struct { // Action is the action that was performed. Possible values are: // "created", "closed", "opened", "edited", "deleted" @@ -448,7 +448,7 @@ type MilestoneEvent struct { // Events of this type are not visible in timelines. These events are only used to trigger organization hooks. // Webhook event name is "organization". // -// GitHub API docs: https://developer.github.com/v3/activity/events/types/#organizationevent +// GitHub API docs: https://docs.github.com/en/rest/reference/activity/events/types/#organizationevent type OrganizationEvent struct { // Action is the action that was performed. // Possible values are: "deleted", "renamed", "member_added", "member_removed", or "member_invited". @@ -469,7 +469,7 @@ type OrganizationEvent struct { // OrgBlockEvent is triggered when an organization blocks or unblocks a user. // The Webhook event name is "org_block". // -// GitHub API docs: https://developer.github.com/v3/activity/events/types/#orgblockevent +// GitHub API docs: https://docs.github.com/en/rest/reference/activity/events/types/#orgblockevent type OrgBlockEvent struct { // Action is the action that was performed. // Can be "blocked" or "unblocked". @@ -507,7 +507,7 @@ type PackageEvent struct { // // Events of this type are not visible in timelines, they are only used to trigger hooks. // -// GitHub API docs: https://developer.github.com/v3/activity/events/types/#pagebuildevent +// GitHub API docs: https://docs.github.com/en/rest/reference/activity/events/types/#pagebuildevent type PageBuildEvent struct { Build *PagesBuild `json:"build,omitempty"` @@ -534,7 +534,7 @@ type PingEvent struct { // ProjectEvent is triggered when project is created, modified or deleted. // The webhook event name is "project". // -// GitHub API docs: https://developer.github.com/v3/activity/events/types/#projectevent +// GitHub API docs: https://docs.github.com/en/rest/reference/activity/events/types/#projectevent type ProjectEvent struct { Action *string `json:"action,omitempty"` Changes *ProjectChange `json:"changes,omitempty"` @@ -550,7 +550,7 @@ type ProjectEvent struct { // ProjectCardEvent is triggered when a project card is created, updated, moved, converted to an issue, or deleted. // The webhook event name is "project_card". // -// GitHub API docs: https://developer.github.com/v3/activity/events/types/#projectcardevent +// GitHub API docs: https://docs.github.com/en/rest/reference/activity/events/types/#projectcardevent type ProjectCardEvent struct { Action *string `json:"action,omitempty"` Changes *ProjectCardChange `json:"changes,omitempty"` @@ -567,7 +567,7 @@ type ProjectCardEvent struct { // ProjectColumnEvent is triggered when a project column is created, updated, moved, or deleted. // The webhook event name is "project_column". // -// GitHub API docs: https://developer.github.com/v3/activity/events/types/#projectcolumnevent +// GitHub API docs: https://docs.github.com/en/rest/reference/activity/events/types/#projectcolumnevent type ProjectColumnEvent struct { Action *string `json:"action,omitempty"` Changes *ProjectColumnChange `json:"changes,omitempty"` @@ -585,7 +585,7 @@ type ProjectColumnEvent struct { // According to GitHub: "Without a doubt: the best GitHub event." // The Webhook event name is "public". // -// GitHub API docs: https://developer.github.com/v3/activity/events/types/#publicevent +// GitHub API docs: https://docs.github.com/en/rest/reference/activity/events/types/#publicevent type PublicEvent struct { // The following fields are only populated by Webhook events. Repo *Repository `json:"repository,omitempty"` @@ -598,7 +598,7 @@ type PublicEvent struct { // locked, unlocked, a pull request review is requested, or a review request is removed. // The Webhook event name is "pull_request". // -// GitHub API docs: https://developer.github.com/v3/activity/events/types/#pullrequestevent +// GitHub API docs: https://docs.github.com/en/rest/reference/activity/events/types/#pullrequestevent type PullRequestEvent struct { // Action is the action that was performed. Possible values are: // "assigned", "unassigned", "review_requested", "review_request_removed", "labeled", "unlabeled", @@ -639,7 +639,7 @@ type PullRequestEvent struct { // request. // The Webhook event name is "pull_request_review". // -// GitHub API docs: https://developer.github.com/v3/activity/events/types/#pullrequestreviewevent +// GitHub API docs: https://docs.github.com/en/rest/reference/activity/events/types/#pullrequestreviewevent type PullRequestReviewEvent struct { // Action is always "submitted". Action *string `json:"action,omitempty"` @@ -660,7 +660,7 @@ type PullRequestReviewEvent struct { // portion of the unified diff of a pull request. // The Webhook event name is "pull_request_review_comment". // -// GitHub API docs: https://developer.github.com/v3/activity/events/types/#pullrequestreviewcommentevent +// GitHub API docs: https://docs.github.com/en/rest/reference/activity/events/types/#pullrequestreviewcommentevent type PullRequestReviewCommentEvent struct { // Action is the action that was performed on the comment. // Possible values are: "created", "edited", "deleted". @@ -677,7 +677,7 @@ type PullRequestReviewCommentEvent struct { // PushEvent represents a git push to a GitHub repository. // -// GitHub API docs: https://developer.github.com/v3/activity/events/types/#pushevent +// GitHub API docs: https://docs.github.com/en/rest/reference/activity/events/types/#pushevent type PushEvent struct { PushID *int64 `json:"push_id,omitempty"` Head *string `json:"head,omitempty"` @@ -779,7 +779,7 @@ type PushEventRepoOwner struct { // edited, deleted, or prereleased. // The Webhook event name is "release". // -// GitHub API docs: https://developer.github.com/v3/activity/events/types/#releaseevent +// GitHub API docs: https://docs.github.com/en/rest/reference/activity/events/types/#releaseevent type ReleaseEvent struct { // Action is the action that was performed. Possible values are: "published", "unpublished", // "created", "edited", "deleted", or "prereleased". @@ -800,7 +800,7 @@ type ReleaseEvent struct { // Events of this type are not visible in timelines, they are only used to // trigger organization webhooks. // -// GitHub API docs: https://developer.github.com/v3/activity/events/types/#repositoryevent +// GitHub API docs: https://docs.github.com/en/rest/reference/activity/events/types/#repositoryevent type RepositoryEvent struct { // Action is the action that was performed. Possible values are: "created", // "deleted" (organization hooks only), "archived", "unarchived", "edited", "renamed", @@ -816,7 +816,7 @@ type RepositoryEvent struct { // RepositoryDispatchEvent is triggered when a client sends a POST request to the repository dispatch event endpoint. // -// GitHub API docs: https://developer.github.com/v3/activity/events/types/#repositorydispatchevent +// GitHub API docs: https://docs.github.com/en/rest/reference/activity/events/types/#repositorydispatchevent type RepositoryDispatchEvent struct { // Action is the event_type that submitted with the repository dispatch payload. Value can be any string. Action *string `json:"action,omitempty"` @@ -832,7 +832,7 @@ type RepositoryDispatchEvent struct { // RepositoryVulnerabilityAlertEvent is triggered when a security alert is created, dismissed, or resolved. // -// GitHub API docs: https://developer.github.com/v3/activity/events/types/#repositoryvulnerabilityalertevent +// GitHub API docs: https://docs.github.com/en/rest/reference/activity/events/types/#repositoryvulnerabilityalertevent type RepositoryVulnerabilityAlertEvent struct { // Action is the action that was performed. Possible values are: "create", "dismiss", "resolve". Action *string `json:"action,omitempty"` @@ -857,7 +857,7 @@ type RepositoryVulnerabilityAlertEvent struct { // StarEvent is triggered when a star is added or removed from a repository. // The Webhook event name is "star". // -// GitHub API docs: https://developer.github.com/v3/activity/events/types/#starevent +// GitHub API docs: https://docs.github.com/en/rest/reference/activity/events/types/#starevent type StarEvent struct { // Action is the action that was performed. Possible values are: "created" or "deleted". Action *string `json:"action,omitempty"` @@ -872,7 +872,7 @@ type StarEvent struct { // Events of this type are not visible in timelines, they are only used to // trigger hooks. // -// GitHub API docs: https://developer.github.com/v3/activity/events/types/#statusevent +// GitHub API docs: https://docs.github.com/en/rest/reference/activity/events/types/#statusevent type StatusEvent struct { SHA *string `json:"sha,omitempty"` // State is the new state. Possible values are: "pending", "success", "failure", "error". @@ -899,7 +899,7 @@ type StatusEvent struct { // Events of this type are not visible in timelines. These events are only used // to trigger hooks. // -// GitHub API docs: https://developer.github.com/v3/activity/events/types/#teamevent +// GitHub API docs: https://docs.github.com/en/rest/reference/activity/events/types/#teamevent type TeamEvent struct { Action *string `json:"action,omitempty"` Team *Team `json:"team,omitempty"` @@ -918,7 +918,7 @@ type TeamEvent struct { // Events of this type are not visible in timelines. These events are only used // to trigger hooks. // -// GitHub API docs: https://developer.github.com/v3/activity/events/types/#teamaddevent +// GitHub API docs: https://docs.github.com/en/rest/reference/activity/events/types/#teamaddevent type TeamAddEvent struct { Team *Team `json:"team,omitempty"` Repo *Repository `json:"repository,omitempty"` @@ -949,7 +949,7 @@ type UserEvent struct { // The event’s actor is the user who starred a repository, and the event’s // repository is the repository that was starred. // -// GitHub API docs: https://developer.github.com/v3/activity/events/types/#watchevent +// GitHub API docs: https://docs.github.com/en/rest/reference/activity/events/types/#watchevent type WatchEvent struct { // Action is the action that was performed. Possible value is: "started". Action *string `json:"action,omitempty"` diff --git a/github/gists.go b/github/gists.go index af6084f9c41..fb381c2594c 100644 --- a/github/gists.go +++ b/github/gists.go @@ -14,7 +14,7 @@ import ( // GistsService handles communication with the Gist related // methods of the GitHub API. // -// GitHub API docs: https://developer.github.com/v3/gists/ +// GitHub API docs: https://docs.github.com/en/rest/reference/gists/ type GistsService service // Gist represents a GitHub's gist. @@ -96,8 +96,8 @@ type GistListOptions struct { // is authenticated, it will returns all gists for the authenticated // user. // -// GitHub API docs: https://developer.github.com/v3/gists/#list-gists-for-a-user -// GitHub API docs: https://developer.github.com/v3/gists/#list-gists-for-the-authenticated-user +// GitHub API docs: https://docs.github.com/en/rest/reference/gists/#list-gists-for-the-authenticated-user +// GitHub API docs: https://docs.github.com/en/rest/reference/gists/#list-gists-for-a-user func (s *GistsService) List(ctx context.Context, user string, opts *GistListOptions) ([]*Gist, *Response, error) { var u string if user != "" { @@ -126,7 +126,7 @@ func (s *GistsService) List(ctx context.Context, user string, opts *GistListOpti // ListAll lists all public gists. // -// GitHub API docs: https://developer.github.com/v3/gists/#list-public-gists +// GitHub API docs: https://docs.github.com/en/rest/reference/gists/#list-public-gists func (s *GistsService) ListAll(ctx context.Context, opts *GistListOptions) ([]*Gist, *Response, error) { u, err := addOptions("gists/public", opts) if err != nil { @@ -149,7 +149,7 @@ func (s *GistsService) ListAll(ctx context.Context, opts *GistListOptions) ([]*G // ListStarred lists starred gists of authenticated user. // -// GitHub API docs: https://developer.github.com/v3/gists/#list-starred-gists +// GitHub API docs: https://docs.github.com/en/rest/reference/gists/#list-starred-gists func (s *GistsService) ListStarred(ctx context.Context, opts *GistListOptions) ([]*Gist, *Response, error) { u, err := addOptions("gists/starred", opts) if err != nil { @@ -172,7 +172,7 @@ func (s *GistsService) ListStarred(ctx context.Context, opts *GistListOptions) ( // Get a single gist. // -// GitHub API docs: https://developer.github.com/v3/gists/#get-a-gist +// GitHub API docs: https://docs.github.com/en/rest/reference/gists/#get-a-gist func (s *GistsService) Get(ctx context.Context, id string) (*Gist, *Response, error) { u := fmt.Sprintf("gists/%v", id) req, err := s.client.NewRequest("GET", u, nil) @@ -191,7 +191,7 @@ func (s *GistsService) Get(ctx context.Context, id string) (*Gist, *Response, er // GetRevision gets a specific revision of a gist. // -// GitHub API docs: https://developer.github.com/v3/gists/#get-a-gist-revision +// GitHub API docs: https://docs.github.com/en/rest/reference/gists/#get-a-gist-revision func (s *GistsService) GetRevision(ctx context.Context, id, sha string) (*Gist, *Response, error) { u := fmt.Sprintf("gists/%v/%v", id, sha) req, err := s.client.NewRequest("GET", u, nil) @@ -210,7 +210,7 @@ func (s *GistsService) GetRevision(ctx context.Context, id, sha string) (*Gist, // Create a gist for authenticated user. // -// GitHub API docs: https://developer.github.com/v3/gists/#create-a-gist +// GitHub API docs: https://docs.github.com/en/rest/reference/gists/#create-a-gist func (s *GistsService) Create(ctx context.Context, gist *Gist) (*Gist, *Response, error) { u := "gists" req, err := s.client.NewRequest("POST", u, gist) @@ -229,7 +229,7 @@ func (s *GistsService) Create(ctx context.Context, gist *Gist) (*Gist, *Response // Edit a gist. // -// GitHub API docs: https://developer.github.com/v3/gists/#update-a-gist +// GitHub API docs: https://docs.github.com/en/rest/reference/gists/#update-a-gist func (s *GistsService) Edit(ctx context.Context, id string, gist *Gist) (*Gist, *Response, error) { u := fmt.Sprintf("gists/%v", id) req, err := s.client.NewRequest("PATCH", u, gist) @@ -248,7 +248,7 @@ func (s *GistsService) Edit(ctx context.Context, id string, gist *Gist) (*Gist, // ListCommits lists commits of a gist. // -// GitHub API docs: https://developer.github.com/v3/gists/#list-gist-commits +// GitHub API docs: https://docs.github.com/en/rest/reference/gists/#list-gist-commits func (s *GistsService) ListCommits(ctx context.Context, id string, opts *ListOptions) ([]*GistCommit, *Response, error) { u := fmt.Sprintf("gists/%v/commits", id) u, err := addOptions(u, opts) @@ -272,7 +272,7 @@ func (s *GistsService) ListCommits(ctx context.Context, id string, opts *ListOpt // Delete a gist. // -// GitHub API docs: https://developer.github.com/v3/gists/#delete-a-gist +// GitHub API docs: https://docs.github.com/en/rest/reference/gists/#delete-a-gist func (s *GistsService) Delete(ctx context.Context, id string) (*Response, error) { u := fmt.Sprintf("gists/%v", id) req, err := s.client.NewRequest("DELETE", u, nil) @@ -284,7 +284,7 @@ func (s *GistsService) Delete(ctx context.Context, id string) (*Response, error) // Star a gist on behalf of authenticated user. // -// GitHub API docs: https://developer.github.com/v3/gists/#star-a-gist +// GitHub API docs: https://docs.github.com/en/rest/reference/gists/#star-a-gist func (s *GistsService) Star(ctx context.Context, id string) (*Response, error) { u := fmt.Sprintf("gists/%v/star", id) req, err := s.client.NewRequest("PUT", u, nil) @@ -296,7 +296,7 @@ func (s *GistsService) Star(ctx context.Context, id string) (*Response, error) { // Unstar a gist on a behalf of authenticated user. // -// GitHub API docs: https://developer.github.com/v3/gists/#unstar-a-gist +// GitHub API docs: https://docs.github.com/en/rest/reference/gists/#unstar-a-gist func (s *GistsService) Unstar(ctx context.Context, id string) (*Response, error) { u := fmt.Sprintf("gists/%v/star", id) req, err := s.client.NewRequest("DELETE", u, nil) @@ -308,7 +308,7 @@ func (s *GistsService) Unstar(ctx context.Context, id string) (*Response, error) // IsStarred checks if a gist is starred by authenticated user. // -// GitHub API docs: https://developer.github.com/v3/gists/#check-if-a-gist-is-starred +// GitHub API docs: https://docs.github.com/en/rest/reference/gists/#check-if-a-gist-is-starred func (s *GistsService) IsStarred(ctx context.Context, id string) (bool, *Response, error) { u := fmt.Sprintf("gists/%v/star", id) req, err := s.client.NewRequest("GET", u, nil) @@ -322,7 +322,7 @@ func (s *GistsService) IsStarred(ctx context.Context, id string) (bool, *Respons // Fork a gist. // -// GitHub API docs: https://developer.github.com/v3/gists/#fork-a-gist +// GitHub API docs: https://docs.github.com/en/rest/reference/gists/#fork-a-gist func (s *GistsService) Fork(ctx context.Context, id string) (*Gist, *Response, error) { u := fmt.Sprintf("gists/%v/forks", id) req, err := s.client.NewRequest("POST", u, nil) @@ -341,7 +341,7 @@ func (s *GistsService) Fork(ctx context.Context, id string) (*Gist, *Response, e // ListForks lists forks of a gist. // -// GitHub API docs: https://developer.github.com/v3/gists/#list-gist-forks +// GitHub API docs: https://docs.github.com/en/rest/reference/gists/#list-gist-forks func (s *GistsService) ListForks(ctx context.Context, id string, opts *ListOptions) ([]*GistFork, *Response, error) { u := fmt.Sprintf("gists/%v/forks", id) u, err := addOptions(u, opts) diff --git a/github/gists_comments.go b/github/gists_comments.go index 35406a9c3eb..cd3d5631776 100644 --- a/github/gists_comments.go +++ b/github/gists_comments.go @@ -26,7 +26,7 @@ func (g GistComment) String() string { // ListComments lists all comments for a gist. // -// GitHub API docs: https://developer.github.com/v3/gists/comments/#list-gist-comments +// GitHub API docs: https://docs.github.com/en/rest/reference/gists/#list-gist-comments func (s *GistsService) ListComments(ctx context.Context, gistID string, opts *ListOptions) ([]*GistComment, *Response, error) { u := fmt.Sprintf("gists/%v/comments", gistID) u, err := addOptions(u, opts) @@ -50,7 +50,7 @@ func (s *GistsService) ListComments(ctx context.Context, gistID string, opts *Li // GetComment retrieves a single comment from a gist. // -// GitHub API docs: https://developer.github.com/v3/gists/comments/#get-a-gist-comment +// GitHub API docs: https://docs.github.com/en/rest/reference/gists/#get-a-gist-comment func (s *GistsService) GetComment(ctx context.Context, gistID string, commentID int64) (*GistComment, *Response, error) { u := fmt.Sprintf("gists/%v/comments/%v", gistID, commentID) req, err := s.client.NewRequest("GET", u, nil) @@ -69,7 +69,7 @@ func (s *GistsService) GetComment(ctx context.Context, gistID string, commentID // CreateComment creates a comment for a gist. // -// GitHub API docs: https://developer.github.com/v3/gists/comments/#create-a-gist-comment +// GitHub API docs: https://docs.github.com/en/rest/reference/gists/#create-a-gist-comment func (s *GistsService) CreateComment(ctx context.Context, gistID string, comment *GistComment) (*GistComment, *Response, error) { u := fmt.Sprintf("gists/%v/comments", gistID) req, err := s.client.NewRequest("POST", u, comment) @@ -88,7 +88,7 @@ func (s *GistsService) CreateComment(ctx context.Context, gistID string, comment // EditComment edits an existing gist comment. // -// GitHub API docs: https://developer.github.com/v3/gists/comments/#update-a-gist-comment +// GitHub API docs: https://docs.github.com/en/rest/reference/gists/#update-a-gist-comment func (s *GistsService) EditComment(ctx context.Context, gistID string, commentID int64, comment *GistComment) (*GistComment, *Response, error) { u := fmt.Sprintf("gists/%v/comments/%v", gistID, commentID) req, err := s.client.NewRequest("PATCH", u, comment) @@ -107,7 +107,7 @@ func (s *GistsService) EditComment(ctx context.Context, gistID string, commentID // DeleteComment deletes a gist comment. // -// GitHub API docs: https://developer.github.com/v3/gists/comments/#delete-a-gist-comment +// GitHub API docs: https://docs.github.com/en/rest/reference/gists/#delete-a-gist-comment func (s *GistsService) DeleteComment(ctx context.Context, gistID string, commentID int64) (*Response, error) { u := fmt.Sprintf("gists/%v/comments/%v", gistID, commentID) req, err := s.client.NewRequest("DELETE", u, nil) diff --git a/github/git.go b/github/git.go index 1ce47437bd3..e4b0671f966 100644 --- a/github/git.go +++ b/github/git.go @@ -8,5 +8,5 @@ package github // GitService handles communication with the git data related // methods of the GitHub API. // -// GitHub API docs: https://developer.github.com/v3/git/ +// GitHub API docs: https://docs.github.com/en/rest/reference/git/ type GitService service diff --git a/github/git_blobs.go b/github/git_blobs.go index 70aee14a7ae..60c33734fb5 100644 --- a/github/git_blobs.go +++ b/github/git_blobs.go @@ -23,7 +23,7 @@ type Blob struct { // GetBlob fetches a blob from a repo given a SHA. // -// GitHub API docs: https://developer.github.com/v3/git/blobs/#get-a-blob +// GitHub API docs: https://docs.github.com/en/rest/reference/git/#get-a-blob func (s *GitService) GetBlob(ctx context.Context, owner string, repo string, sha string) (*Blob, *Response, error) { u := fmt.Sprintf("repos/%v/%v/git/blobs/%v", owner, repo, sha) req, err := s.client.NewRequest("GET", u, nil) @@ -39,7 +39,7 @@ func (s *GitService) GetBlob(ctx context.Context, owner string, repo string, sha // GetBlobRaw fetches a blob's contents from a repo. // Unlike GetBlob, it returns the raw bytes rather than the base64-encoded data. // -// GitHub API docs: https://developer.github.com/v3/git/blobs/#get-a-blob +// GitHub API docs: https://docs.github.com/en/rest/reference/git/#get-a-blob func (s *GitService) GetBlobRaw(ctx context.Context, owner, repo, sha string) ([]byte, *Response, error) { u := fmt.Sprintf("repos/%v/%v/git/blobs/%v", owner, repo, sha) req, err := s.client.NewRequest("GET", u, nil) @@ -55,7 +55,7 @@ func (s *GitService) GetBlobRaw(ctx context.Context, owner, repo, sha string) ([ // CreateBlob creates a blob object. // -// GitHub API docs: https://developer.github.com/v3/git/blobs/#create-a-blob +// GitHub API docs: https://docs.github.com/en/rest/reference/git/#create-a-blob func (s *GitService) CreateBlob(ctx context.Context, owner string, repo string, blob *Blob) (*Blob, *Response, error) { u := fmt.Sprintf("repos/%v/%v/git/blobs", owner, repo) req, err := s.client.NewRequest("POST", u, blob) diff --git a/github/git_commits.go b/github/git_commits.go index e1dba1cf5d1..492369d2997 100644 --- a/github/git_commits.go +++ b/github/git_commits.go @@ -70,7 +70,7 @@ func (c CommitAuthor) String() string { // GetCommit fetches the Commit object for a given SHA. // -// GitHub API docs: https://developer.github.com/v3/git/commits/#get-a-commit +// GitHub API docs: https://docs.github.com/en/rest/reference/git/#get-a-commit func (s *GitService) GetCommit(ctx context.Context, owner string, repo string, sha string) (*Commit, *Response, error) { u := fmt.Sprintf("repos/%v/%v/git/commits/%v", owner, repo, sha) req, err := s.client.NewRequest("GET", u, nil) @@ -104,7 +104,7 @@ type createCommit struct { // data if omitted. If the commit.Author is omitted, it will be filled in with // the authenticated user’s information and the current date. // -// GitHub API docs: https://developer.github.com/v3/git/commits/#create-a-commit +// GitHub API docs: https://docs.github.com/en/rest/reference/git/#create-a-commit func (s *GitService) CreateCommit(ctx context.Context, owner string, repo string, commit *Commit) (*Commit, *Response, error) { if commit == nil { return nil, nil, fmt.Errorf("commit must be provided") diff --git a/github/git_refs.go b/github/git_refs.go index ef1d0264165..1c01bf69b69 100644 --- a/github/git_refs.go +++ b/github/git_refs.go @@ -49,7 +49,7 @@ type updateRefRequest struct { // GetRef fetches a single reference in a repository. // -// GitHub API docs: https://developer.github.com/v3/git/refs/#get-a-reference +// GitHub API docs: https://docs.github.com/en/rest/reference/git/#get-a-reference func (s *GitService) GetRef(ctx context.Context, owner string, repo string, ref string) (*Reference, *Response, error) { ref = strings.TrimPrefix(ref, "refs/") u := fmt.Sprintf("repos/%v/%v/git/ref/%v", owner, repo, refURLEscape(ref)) @@ -88,7 +88,7 @@ type ReferenceListOptions struct { // ListMatchingRefs lists references in a repository that match a supplied ref. // Use an empty ref to list all references. // -// GitHub API docs: https://developer.github.com/v3/git/refs/#list-matching-references +// GitHub API docs: https://docs.github.com/en/rest/reference/git/#list-matching-references func (s *GitService) ListMatchingRefs(ctx context.Context, owner, repo string, opts *ReferenceListOptions) ([]*Reference, *Response, error) { var ref string if opts != nil { @@ -116,7 +116,7 @@ func (s *GitService) ListMatchingRefs(ctx context.Context, owner, repo string, o // CreateRef creates a new ref in a repository. // -// GitHub API docs: https://developer.github.com/v3/git/refs/#create-a-reference +// GitHub API docs: https://docs.github.com/en/rest/reference/git/#create-a-reference func (s *GitService) CreateRef(ctx context.Context, owner string, repo string, ref *Reference) (*Reference, *Response, error) { u := fmt.Sprintf("repos/%v/%v/git/refs", owner, repo) req, err := s.client.NewRequest("POST", u, &createRefRequest{ @@ -139,7 +139,7 @@ func (s *GitService) CreateRef(ctx context.Context, owner string, repo string, r // UpdateRef updates an existing ref in a repository. // -// GitHub API docs: https://developer.github.com/v3/git/refs/#update-a-reference +// GitHub API docs: https://docs.github.com/en/rest/reference/git/#update-a-reference func (s *GitService) UpdateRef(ctx context.Context, owner string, repo string, ref *Reference, force bool) (*Reference, *Response, error) { refPath := strings.TrimPrefix(*ref.Ref, "refs/") u := fmt.Sprintf("repos/%v/%v/git/refs/%v", owner, repo, refPath) @@ -162,7 +162,7 @@ func (s *GitService) UpdateRef(ctx context.Context, owner string, repo string, r // DeleteRef deletes a ref from a repository. // -// GitHub API docs: https://developer.github.com/v3/git/refs/#delete-a-reference +// GitHub API docs: https://docs.github.com/en/rest/reference/git/#delete-a-reference func (s *GitService) DeleteRef(ctx context.Context, owner string, repo string, ref string) (*Response, error) { ref = strings.TrimPrefix(ref, "refs/") u := fmt.Sprintf("repos/%v/%v/git/refs/%v", owner, repo, refURLEscape(ref)) diff --git a/github/git_tags.go b/github/git_tags.go index abdbde6821b..57d9160083e 100644 --- a/github/git_tags.go +++ b/github/git_tags.go @@ -35,7 +35,7 @@ type createTagRequest struct { // GetTag fetches a tag from a repo given a SHA. // -// GitHub API docs: https://developer.github.com/v3/git/tags/#get-a-tag +// GitHub API docs: https://docs.github.com/en/rest/reference/git/#get-a-tag func (s *GitService) GetTag(ctx context.Context, owner string, repo string, sha string) (*Tag, *Response, error) { u := fmt.Sprintf("repos/%v/%v/git/tags/%v", owner, repo, sha) req, err := s.client.NewRequest("GET", u, nil) @@ -50,7 +50,7 @@ func (s *GitService) GetTag(ctx context.Context, owner string, repo string, sha // CreateTag creates a tag object. // -// GitHub API docs: https://developer.github.com/v3/git/tags/#create-a-tag-object +// GitHub API docs: https://docs.github.com/en/rest/reference/git/#create-a-tag-object func (s *GitService) CreateTag(ctx context.Context, owner string, repo string, tag *Tag) (*Tag, *Response, error) { u := fmt.Sprintf("repos/%v/%v/git/tags", owner, repo) diff --git a/github/git_trees.go b/github/git_trees.go index 7430876ad94..b9853548305 100644 --- a/github/git_trees.go +++ b/github/git_trees.go @@ -93,7 +93,7 @@ func (t *TreeEntry) MarshalJSON() ([]byte, error) { // GetTree fetches the Tree object for a given sha hash from a repository. // -// GitHub API docs: https://developer.github.com/v3/git/trees/#get-a-tree +// GitHub API docs: https://docs.github.com/en/rest/reference/git/#get-a-tree func (s *GitService) GetTree(ctx context.Context, owner string, repo string, sha string, recursive bool) (*Tree, *Response, error) { u := fmt.Sprintf("repos/%v/%v/git/trees/%v", owner, repo, sha) if recursive { @@ -124,7 +124,7 @@ type createTree struct { // path modifying that tree are specified, it will overwrite the contents of // that tree with the new path contents and write a new tree out. // -// GitHub API docs: https://developer.github.com/v3/git/trees/#create-a-tree +// GitHub API docs: https://docs.github.com/en/rest/reference/git/#create-a-tree func (s *GitService) CreateTree(ctx context.Context, owner string, repo string, baseTree string, entries []*TreeEntry) (*Tree, *Response, error) { u := fmt.Sprintf("repos/%v/%v/git/trees", owner, repo) diff --git a/github/github.go b/github/github.go index c739de925f3..7cdbf5db255 100644 --- a/github/github.go +++ b/github/github.go @@ -122,10 +122,10 @@ const ( // https://developer.github.com/changes/2019-04-11-pulls-branches-for-commit/ mediaTypeListPullsOrBranchesForCommitPreview = "application/vnd.github.groot-preview+json" - // https://developer.github.com/v3/previews/#repository-creation-permissions + // https://docs.github.com/en/rest/reference/previews/#repository-creation-permissions mediaTypeMemberAllowedRepoCreationTypePreview = "application/vnd.github.surtur-preview+json" - // https://developer.github.com/v3/previews/#create-and-use-repository-templates + // https://docs.github.com/en/rest/reference/previews/#create-and-use-repository-templates mediaTypeRepositoryTemplatePreview = "application/vnd.github.baptiste-preview+json" // https://developer.github.com/changes/2019-10-03-multi-line-comments/ @@ -654,7 +654,7 @@ func (c *Client) checkRateLimitBeforeDo(req *http.Request, rateLimitCategory rat /* An ErrorResponse reports one or more errors caused by an API request. -GitHub API docs: https://developer.github.com/v3/#client-errors +GitHub API docs: https://docs.github.com/en/rest/reference/#client-errors */ type ErrorResponse struct { Response *http.Response // HTTP response that caused this error @@ -669,7 +669,7 @@ type ErrorResponse struct { } `json:"block,omitempty"` // Most errors will also include a documentation_url field pointing // to some content that might help you resolve the error, see - // https://developer.github.com/v3/#client-errors + // https://docs.github.com/en/rest/reference/#client-errors DocumentationURL string `json:"documentation_url,omitempty"` } @@ -716,7 +716,7 @@ func (*AcceptedError) Error() string { } // AbuseRateLimitError occurs when GitHub returns 403 Forbidden response with the -// "documentation_url" field value equal to "https://developer.github.com/v3/#abuse-rate-limits". +// "documentation_url" field value equal to "https://docs.github.com/en/rest/reference/#abuse-rate-limits". type AbuseRateLimitError struct { Response *http.Response // HTTP response that caused this error Message string `json:"message"` // error message @@ -767,7 +767,7 @@ GitHub error responses structure are often undocumented and inconsistent. Sometimes error is just a simple string (Issue #540). In such cases, Message represents an error message as a workaround. -GitHub API docs: https://developer.github.com/v3/#client-errors +GitHub API docs: https://docs.github.com/en/rest/reference/#client-errors */ type Error struct { Resource string `json:"resource"` // resource on which the error occurred @@ -823,7 +823,7 @@ func CheckResponse(r *http.Response) error { Response: errorResponse.Response, Message: errorResponse.Message, } - case r.StatusCode == http.StatusForbidden && strings.HasSuffix(errorResponse.DocumentationURL, "/v3/#abuse-rate-limits"): + case r.StatusCode == http.StatusForbidden && strings.HasSuffix(errorResponse.DocumentationURL, "#abuse-rate-limits"): abuseRateLimitError := &AbuseRateLimitError{ Response: errorResponse.Response, Message: errorResponse.Message, @@ -883,14 +883,14 @@ type RateLimits struct { // requests are limited to 60 per hour. Authenticated requests are // limited to 5,000 per hour. // - // GitHub API docs: https://developer.github.com/v3/#rate-limiting + // GitHub API docs: https://docs.github.com/en/rest/reference/#rate-limiting Core *Rate `json:"core"` // The rate limit for search API requests. Unauthenticated requests // are limited to 10 requests per minutes. Authenticated requests are // limited to 30 per minute. // - // GitHub API docs: https://developer.github.com/v3/search/#rate-limit + // GitHub API docs: https://docs.github.com/en/rest/reference/search/#rate-limit Search *Rate `json:"search"` } @@ -977,7 +977,7 @@ that need to use a higher rate limit associated with your OAuth application. This will add the client id and secret as a base64-encoded string in the format ClientID:ClientSecret and apply it as an "Authorization": "Basic" header. -See https://developer.github.com/v3/#unauthenticated-rate-limited-requests for +See https://docs.github.com/en/rest/reference/#unauthenticated-rate-limited-requests for more information. */ type UnauthenticatedRateLimitedTransport struct { diff --git a/github/github_test.go b/github/github_test.go index d86ec206cb0..78edb25b353 100644 --- a/github/github_test.go +++ b/github/github_test.go @@ -770,7 +770,7 @@ func TestDo_rateLimit_rateLimitError(t *testing.T) { w.WriteHeader(http.StatusForbidden) fmt.Fprintln(w, `{ "message": "API rate limit exceeded for xxx.xxx.xxx.xxx. (But here's the good news: Authenticated requests get a higher rate limit. Check out the documentation for more details.)", - "documentation_url": "https://developer.github.com/v3/#rate-limiting" + "documentation_url": "https://docs.github.com/en/rest/overview/resources-in-the-rest-api#abuse-rate-limits" }`) }) @@ -811,7 +811,7 @@ func TestDo_rateLimit_noNetworkCall(t *testing.T) { w.WriteHeader(http.StatusForbidden) fmt.Fprintln(w, `{ "message": "API rate limit exceeded for xxx.xxx.xxx.xxx. (But here's the good news: Authenticated requests get a higher rate limit. Check out the documentation for more details.)", - "documentation_url": "https://developer.github.com/v3/#rate-limiting" + "documentation_url": "https://docs.github.com/en/rest/overview/resources-in-the-rest-api#abuse-rate-limits" }`) }) @@ -863,7 +863,7 @@ func TestDo_rateLimit_abuseRateLimitError(t *testing.T) { // there is no "Retry-After" header. fmt.Fprintln(w, `{ "message": "You have triggered an abuse detection mechanism and have been temporarily blocked from content creation. Please retry your request again later.", - "documentation_url": "https://developer.github.com/v3/#abuse-rate-limits" + "documentation_url": "https://docs.github.com/en/rest/overview/resources-in-the-rest-api#abuse-rate-limits" }`) }) @@ -897,7 +897,7 @@ func TestDo_rateLimit_abuseRateLimitErrorEnterprise(t *testing.T) { // url changes between versions but follows roughly the same format. fmt.Fprintln(w, `{ "message": "You have triggered an abuse detection mechanism and have been temporarily blocked from content creation. Please retry your request again later.", - "documentation_url": "https://developer.github.com/enterprise/2.12/v3/#abuse-rate-limits" + "documentation_url": "https://docs.github.com/en/rest/overview/resources-in-the-rest-api#abuse-rate-limits" }`) }) @@ -927,7 +927,7 @@ func TestDo_rateLimit_abuseRateLimitError_retryAfter(t *testing.T) { w.WriteHeader(http.StatusForbidden) fmt.Fprintln(w, `{ "message": "You have triggered an abuse detection mechanism ...", - "documentation_url": "https://developer.github.com/v3/#abuse-rate-limits" + "documentation_url": "https://docs.github.com/en/rest/overview/resources-in-the-rest-api#abuse-rate-limits" }`) }) @@ -1049,7 +1049,7 @@ func TestCheckResponse_AbuseRateLimit(t *testing.T) { Request: &http.Request{}, StatusCode: http.StatusForbidden, Body: ioutil.NopCloser(strings.NewReader(`{"message":"m", - "documentation_url": "developer.github.com/v3/#abuse-rate-limits"}`)), + "documentation_url": "docs.github.com/en/rest/overview/resources-in-the-rest-api#abuse-rate-limits"}`)), } err := CheckResponse(res).(*AbuseRateLimitError) diff --git a/github/gitignore.go b/github/gitignore.go index 5d03f055722..ae035a084a1 100644 --- a/github/gitignore.go +++ b/github/gitignore.go @@ -13,7 +13,7 @@ import ( // GitignoresService provides access to the gitignore related functions in the // GitHub API. // -// GitHub API docs: https://developer.github.com/v3/gitignore/ +// GitHub API docs: https://docs.github.com/en/rest/reference/gitignore/ type GitignoresService service // Gitignore represents a .gitignore file as returned by the GitHub API. @@ -28,7 +28,7 @@ func (g Gitignore) String() string { // List all available Gitignore templates. // -// GitHub API docs: https://developer.github.com/v3/gitignore/#listing-available-templates +// GitHub API docs: https://docs.github.com/en/rest/reference/gitignore/#listing-available-templates func (s *GitignoresService) List(ctx context.Context) ([]string, *Response, error) { req, err := s.client.NewRequest("GET", "gitignore/templates", nil) if err != nil { @@ -46,7 +46,7 @@ func (s *GitignoresService) List(ctx context.Context) ([]string, *Response, erro // Get a Gitignore by name. // -// GitHub API docs: https://developer.github.com/v3/gitignore/#get-a-gitignore-template +// GitHub API docs: https://docs.github.com/en/rest/reference/gitignore/#get-a-gitignore-template func (s *GitignoresService) Get(ctx context.Context, name string) (*Gitignore, *Response, error) { u := fmt.Sprintf("gitignore/templates/%v", name) req, err := s.client.NewRequest("GET", u, nil) diff --git a/github/interactions.go b/github/interactions.go index b9965491db5..94c4cde5657 100644 --- a/github/interactions.go +++ b/github/interactions.go @@ -8,7 +8,7 @@ package github // InteractionsService handles communication with the repository and organization related // methods of the GitHub API. // -// GitHub API docs: https://developer.github.com/v3/interactions/ +// GitHub API docs: https://docs.github.com/en/rest/reference/interactions/ type InteractionsService service // InteractionRestriction represents the interaction restrictions for repository and organization. diff --git a/github/interactions_orgs.go b/github/interactions_orgs.go index e2fcabbc901..24b1f12ed53 100644 --- a/github/interactions_orgs.go +++ b/github/interactions_orgs.go @@ -12,7 +12,7 @@ import ( // GetRestrictionsForOrg fetches the interaction restrictions for an organization. // -// GitHub API docs: https://developer.github.com/v3/interactions/orgs/#get-interaction-restrictions-for-an-organization +// GitHub API docs: https://docs.github.com/en/rest/reference/interactions/#get-interaction-restrictions-for-an-organization func (s *InteractionsService) GetRestrictionsForOrg(ctx context.Context, organization string) (*InteractionRestriction, *Response, error) { u := fmt.Sprintf("orgs/%v/interaction-limits", organization) req, err := s.client.NewRequest("GET", u, nil) @@ -39,7 +39,7 @@ func (s *InteractionsService) GetRestrictionsForOrg(ctx context.Context, organiz // in public repositories for the given organization. // Possible values are: "existing_users", "contributors_only", "collaborators_only". // -// GitHub API docs: https://developer.github.com/v3/interactions/orgs/#set-interaction-restrictions-for-an-organization +// GitHub API docs: https://docs.github.com/en/rest/reference/interactions/#set-interaction-restrictions-for-an-organization func (s *InteractionsService) UpdateRestrictionsForOrg(ctx context.Context, organization, limit string) (*InteractionRestriction, *Response, error) { u := fmt.Sprintf("orgs/%v/interaction-limits", organization) @@ -65,7 +65,7 @@ func (s *InteractionsService) UpdateRestrictionsForOrg(ctx context.Context, orga // RemoveRestrictionsFromOrg removes the interaction restrictions for an organization. // -// GitHub API docs: https://developer.github.com/v3/interactions/orgs/#remove-interaction-restrictions-for-an-organization +// GitHub API docs: https://docs.github.com/en/rest/reference/interactions/#remove-interaction-restrictions-for-an-organization func (s *InteractionsService) RemoveRestrictionsFromOrg(ctx context.Context, organization string) (*Response, error) { u := fmt.Sprintf("orgs/%v/interaction-limits", organization) req, err := s.client.NewRequest("DELETE", u, nil) diff --git a/github/interactions_repos.go b/github/interactions_repos.go index 74f4ec4d6d5..0bd1cb9e427 100644 --- a/github/interactions_repos.go +++ b/github/interactions_repos.go @@ -12,7 +12,7 @@ import ( // GetRestrictionsForRepo fetches the interaction restrictions for a repository. // -// GitHub API docs: https://developer.github.com/v3/interactions/repos/#get-interaction-restrictions-for-a-repository +// GitHub API docs: https://docs.github.com/en/rest/reference/interactions/#get-interaction-restrictions-for-a-repository func (s *InteractionsService) GetRestrictionsForRepo(ctx context.Context, owner, repo string) (*InteractionRestriction, *Response, error) { u := fmt.Sprintf("repos/%v/%v/interaction-limits", owner, repo) req, err := s.client.NewRequest("GET", u, nil) @@ -39,7 +39,7 @@ func (s *InteractionsService) GetRestrictionsForRepo(ctx context.Context, owner, // for the given repository. // Possible values are: "existing_users", "contributors_only", "collaborators_only". // -// GitHub API docs: https://developer.github.com/v3/interactions/repos/#set-interaction-restrictions-for-a-repository +// GitHub API docs: https://docs.github.com/en/rest/reference/interactions/#set-interaction-restrictions-for-a-repository func (s *InteractionsService) UpdateRestrictionsForRepo(ctx context.Context, owner, repo, limit string) (*InteractionRestriction, *Response, error) { u := fmt.Sprintf("repos/%v/%v/interaction-limits", owner, repo) @@ -65,7 +65,7 @@ func (s *InteractionsService) UpdateRestrictionsForRepo(ctx context.Context, own // RemoveRestrictionsFromRepo removes the interaction restrictions for a repository. // -// GitHub API docs: https://developer.github.com/v3/interactions/repos/#remove-interaction-restrictions-for-a-repository +// GitHub API docs: https://docs.github.com/en/rest/reference/interactions/#remove-interaction-restrictions-for-a-repository func (s *InteractionsService) RemoveRestrictionsFromRepo(ctx context.Context, owner, repo string) (*Response, error) { u := fmt.Sprintf("repos/%v/%v/interaction-limits", owner, repo) req, err := s.client.NewRequest("DELETE", u, nil) diff --git a/github/issues.go b/github/issues.go index ccce80abc79..f584c72224d 100644 --- a/github/issues.go +++ b/github/issues.go @@ -15,7 +15,7 @@ import ( // IssuesService handles communication with the issue related // methods of the GitHub API. // -// GitHub API docs: https://developer.github.com/v3/issues/ +// GitHub API docs: https://docs.github.com/en/rest/reference/issues/ type IssuesService service // Issue represents a GitHub issue on a repository. @@ -55,7 +55,7 @@ type Issue struct { NodeID *string `json:"node_id,omitempty"` // TextMatches is only populated from search results that request text matches - // See: search.go and https://developer.github.com/v3/search/#text-match-metadata + // See: search.go and https://docs.github.com/en/rest/reference/search/#text-match-metadata TextMatches []*TextMatch `json:"text_matches,omitempty"` // ActiveLockReason is populated only when LockReason is provided while locking the issue. @@ -129,8 +129,8 @@ type PullRequestLinks struct { // organization repositories; if false, list only owned and member // repositories. // -// GitHub API docs: https://developer.github.com/v3/issues/#list-issues-assigned-to-the-authenticated-user -// GitHub API docs: https://developer.github.com/v3/issues/#list-user-account-issues-assigned-to-the-authenticated-user +// GitHub API docs: https://docs.github.com/en/rest/reference/issues/#list-user-account-issues-assigned-to-the-authenticated-user +// GitHub API docs: https://docs.github.com/en/rest/reference/issues/#list-issues-assigned-to-the-authenticated-user func (s *IssuesService) List(ctx context.Context, all bool, opts *IssueListOptions) ([]*Issue, *Response, error) { var u string if all { @@ -144,7 +144,7 @@ func (s *IssuesService) List(ctx context.Context, all bool, opts *IssueListOptio // ListByOrg fetches the issues in the specified organization for the // authenticated user. // -// GitHub API docs: https://developer.github.com/v3/issues/#list-organization-issues-assigned-to-the-authenticated-user +// GitHub API docs: https://docs.github.com/en/rest/reference/issues/#list-organization-issues-assigned-to-the-authenticated-user func (s *IssuesService) ListByOrg(ctx context.Context, org string, opts *IssueListOptions) ([]*Issue, *Response, error) { u := fmt.Sprintf("orgs/%v/issues", org) return s.listIssues(ctx, u, opts) @@ -216,7 +216,7 @@ type IssueListByRepoOptions struct { // ListByRepo lists the issues for the specified repository. // -// GitHub API docs: https://developer.github.com/v3/issues/#list-repository-issues +// GitHub API docs: https://docs.github.com/en/rest/reference/issues/#list-repository-issues func (s *IssuesService) ListByRepo(ctx context.Context, owner string, repo string, opts *IssueListByRepoOptions) ([]*Issue, *Response, error) { u := fmt.Sprintf("repos/%v/%v/issues", owner, repo) u, err := addOptions(u, opts) @@ -244,7 +244,7 @@ func (s *IssuesService) ListByRepo(ctx context.Context, owner string, repo strin // Get a single issue. // -// GitHub API docs: https://developer.github.com/v3/issues/#get-an-issue +// GitHub API docs: https://docs.github.com/en/rest/reference/issues/#get-an-issue func (s *IssuesService) Get(ctx context.Context, owner string, repo string, number int) (*Issue, *Response, error) { u := fmt.Sprintf("repos/%v/%v/issues/%d", owner, repo, number) req, err := s.client.NewRequest("GET", u, nil) @@ -267,7 +267,7 @@ func (s *IssuesService) Get(ctx context.Context, owner string, repo string, numb // Create a new issue on the specified repository. // -// GitHub API docs: https://developer.github.com/v3/issues/#create-an-issue +// GitHub API docs: https://docs.github.com/en/rest/reference/issues/#create-an-issue func (s *IssuesService) Create(ctx context.Context, owner string, repo string, issue *IssueRequest) (*Issue, *Response, error) { u := fmt.Sprintf("repos/%v/%v/issues", owner, repo) req, err := s.client.NewRequest("POST", u, issue) @@ -286,7 +286,7 @@ func (s *IssuesService) Create(ctx context.Context, owner string, repo string, i // Edit an issue. // -// GitHub API docs: https://developer.github.com/v3/issues/#update-an-issue +// GitHub API docs: https://docs.github.com/en/rest/reference/issues/#update-an-issue func (s *IssuesService) Edit(ctx context.Context, owner string, repo string, number int, issue *IssueRequest) (*Issue, *Response, error) { u := fmt.Sprintf("repos/%v/%v/issues/%d", owner, repo, number) req, err := s.client.NewRequest("PATCH", u, issue) @@ -314,7 +314,7 @@ type LockIssueOptions struct { // Lock an issue's conversation. // -// GitHub API docs: https://developer.github.com/v3/issues/#lock-an-issue +// GitHub API docs: https://docs.github.com/en/rest/reference/issues/#lock-an-issue func (s *IssuesService) Lock(ctx context.Context, owner string, repo string, number int, opts *LockIssueOptions) (*Response, error) { u := fmt.Sprintf("repos/%v/%v/issues/%d/lock", owner, repo, number) req, err := s.client.NewRequest("PUT", u, opts) @@ -331,7 +331,7 @@ func (s *IssuesService) Lock(ctx context.Context, owner string, repo string, num // Unlock an issue's conversation. // -// GitHub API docs: https://developer.github.com/v3/issues/#unlock-an-issue +// GitHub API docs: https://docs.github.com/en/rest/reference/issues/#unlock-an-issue func (s *IssuesService) Unlock(ctx context.Context, owner string, repo string, number int) (*Response, error) { u := fmt.Sprintf("repos/%v/%v/issues/%d/lock", owner, repo, number) req, err := s.client.NewRequest("DELETE", u, nil) diff --git a/github/issues_assignees.go b/github/issues_assignees.go index fedb3510615..e8fb4e3c9ff 100644 --- a/github/issues_assignees.go +++ b/github/issues_assignees.go @@ -13,7 +13,7 @@ import ( // ListAssignees fetches all available assignees (owners and collaborators) to // which issues may be assigned. // -// GitHub API docs: https://developer.github.com/v3/issues/assignees/#list-assignees +// GitHub API docs: https://docs.github.com/en/rest/reference/issues/#list-assignees func (s *IssuesService) ListAssignees(ctx context.Context, owner, repo string, opts *ListOptions) ([]*User, *Response, error) { u := fmt.Sprintf("repos/%v/%v/assignees", owner, repo) u, err := addOptions(u, opts) @@ -36,7 +36,7 @@ func (s *IssuesService) ListAssignees(ctx context.Context, owner, repo string, o // IsAssignee checks if a user is an assignee for the specified repository. // -// GitHub API docs: https://developer.github.com/v3/issues/assignees/#check-if-a-user-can-be-assigned +// GitHub API docs: https://docs.github.com/en/rest/reference/issues/#check-if-a-user-can-be-assigned func (s *IssuesService) IsAssignee(ctx context.Context, owner, repo, user string) (bool, *Response, error) { u := fmt.Sprintf("repos/%v/%v/assignees/%v", owner, repo, user) req, err := s.client.NewRequest("GET", u, nil) @@ -50,7 +50,7 @@ func (s *IssuesService) IsAssignee(ctx context.Context, owner, repo, user string // AddAssignees adds the provided GitHub users as assignees to the issue. // -// GitHub API docs: https://developer.github.com/v3/issues/assignees/#add-assignees-to-an-issue +// GitHub API docs: https://docs.github.com/en/rest/reference/issues/#add-assignees-to-an-issue func (s *IssuesService) AddAssignees(ctx context.Context, owner, repo string, number int, assignees []string) (*Issue, *Response, error) { users := &struct { Assignees []string `json:"assignees,omitempty"` @@ -68,7 +68,7 @@ func (s *IssuesService) AddAssignees(ctx context.Context, owner, repo string, nu // RemoveAssignees removes the provided GitHub users as assignees from the issue. // -// GitHub API docs: https://developer.github.com/v3/issues/assignees/#remove-assignees-from-an-issue +// GitHub API docs: https://docs.github.com/en/rest/reference/issues/#remove-assignees-from-an-issue func (s *IssuesService) RemoveAssignees(ctx context.Context, owner, repo string, number int, assignees []string) (*Issue, *Response, error) { users := &struct { Assignees []string `json:"assignees,omitempty"` diff --git a/github/issues_comments.go b/github/issues_comments.go index eade48eed10..55090a152d0 100644 --- a/github/issues_comments.go +++ b/github/issues_comments.go @@ -44,8 +44,8 @@ type IssueListCommentsOptions struct { // ListComments lists all comments on the specified issue. Specifying an issue // number of 0 will return all comments on all issues for the repository. // -// GitHub API docs: https://developer.github.com/v3/issues/comments/#list-issue-comments -// GitHub API docs: https://developer.github.com/v3/issues/comments/#list-issue-comments-for-a-repository +// GitHub API docs: https://docs.github.com/en/rest/reference/issues/#list-issue-comments +// GitHub API docs: https://docs.github.com/en/rest/reference/issues/#list-issue-comments-for-a-repository func (s *IssuesService) ListComments(ctx context.Context, owner string, repo string, number int, opts *IssueListCommentsOptions) ([]*IssueComment, *Response, error) { var u string if number == 0 { @@ -77,7 +77,7 @@ func (s *IssuesService) ListComments(ctx context.Context, owner string, repo str // GetComment fetches the specified issue comment. // -// GitHub API docs: https://developer.github.com/v3/issues/comments/#get-an-issue-comment +// GitHub API docs: https://docs.github.com/en/rest/reference/issues/#get-an-issue-comment func (s *IssuesService) GetComment(ctx context.Context, owner string, repo string, commentID int64) (*IssueComment, *Response, error) { u := fmt.Sprintf("repos/%v/%v/issues/comments/%d", owner, repo, commentID) @@ -100,7 +100,7 @@ func (s *IssuesService) GetComment(ctx context.Context, owner string, repo strin // CreateComment creates a new comment on the specified issue. // -// GitHub API docs: https://developer.github.com/v3/issues/comments/#create-an-issue-comment +// GitHub API docs: https://docs.github.com/en/rest/reference/issues/#create-an-issue-comment func (s *IssuesService) CreateComment(ctx context.Context, owner string, repo string, number int, comment *IssueComment) (*IssueComment, *Response, error) { u := fmt.Sprintf("repos/%v/%v/issues/%d/comments", owner, repo, number) req, err := s.client.NewRequest("POST", u, comment) @@ -119,7 +119,7 @@ func (s *IssuesService) CreateComment(ctx context.Context, owner string, repo st // EditComment updates an issue comment. // A non-nil comment.Body must be provided. Other comment fields should be left nil. // -// GitHub API docs: https://developer.github.com/v3/issues/comments/#update-an-issue-comment +// GitHub API docs: https://docs.github.com/en/rest/reference/issues/#update-an-issue-comment func (s *IssuesService) EditComment(ctx context.Context, owner string, repo string, commentID int64, comment *IssueComment) (*IssueComment, *Response, error) { u := fmt.Sprintf("repos/%v/%v/issues/comments/%d", owner, repo, commentID) req, err := s.client.NewRequest("PATCH", u, comment) @@ -137,7 +137,7 @@ func (s *IssuesService) EditComment(ctx context.Context, owner string, repo stri // DeleteComment deletes an issue comment. // -// GitHub API docs: https://developer.github.com/v3/issues/comments/#delete-an-issue-comment +// GitHub API docs: https://docs.github.com/en/rest/reference/issues/#delete-an-issue-comment func (s *IssuesService) DeleteComment(ctx context.Context, owner string, repo string, commentID int64) (*Response, error) { u := fmt.Sprintf("repos/%v/%v/issues/comments/%d", owner, repo, commentID) req, err := s.client.NewRequest("DELETE", u, nil) diff --git a/github/issues_events.go b/github/issues_events.go index 8d3dd864cd1..60ff78a6611 100644 --- a/github/issues_events.go +++ b/github/issues_events.go @@ -95,7 +95,7 @@ type DismissedReview struct { // ListIssueEvents lists events for the specified issue. // -// GitHub API docs: https://developer.github.com/v3/issues/events/#list-issue-events +// GitHub API docs: https://docs.github.com/en/rest/reference/issues/#list-issue-events func (s *IssuesService) ListIssueEvents(ctx context.Context, owner, repo string, number int, opts *ListOptions) ([]*IssueEvent, *Response, error) { u := fmt.Sprintf("repos/%v/%v/issues/%v/events", owner, repo, number) u, err := addOptions(u, opts) @@ -122,7 +122,7 @@ func (s *IssuesService) ListIssueEvents(ctx context.Context, owner, repo string, // ListRepositoryEvents lists events for the specified repository. // -// GitHub API docs: https://developer.github.com/v3/issues/events/#list-issue-events-for-a-repository +// GitHub API docs: https://docs.github.com/en/rest/reference/issues/#list-issue-events-for-a-repository func (s *IssuesService) ListRepositoryEvents(ctx context.Context, owner, repo string, opts *ListOptions) ([]*IssueEvent, *Response, error) { u := fmt.Sprintf("repos/%v/%v/issues/events", owner, repo) u, err := addOptions(u, opts) @@ -146,7 +146,7 @@ func (s *IssuesService) ListRepositoryEvents(ctx context.Context, owner, repo st // GetEvent returns the specified issue event. // -// GitHub API docs: https://developer.github.com/v3/issues/events/#get-an-issue-event +// GitHub API docs: https://docs.github.com/en/rest/reference/issues/#get-an-issue-event func (s *IssuesService) GetEvent(ctx context.Context, owner, repo string, id int64) (*IssueEvent, *Response, error) { u := fmt.Sprintf("repos/%v/%v/issues/events/%v", owner, repo, id) diff --git a/github/issues_labels.go b/github/issues_labels.go index 12a87415547..5e2c6f9b5ff 100644 --- a/github/issues_labels.go +++ b/github/issues_labels.go @@ -27,7 +27,7 @@ func (l Label) String() string { // ListLabels lists all labels for a repository. // -// GitHub API docs: https://developer.github.com/v3/issues/labels/#list-labels-for-a-repository +// GitHub API docs: https://docs.github.com/en/rest/reference/issues/#list-labels-for-a-repository func (s *IssuesService) ListLabels(ctx context.Context, owner string, repo string, opts *ListOptions) ([]*Label, *Response, error) { u := fmt.Sprintf("repos/%v/%v/labels", owner, repo) u, err := addOptions(u, opts) @@ -51,7 +51,7 @@ func (s *IssuesService) ListLabels(ctx context.Context, owner string, repo strin // GetLabel gets a single label. // -// GitHub API docs: https://developer.github.com/v3/issues/labels/#get-a-label +// GitHub API docs: https://docs.github.com/en/rest/reference/issues/#get-a-label func (s *IssuesService) GetLabel(ctx context.Context, owner string, repo string, name string) (*Label, *Response, error) { u := fmt.Sprintf("repos/%v/%v/labels/%v", owner, repo, name) req, err := s.client.NewRequest("GET", u, nil) @@ -70,7 +70,7 @@ func (s *IssuesService) GetLabel(ctx context.Context, owner string, repo string, // CreateLabel creates a new label on the specified repository. // -// GitHub API docs: https://developer.github.com/v3/issues/labels/#create-a-label +// GitHub API docs: https://docs.github.com/en/rest/reference/issues/#create-a-label func (s *IssuesService) CreateLabel(ctx context.Context, owner string, repo string, label *Label) (*Label, *Response, error) { u := fmt.Sprintf("repos/%v/%v/labels", owner, repo) req, err := s.client.NewRequest("POST", u, label) @@ -89,7 +89,7 @@ func (s *IssuesService) CreateLabel(ctx context.Context, owner string, repo stri // EditLabel edits a label. // -// GitHub API docs: https://developer.github.com/v3/issues/labels/#update-a-label +// GitHub API docs: https://docs.github.com/en/rest/reference/issues/#update-a-label func (s *IssuesService) EditLabel(ctx context.Context, owner string, repo string, name string, label *Label) (*Label, *Response, error) { u := fmt.Sprintf("repos/%v/%v/labels/%v", owner, repo, name) req, err := s.client.NewRequest("PATCH", u, label) @@ -108,7 +108,7 @@ func (s *IssuesService) EditLabel(ctx context.Context, owner string, repo string // DeleteLabel deletes a label. // -// GitHub API docs: https://developer.github.com/v3/issues/labels/#delete-a-label +// GitHub API docs: https://docs.github.com/en/rest/reference/issues/#delete-a-label func (s *IssuesService) DeleteLabel(ctx context.Context, owner string, repo string, name string) (*Response, error) { u := fmt.Sprintf("repos/%v/%v/labels/%v", owner, repo, name) req, err := s.client.NewRequest("DELETE", u, nil) @@ -120,7 +120,7 @@ func (s *IssuesService) DeleteLabel(ctx context.Context, owner string, repo stri // ListLabelsByIssue lists all labels for an issue. // -// GitHub API docs: https://developer.github.com/v3/issues/labels/#list-labels-for-an-issue +// GitHub API docs: https://docs.github.com/en/rest/reference/issues/#list-labels-for-an-issue func (s *IssuesService) ListLabelsByIssue(ctx context.Context, owner string, repo string, number int, opts *ListOptions) ([]*Label, *Response, error) { u := fmt.Sprintf("repos/%v/%v/issues/%d/labels", owner, repo, number) u, err := addOptions(u, opts) @@ -144,7 +144,7 @@ func (s *IssuesService) ListLabelsByIssue(ctx context.Context, owner string, rep // AddLabelsToIssue adds labels to an issue. // -// GitHub API docs: https://developer.github.com/v3/issues/labels/#add-labels-to-an-issue +// GitHub API docs: https://docs.github.com/en/rest/reference/issues/#add-labels-to-an-issue func (s *IssuesService) AddLabelsToIssue(ctx context.Context, owner string, repo string, number int, labels []string) ([]*Label, *Response, error) { u := fmt.Sprintf("repos/%v/%v/issues/%d/labels", owner, repo, number) req, err := s.client.NewRequest("POST", u, labels) @@ -163,7 +163,7 @@ func (s *IssuesService) AddLabelsToIssue(ctx context.Context, owner string, repo // RemoveLabelForIssue removes a label for an issue. // -// GitHub API docs: https://developer.github.com/v3/issues/labels/#remove-a-label-from-an-issue +// GitHub API docs: https://docs.github.com/en/rest/reference/issues/#remove-a-label-from-an-issue func (s *IssuesService) RemoveLabelForIssue(ctx context.Context, owner string, repo string, number int, label string) (*Response, error) { u := fmt.Sprintf("repos/%v/%v/issues/%d/labels/%v", owner, repo, number, label) req, err := s.client.NewRequest("DELETE", u, nil) @@ -176,7 +176,7 @@ func (s *IssuesService) RemoveLabelForIssue(ctx context.Context, owner string, r // ReplaceLabelsForIssue replaces all labels for an issue. // -// GitHub API docs: https://developer.github.com/v3/issues/labels/#set-labels-for-an-issue +// GitHub API docs: https://docs.github.com/en/rest/reference/issues/#set-labels-for-an-issue func (s *IssuesService) ReplaceLabelsForIssue(ctx context.Context, owner string, repo string, number int, labels []string) ([]*Label, *Response, error) { u := fmt.Sprintf("repos/%v/%v/issues/%d/labels", owner, repo, number) req, err := s.client.NewRequest("PUT", u, labels) @@ -195,7 +195,7 @@ func (s *IssuesService) ReplaceLabelsForIssue(ctx context.Context, owner string, // RemoveLabelsForIssue removes all labels for an issue. // -// GitHub API docs: https://developer.github.com/v3/issues/labels/#remove-all-labels-from-an-issue +// GitHub API docs: https://docs.github.com/en/rest/reference/issues/#remove-all-labels-from-an-issue func (s *IssuesService) RemoveLabelsForIssue(ctx context.Context, owner string, repo string, number int) (*Response, error) { u := fmt.Sprintf("repos/%v/%v/issues/%d/labels", owner, repo, number) req, err := s.client.NewRequest("DELETE", u, nil) @@ -208,7 +208,7 @@ func (s *IssuesService) RemoveLabelsForIssue(ctx context.Context, owner string, // ListLabelsForMilestone lists labels for every issue in a milestone. // -// GitHub API docs: https://developer.github.com/v3/issues/labels/#list-labels-for-issues-in-a-milestone +// GitHub API docs: https://docs.github.com/en/rest/reference/issues/#list-labels-for-issues-in-a-milestone func (s *IssuesService) ListLabelsForMilestone(ctx context.Context, owner string, repo string, number int, opts *ListOptions) ([]*Label, *Response, error) { u := fmt.Sprintf("repos/%v/%v/milestones/%d/labels", owner, repo, number) u, err := addOptions(u, opts) diff --git a/github/issues_milestones.go b/github/issues_milestones.go index ed3a7c54f2d..6f757eef5ef 100644 --- a/github/issues_milestones.go +++ b/github/issues_milestones.go @@ -55,7 +55,7 @@ type MilestoneListOptions struct { // ListMilestones lists all milestones for a repository. // -// GitHub API docs: https://developer.github.com/v3/issues/milestones/#list-milestones +// GitHub API docs: https://docs.github.com/en/rest/reference/issues/#list-milestones func (s *IssuesService) ListMilestones(ctx context.Context, owner string, repo string, opts *MilestoneListOptions) ([]*Milestone, *Response, error) { u := fmt.Sprintf("repos/%v/%v/milestones", owner, repo) u, err := addOptions(u, opts) @@ -79,7 +79,7 @@ func (s *IssuesService) ListMilestones(ctx context.Context, owner string, repo s // GetMilestone gets a single milestone. // -// GitHub API docs: https://developer.github.com/v3/issues/milestones/#get-a-milestone +// GitHub API docs: https://docs.github.com/en/rest/reference/issues/#get-a-milestone func (s *IssuesService) GetMilestone(ctx context.Context, owner string, repo string, number int) (*Milestone, *Response, error) { u := fmt.Sprintf("repos/%v/%v/milestones/%d", owner, repo, number) req, err := s.client.NewRequest("GET", u, nil) @@ -98,7 +98,7 @@ func (s *IssuesService) GetMilestone(ctx context.Context, owner string, repo str // CreateMilestone creates a new milestone on the specified repository. // -// GitHub API docs: https://developer.github.com/v3/issues/milestones/#create-a-milestone +// GitHub API docs: https://docs.github.com/en/rest/reference/issues/#create-a-milestone func (s *IssuesService) CreateMilestone(ctx context.Context, owner string, repo string, milestone *Milestone) (*Milestone, *Response, error) { u := fmt.Sprintf("repos/%v/%v/milestones", owner, repo) req, err := s.client.NewRequest("POST", u, milestone) @@ -117,7 +117,7 @@ func (s *IssuesService) CreateMilestone(ctx context.Context, owner string, repo // EditMilestone edits a milestone. // -// GitHub API docs: https://developer.github.com/v3/issues/milestones/#update-a-milestone +// GitHub API docs: https://docs.github.com/en/rest/reference/issues/#update-a-milestone func (s *IssuesService) EditMilestone(ctx context.Context, owner string, repo string, number int, milestone *Milestone) (*Milestone, *Response, error) { u := fmt.Sprintf("repos/%v/%v/milestones/%d", owner, repo, number) req, err := s.client.NewRequest("PATCH", u, milestone) @@ -136,7 +136,7 @@ func (s *IssuesService) EditMilestone(ctx context.Context, owner string, repo st // DeleteMilestone deletes a milestone. // -// GitHub API docs: https://developer.github.com/v3/issues/milestones/#delete-a-milestone +// GitHub API docs: https://docs.github.com/en/rest/reference/issues/#delete-a-milestone func (s *IssuesService) DeleteMilestone(ctx context.Context, owner string, repo string, number int) (*Response, error) { u := fmt.Sprintf("repos/%v/%v/milestones/%d", owner, repo, number) req, err := s.client.NewRequest("DELETE", u, nil) diff --git a/github/issues_timeline.go b/github/issues_timeline.go index 6a88af8ca49..5c68c88769e 100644 --- a/github/issues_timeline.go +++ b/github/issues_timeline.go @@ -15,7 +15,7 @@ import ( // Timeline represents an event that occurred around an Issue or Pull Request. // // It is similar to an IssueEvent but may contain more information. -// GitHub API docs: https://developer.github.com/v3/issues/timeline/ +// GitHub API docs: https://docs.github.com/en/rest/reference/issues/timeline/ type Timeline struct { ID *int64 `json:"id,omitempty"` URL *string `json:"url,omitempty"` @@ -131,7 +131,7 @@ type Source struct { // ListIssueTimeline lists events for the specified issue. // -// GitHub API docs: https://developer.github.com/v3/issues/timeline/#list-timeline-events-for-an-issue +// GitHub API docs: https://docs.github.com/en/rest/reference/issues/#list-timeline-events-for-an-issue func (s *IssuesService) ListIssueTimeline(ctx context.Context, owner, repo string, number int, opts *ListOptions) ([]*Timeline, *Response, error) { u := fmt.Sprintf("repos/%v/%v/issues/%v/timeline", owner, repo, number) u, err := addOptions(u, opts) diff --git a/github/licenses.go b/github/licenses.go index 55885f27046..0d04096ba50 100644 --- a/github/licenses.go +++ b/github/licenses.go @@ -13,7 +13,7 @@ import ( // LicensesService handles communication with the license related // methods of the GitHub API. // -// GitHub API docs: https://developer.github.com/v3/licenses/ +// GitHub API docs: https://docs.github.com/en/rest/reference/licenses/ type LicensesService service // RepositoryLicense represents the license for a repository. @@ -60,7 +60,7 @@ func (l License) String() string { // List popular open source licenses. // -// GitHub API docs: https://developer.github.com/v3/licenses/#list-all-licenses +// GitHub API docs: https://docs.github.com/en/rest/reference/licenses/#list-all-licenses func (s *LicensesService) List(ctx context.Context) ([]*License, *Response, error) { req, err := s.client.NewRequest("GET", "licenses", nil) if err != nil { @@ -78,7 +78,7 @@ func (s *LicensesService) List(ctx context.Context) ([]*License, *Response, erro // Get extended metadata for one license. // -// GitHub API docs: https://developer.github.com/v3/licenses/#get-a-license +// GitHub API docs: https://docs.github.com/en/rest/reference/licenses/#get-a-license func (s *LicensesService) Get(ctx context.Context, licenseName string) (*License, *Response, error) { u := fmt.Sprintf("licenses/%s", licenseName) diff --git a/github/messages.go b/github/messages.go index adf623e0e88..f2d167c777d 100644 --- a/github/messages.go +++ b/github/messages.go @@ -218,14 +218,14 @@ func ValidateSignature(signature string, payload, secretToken []byte) error { // WebHookType returns the event type of webhook request r. // -// GitHub API docs: https://developer.github.com/v3/repos/hooks/#webhook-headers +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/hooks/#webhook-headers func WebHookType(r *http.Request) string { return r.Header.Get(eventTypeHeader) } // DeliveryID returns the unique delivery ID of webhook request r. // -// GitHub API docs: https://developer.github.com/v3/repos/hooks/#webhook-headers +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/hooks/#webhook-headers func DeliveryID(r *http.Request) string { return r.Header.Get(deliveryIDHeader) } diff --git a/github/migrations.go b/github/migrations.go index fae0c6e17db..b77692b3408 100644 --- a/github/migrations.go +++ b/github/migrations.go @@ -16,7 +16,7 @@ import ( // MigrationService provides access to the migration related functions // in the GitHub API. // -// GitHub API docs: https://developer.github.com/v3/migration/ +// GitHub API docs: https://docs.github.com/en/rest/reference/migration/ type MigrationService service // Migration represents a GitHub migration (archival). @@ -74,7 +74,7 @@ type startMigration struct { // StartMigration starts the generation of a migration archive. // repos is a slice of repository names to migrate. // -// GitHub API docs: https://developer.github.com/v3/migrations/orgs/#start-an-organization-migration +// GitHub API docs: https://docs.github.com/en/rest/reference/migrations/#start-an-organization-migration func (s *MigrationService) StartMigration(ctx context.Context, org string, repos []string, opts *MigrationOptions) (*Migration, *Response, error) { u := fmt.Sprintf("orgs/%v/migrations", org) @@ -103,7 +103,7 @@ func (s *MigrationService) StartMigration(ctx context.Context, org string, repos // ListMigrations lists the most recent migrations. // -// GitHub API docs: https://developer.github.com/v3/migrations/orgs/#list-organization-migrations +// GitHub API docs: https://docs.github.com/en/rest/reference/migrations/#list-organization-migrations func (s *MigrationService) ListMigrations(ctx context.Context, org string, opts *ListOptions) ([]*Migration, *Response, error) { u := fmt.Sprintf("orgs/%v/migrations", org) u, err := addOptions(u, opts) @@ -131,7 +131,7 @@ func (s *MigrationService) ListMigrations(ctx context.Context, org string, opts // MigrationStatus gets the status of a specific migration archive. // id is the migration ID. // -// GitHub API docs: https://developer.github.com/v3/migrations/orgs/#get-an-organization-migration-status +// GitHub API docs: https://docs.github.com/en/rest/reference/migrations/#get-an-organization-migration-status func (s *MigrationService) MigrationStatus(ctx context.Context, org string, id int64) (*Migration, *Response, error) { u := fmt.Sprintf("orgs/%v/migrations/%v", org, id) @@ -155,7 +155,7 @@ func (s *MigrationService) MigrationStatus(ctx context.Context, org string, id i // MigrationArchiveURL fetches a migration archive URL. // id is the migration ID. // -// GitHub API docs: https://developer.github.com/v3/migrations/orgs/#download-an-organization-migration-archive +// GitHub API docs: https://docs.github.com/en/rest/reference/migrations/#download-an-organization-migration-archive func (s *MigrationService) MigrationArchiveURL(ctx context.Context, org string, id int64) (url string, err error) { u := fmt.Sprintf("orgs/%v/migrations/%v/archive", org, id) @@ -192,7 +192,7 @@ func (s *MigrationService) MigrationArchiveURL(ctx context.Context, org string, // DeleteMigration deletes a previous migration archive. // id is the migration ID. // -// GitHub API docs: https://developer.github.com/v3/migrations/orgs/#delete-an-organization-migration-archive +// GitHub API docs: https://docs.github.com/en/rest/reference/migrations/#delete-an-organization-migration-archive func (s *MigrationService) DeleteMigration(ctx context.Context, org string, id int64) (*Response, error) { u := fmt.Sprintf("orgs/%v/migrations/%v/archive", org, id) @@ -212,7 +212,7 @@ func (s *MigrationService) DeleteMigration(ctx context.Context, org string, id i // You should unlock each migrated repository and delete them when the migration // is complete and you no longer need the source data. // -// GitHub API docs: https://developer.github.com/v3/migrations/orgs/#unlock-an-organization-repository +// GitHub API docs: https://docs.github.com/en/rest/reference/migrations/#unlock-an-organization-repository func (s *MigrationService) UnlockRepo(ctx context.Context, org string, id int64, repo string) (*Response, error) { u := fmt.Sprintf("orgs/%v/migrations/%v/repos/%v/lock", org, id, repo) diff --git a/github/migrations_source_import.go b/github/migrations_source_import.go index 7a46d0edfff..49e01503e29 100644 --- a/github/migrations_source_import.go +++ b/github/migrations_source_import.go @@ -115,7 +115,7 @@ func (i Import) String() string { // SourceImportAuthor identifies an author imported from a source repository. // -// GitHub API docs: https://developer.github.com/v3/migration/source_imports/#get-commit-authors +// GitHub API docs: https://docs.github.com/en/rest/reference/migration/source_imports/#get-commit-authors type SourceImportAuthor struct { ID *int64 `json:"id,omitempty"` RemoteID *string `json:"remote_id,omitempty"` @@ -132,7 +132,7 @@ func (a SourceImportAuthor) String() string { // LargeFile identifies a file larger than 100MB found during a repository import. // -// GitHub API docs: https://developer.github.com/v3/migration/source_imports/#get-large-files +// GitHub API docs: https://docs.github.com/en/rest/reference/migration/source_imports/#get-large-files type LargeFile struct { RefName *string `json:"ref_name,omitempty"` Path *string `json:"path,omitempty"` @@ -146,7 +146,7 @@ func (f LargeFile) String() string { // StartImport initiates a repository import. // -// GitHub API docs: https://developer.github.com/v3/migrations/source_imports/#start-an-import +// GitHub API docs: https://docs.github.com/en/rest/reference/migrations/#start-an-import func (s *MigrationService) StartImport(ctx context.Context, owner, repo string, in *Import) (*Import, *Response, error) { u := fmt.Sprintf("repos/%v/%v/import", owner, repo) req, err := s.client.NewRequest("PUT", u, in) @@ -165,7 +165,7 @@ func (s *MigrationService) StartImport(ctx context.Context, owner, repo string, // ImportProgress queries for the status and progress of an ongoing repository import. // -// GitHub API docs: https://developer.github.com/v3/migrations/source_imports/#get-an-import-status +// GitHub API docs: https://docs.github.com/en/rest/reference/migrations/#get-an-import-status func (s *MigrationService) ImportProgress(ctx context.Context, owner, repo string) (*Import, *Response, error) { u := fmt.Sprintf("repos/%v/%v/import", owner, repo) req, err := s.client.NewRequest("GET", u, nil) @@ -184,7 +184,7 @@ func (s *MigrationService) ImportProgress(ctx context.Context, owner, repo strin // UpdateImport initiates a repository import. // -// GitHub API docs: https://developer.github.com/v3/migrations/source_imports/#update-an-import +// GitHub API docs: https://docs.github.com/en/rest/reference/migrations/#update-an-import func (s *MigrationService) UpdateImport(ctx context.Context, owner, repo string, in *Import) (*Import, *Response, error) { u := fmt.Sprintf("repos/%v/%v/import", owner, repo) req, err := s.client.NewRequest("PATCH", u, in) @@ -213,7 +213,7 @@ func (s *MigrationService) UpdateImport(ctx context.Context, owner, repo string, // This method and MapCommitAuthor allow you to provide correct Git author // information. // -// GitHub API docs: https://developer.github.com/v3/migrations/source_imports/#get-commit-authors +// GitHub API docs: https://docs.github.com/en/rest/reference/migrations/#get-commit-authors func (s *MigrationService) CommitAuthors(ctx context.Context, owner, repo string) ([]*SourceImportAuthor, *Response, error) { u := fmt.Sprintf("repos/%v/%v/import/authors", owner, repo) req, err := s.client.NewRequest("GET", u, nil) @@ -234,7 +234,7 @@ func (s *MigrationService) CommitAuthors(ctx context.Context, owner, repo string // application can continue updating authors any time before you push new // commits to the repository. // -// GitHub API docs: https://developer.github.com/v3/migrations/source_imports/#map-a-commit-author +// GitHub API docs: https://docs.github.com/en/rest/reference/migrations/#map-a-commit-author func (s *MigrationService) MapCommitAuthor(ctx context.Context, owner, repo string, id int64, author *SourceImportAuthor) (*SourceImportAuthor, *Response, error) { u := fmt.Sprintf("repos/%v/%v/import/authors/%v", owner, repo, id) req, err := s.client.NewRequest("PATCH", u, author) @@ -255,7 +255,7 @@ func (s *MigrationService) MapCommitAuthor(ctx context.Context, owner, repo stri // files larger than 100MB. Only the UseLFS field on the provided Import is // used. // -// GitHub API docs: https://developer.github.com/v3/migrations/source_imports/#update-git-lfs-preference +// GitHub API docs: https://docs.github.com/en/rest/reference/migrations/#update-git-lfs-preference func (s *MigrationService) SetLFSPreference(ctx context.Context, owner, repo string, in *Import) (*Import, *Response, error) { u := fmt.Sprintf("repos/%v/%v/import/lfs", owner, repo) req, err := s.client.NewRequest("PATCH", u, in) @@ -274,7 +274,7 @@ func (s *MigrationService) SetLFSPreference(ctx context.Context, owner, repo str // LargeFiles lists files larger than 100MB found during the import. // -// GitHub API docs: https://developer.github.com/v3/migrations/source_imports/#get-large-files +// GitHub API docs: https://docs.github.com/en/rest/reference/migrations/#get-large-files func (s *MigrationService) LargeFiles(ctx context.Context, owner, repo string) ([]*LargeFile, *Response, error) { u := fmt.Sprintf("repos/%v/%v/import/large_files", owner, repo) req, err := s.client.NewRequest("GET", u, nil) @@ -293,7 +293,7 @@ func (s *MigrationService) LargeFiles(ctx context.Context, owner, repo string) ( // CancelImport stops an import for a repository. // -// GitHub API docs: https://developer.github.com/v3/migrations/source_imports/#cancel-an-import +// GitHub API docs: https://docs.github.com/en/rest/reference/migrations/#cancel-an-import func (s *MigrationService) CancelImport(ctx context.Context, owner, repo string) (*Response, error) { u := fmt.Sprintf("repos/%v/%v/import", owner, repo) req, err := s.client.NewRequest("DELETE", u, nil) diff --git a/github/migrations_user.go b/github/migrations_user.go index d03bfe7ef2f..1dcb3ff80fc 100644 --- a/github/migrations_user.go +++ b/github/migrations_user.go @@ -67,7 +67,7 @@ type startUserMigration struct { // StartUserMigration starts the generation of a migration archive. // repos is a slice of repository names to migrate. // -// GitHub API docs: https://developer.github.com/v3/migrations/users/#start-a-user-migration +// GitHub API docs: https://docs.github.com/en/rest/reference/migrations/#start-a-user-migration func (s *MigrationService) StartUserMigration(ctx context.Context, repos []string, opts *UserMigrationOptions) (*UserMigration, *Response, error) { u := "user/migrations" @@ -96,7 +96,7 @@ func (s *MigrationService) StartUserMigration(ctx context.Context, repos []strin // ListUserMigrations lists the most recent migrations. // -// GitHub API docs: https://developer.github.com/v3/migrations/users/#list-user-migrations +// GitHub API docs: https://docs.github.com/en/rest/reference/migrations/#list-user-migrations func (s *MigrationService) ListUserMigrations(ctx context.Context) ([]*UserMigration, *Response, error) { u := "user/migrations" @@ -120,7 +120,7 @@ func (s *MigrationService) ListUserMigrations(ctx context.Context) ([]*UserMigra // UserMigrationStatus gets the status of a specific migration archive. // id is the migration ID. // -// GitHub API docs: https://developer.github.com/v3/migrations/users/#get-a-user-migration-status +// GitHub API docs: https://docs.github.com/en/rest/reference/migrations/#get-a-user-migration-status func (s *MigrationService) UserMigrationStatus(ctx context.Context, id int64) (*UserMigration, *Response, error) { u := fmt.Sprintf("user/migrations/%v", id) @@ -144,7 +144,7 @@ func (s *MigrationService) UserMigrationStatus(ctx context.Context, id int64) (* // UserMigrationArchiveURL gets the URL for a specific migration archive. // id is the migration ID. // -// GitHub API docs: https://developer.github.com/v3/migrations/users/#download-a-user-migration-archive +// GitHub API docs: https://docs.github.com/en/rest/reference/migrations/#download-a-user-migration-archive func (s *MigrationService) UserMigrationArchiveURL(ctx context.Context, id int64) (string, error) { url := fmt.Sprintf("user/migrations/%v/archive", id) @@ -178,7 +178,7 @@ func (s *MigrationService) UserMigrationArchiveURL(ctx context.Context, id int64 // DeleteUserMigration will delete a previous migration archive. // id is the migration ID. // -// GitHub API docs: https://developer.github.com/v3/migrations/users/#delete-a-user-migration-archive +// GitHub API docs: https://docs.github.com/en/rest/reference/migrations/#delete-a-user-migration-archive func (s *MigrationService) DeleteUserMigration(ctx context.Context, id int64) (*Response, error) { url := fmt.Sprintf("user/migrations/%v/archive", id) @@ -198,7 +198,7 @@ func (s *MigrationService) DeleteUserMigration(ctx context.Context, id int64) (* // You should unlock each migrated repository and delete them when the migration // is complete and you no longer need the source data. // -// GitHub API docs: https://developer.github.com/v3/migrations/users/#unlock-a-user-repository +// GitHub API docs: https://docs.github.com/en/rest/reference/migrations/#unlock-a-user-repository func (s *MigrationService) UnlockUserRepo(ctx context.Context, id int64, repo string) (*Response, error) { url := fmt.Sprintf("user/migrations/%v/repos/%v/lock", id, repo) diff --git a/github/misc.go b/github/misc.go index 139a0dc66a9..643d0f236f2 100644 --- a/github/misc.go +++ b/github/misc.go @@ -39,7 +39,7 @@ type markdownRequest struct { // Markdown renders an arbitrary Markdown document. // -// GitHub API docs: https://developer.github.com/v3/markdown/ +// GitHub API docs: https://docs.github.com/en/rest/reference/markdown/ func (c *Client) Markdown(ctx context.Context, text string, opts *MarkdownOptions) (string, *Response, error) { request := &markdownRequest{Text: String(text)} if opts != nil { @@ -67,7 +67,7 @@ func (c *Client) Markdown(ctx context.Context, text string, opts *MarkdownOption // ListEmojis returns the emojis available to use on GitHub. // -// GitHub API docs: https://developer.github.com/v3/emojis/ +// GitHub API docs: https://docs.github.com/en/rest/reference/emojis/ func (c *Client) ListEmojis(ctx context.Context) (map[string]string, *Response, error) { req, err := c.NewRequest("GET", "emojis", nil) if err != nil { @@ -97,7 +97,7 @@ func (c *CodeOfConduct) String() string { // ListCodesOfConduct returns all codes of conduct. // -// GitHub API docs: https://developer.github.com/v3/codes_of_conduct/#list-all-codes-of-conduct +// GitHub API docs: https://docs.github.com/en/rest/reference/codes_of_conduct/#list-all-codes-of-conduct func (c *Client) ListCodesOfConduct(ctx context.Context) ([]*CodeOfConduct, *Response, error) { req, err := c.NewRequest("GET", "codes_of_conduct", nil) if err != nil { @@ -118,7 +118,7 @@ func (c *Client) ListCodesOfConduct(ctx context.Context) ([]*CodeOfConduct, *Res // GetCodeOfConduct returns an individual code of conduct. // -// https://developer.github.com/v3/codes_of_conduct/#get-an-individual-code-of-conduct +// https://docs.github.com/en/rest/reference/codes_of_conduct/#get-an-individual-code-of-conduct func (c *Client) GetCodeOfConduct(ctx context.Context, key string) (*CodeOfConduct, *Response, error) { u := fmt.Sprintf("codes_of_conduct/%s", key) req, err := c.NewRequest("GET", u, nil) @@ -168,7 +168,7 @@ type APIMeta struct { // this endpoint on your organization’s GitHub Enterprise installation, this // endpoint provides information about that installation. // -// GitHub API docs: https://developer.github.com/v3/meta/ +// GitHub API docs: https://docs.github.com/en/rest/reference/meta/ func (c *Client) APIMeta(ctx context.Context) (*APIMeta, *Response, error) { req, err := c.NewRequest("GET", "meta", nil) if err != nil { diff --git a/github/orgs.go b/github/orgs.go index 4fd6bbd5097..8dea1d5c2f4 100644 --- a/github/orgs.go +++ b/github/orgs.go @@ -14,7 +14,7 @@ import ( // OrganizationsService provides access to the organization related functions // in the GitHub API. // -// GitHub API docs: https://developer.github.com/v3/orgs/ +// GitHub API docs: https://docs.github.com/en/rest/reference/orgs/ type OrganizationsService service // Organization represents a GitHub organization account. @@ -125,7 +125,7 @@ type OrganizationsListOptions struct { // listing the next set of organizations, use the ID of the last-returned organization // as the opts.Since parameter for the next call. // -// GitHub API docs: https://developer.github.com/v3/orgs/#list-organizations +// GitHub API docs: https://docs.github.com/en/rest/reference/orgs/#list-organizations func (s *OrganizationsService) ListAll(ctx context.Context, opts *OrganizationsListOptions) ([]*Organization, *Response, error) { u, err := addOptions("organizations", opts) if err != nil { @@ -148,8 +148,8 @@ func (s *OrganizationsService) ListAll(ctx context.Context, opts *OrganizationsL // List the organizations for a user. Passing the empty string will list // organizations for the authenticated user. // -// GitHub API docs: https://developer.github.com/v3/orgs/#oauth-scope-requirements -// GitHub API docs: https://developer.github.com/v3/orgs/#list-organizations-for-a-user +// GitHub API docs: https://docs.github.com/en/rest/reference/orgs/#list-organizations-for-the-authenticated-user +// GitHub API docs: https://docs.github.com/en/rest/reference/orgs/#list-organizations-for-a-user func (s *OrganizationsService) List(ctx context.Context, user string, opts *ListOptions) ([]*Organization, *Response, error) { var u string if user != "" { @@ -178,7 +178,7 @@ func (s *OrganizationsService) List(ctx context.Context, user string, opts *List // Get fetches an organization by name. // -// GitHub API docs: https://developer.github.com/v3/orgs/#get-an-organization +// GitHub API docs: https://docs.github.com/en/rest/reference/orgs/#get-an-organization func (s *OrganizationsService) Get(ctx context.Context, org string) (*Organization, *Response, error) { u := fmt.Sprintf("orgs/%v", org) req, err := s.client.NewRequest("GET", u, nil) @@ -219,7 +219,7 @@ func (s *OrganizationsService) GetByID(ctx context.Context, id int64) (*Organiza // Edit an organization. // -// GitHub API docs: https://developer.github.com/v3/orgs/#members_can_create_repositories +// GitHub API docs: https://docs.github.com/en/rest/reference/orgs/#update-an-organization func (s *OrganizationsService) Edit(ctx context.Context, name string, org *Organization) (*Organization, *Response, error) { u := fmt.Sprintf("orgs/%v", name) req, err := s.client.NewRequest("PATCH", u, org) @@ -241,7 +241,7 @@ func (s *OrganizationsService) Edit(ctx context.Context, name string, org *Organ // ListInstallations lists installations for an organization. // -// GitHub API docs: https://developer.github.com/v3/orgs/#list-app-installations-for-an-organization +// GitHub API docs: https://docs.github.com/en/rest/reference/orgs/#list-app-installations-for-an-organization func (s *OrganizationsService) ListInstallations(ctx context.Context, org string, opts *ListOptions) (*OrganizationInstallations, *Response, error) { u := fmt.Sprintf("orgs/%v/installations", org) diff --git a/github/orgs_hooks.go b/github/orgs_hooks.go index a3a5f8df46c..add2b7270a4 100644 --- a/github/orgs_hooks.go +++ b/github/orgs_hooks.go @@ -12,7 +12,7 @@ import ( // ListHooks lists all Hooks for the specified organization. // -// GitHub API docs: https://developer.github.com/v3/orgs/hooks/#list-organization-webhooks +// GitHub API docs: https://docs.github.com/en/rest/reference/orgs/#list-organization-webhooks func (s *OrganizationsService) ListHooks(ctx context.Context, org string, opts *ListOptions) ([]*Hook, *Response, error) { u := fmt.Sprintf("orgs/%v/hooks", org) u, err := addOptions(u, opts) @@ -36,7 +36,7 @@ func (s *OrganizationsService) ListHooks(ctx context.Context, org string, opts * // GetHook returns a single specified Hook. // -// GitHub API docs: https://developer.github.com/v3/orgs/hooks/#get-an-organization-webhook +// GitHub API docs: https://docs.github.com/en/rest/reference/orgs/#get-an-organization-webhook func (s *OrganizationsService) GetHook(ctx context.Context, org string, id int64) (*Hook, *Response, error) { u := fmt.Sprintf("orgs/%v/hooks/%d", org, id) req, err := s.client.NewRequest("GET", u, nil) @@ -54,7 +54,7 @@ func (s *OrganizationsService) GetHook(ctx context.Context, org string, id int64 // Note that only a subset of the hook fields are used and hook must // not be nil. // -// GitHub API docs: https://developer.github.com/v3/orgs/hooks/#create-an-organization-webhook +// GitHub API docs: https://docs.github.com/en/rest/reference/orgs/#create-an-organization-webhook func (s *OrganizationsService) CreateHook(ctx context.Context, org string, hook *Hook) (*Hook, *Response, error) { u := fmt.Sprintf("orgs/%v/hooks", org) @@ -81,7 +81,7 @@ func (s *OrganizationsService) CreateHook(ctx context.Context, org string, hook // EditHook updates a specified Hook. // -// GitHub API docs: https://developer.github.com/v3/orgs/hooks/#update-an-organization-webhook +// GitHub API docs: https://docs.github.com/en/rest/reference/orgs/#update-an-organization-webhook func (s *OrganizationsService) EditHook(ctx context.Context, org string, id int64, hook *Hook) (*Hook, *Response, error) { u := fmt.Sprintf("orgs/%v/hooks/%d", org, id) req, err := s.client.NewRequest("PATCH", u, hook) @@ -95,7 +95,7 @@ func (s *OrganizationsService) EditHook(ctx context.Context, org string, id int6 // PingHook triggers a 'ping' event to be sent to the Hook. // -// GitHub API docs: https://developer.github.com/v3/orgs/hooks/#ping-an-organization-webhook +// GitHub API docs: https://docs.github.com/en/rest/reference/orgs/#ping-an-organization-webhook func (s *OrganizationsService) PingHook(ctx context.Context, org string, id int64) (*Response, error) { u := fmt.Sprintf("orgs/%v/hooks/%d/pings", org, id) req, err := s.client.NewRequest("POST", u, nil) @@ -107,7 +107,7 @@ func (s *OrganizationsService) PingHook(ctx context.Context, org string, id int6 // DeleteHook deletes a specified Hook. // -// GitHub API docs: https://developer.github.com/v3/orgs/hooks/#delete-an-organization-webhook +// GitHub API docs: https://docs.github.com/en/rest/reference/orgs/#delete-an-organization-webhook func (s *OrganizationsService) DeleteHook(ctx context.Context, org string, id int64) (*Response, error) { u := fmt.Sprintf("orgs/%v/hooks/%d", org, id) req, err := s.client.NewRequest("DELETE", u, nil) diff --git a/github/orgs_members.go b/github/orgs_members.go index e388a4c6ede..783f789702e 100644 --- a/github/orgs_members.go +++ b/github/orgs_members.go @@ -71,8 +71,8 @@ type ListMembersOptions struct { // user is an owner of the organization, this will return both concealed and // public members, otherwise it will only return public members. // -// GitHub API docs: https://developer.github.com/v3/orgs/members/#list-organization-members -// GitHub API docs: https://developer.github.com/v3/orgs/members/#list-public-organization-members +// GitHub API docs: https://docs.github.com/en/rest/reference/orgs/#list-organization-members +// GitHub API docs: https://docs.github.com/en/rest/reference/orgs/#list-public-organization-members func (s *OrganizationsService) ListMembers(ctx context.Context, org string, opts *ListMembersOptions) ([]*User, *Response, error) { var u string if opts != nil && opts.PublicOnly { @@ -101,7 +101,7 @@ func (s *OrganizationsService) ListMembers(ctx context.Context, org string, opts // IsMember checks if a user is a member of an organization. // -// GitHub API docs: https://developer.github.com/v3/orgs/members/#check-organization-membership-for-a-user +// GitHub API docs: https://docs.github.com/en/rest/reference/orgs/#check-organization-membership-for-a-user func (s *OrganizationsService) IsMember(ctx context.Context, org, user string) (bool, *Response, error) { u := fmt.Sprintf("orgs/%v/members/%v", org, user) req, err := s.client.NewRequest("GET", u, nil) @@ -116,7 +116,7 @@ func (s *OrganizationsService) IsMember(ctx context.Context, org, user string) ( // IsPublicMember checks if a user is a public member of an organization. // -// GitHub API docs: https://developer.github.com/v3/orgs/members/#check-public-organization-membership-for-a-user +// GitHub API docs: https://docs.github.com/en/rest/reference/orgs/#check-public-organization-membership-for-a-user func (s *OrganizationsService) IsPublicMember(ctx context.Context, org, user string) (bool, *Response, error) { u := fmt.Sprintf("orgs/%v/public_members/%v", org, user) req, err := s.client.NewRequest("GET", u, nil) @@ -131,7 +131,7 @@ func (s *OrganizationsService) IsPublicMember(ctx context.Context, org, user str // RemoveMember removes a user from all teams of an organization. // -// GitHub API docs: https://developer.github.com/v3/orgs/members/#remove-an-organization-member +// GitHub API docs: https://docs.github.com/en/rest/reference/orgs/#remove-an-organization-member func (s *OrganizationsService) RemoveMember(ctx context.Context, org, user string) (*Response, error) { u := fmt.Sprintf("orgs/%v/members/%v", org, user) req, err := s.client.NewRequest("DELETE", u, nil) @@ -145,7 +145,7 @@ func (s *OrganizationsService) RemoveMember(ctx context.Context, org, user strin // PublicizeMembership publicizes a user's membership in an organization. (A // user cannot publicize the membership for another user.) // -// GitHub API docs: https://developer.github.com/v3/orgs/members/#set-public-organization-membership-for-the-authenticated-user +// GitHub API docs: https://docs.github.com/en/rest/reference/orgs/#set-public-organization-membership-for-the-authenticated-user func (s *OrganizationsService) PublicizeMembership(ctx context.Context, org, user string) (*Response, error) { u := fmt.Sprintf("orgs/%v/public_members/%v", org, user) req, err := s.client.NewRequest("PUT", u, nil) @@ -158,7 +158,7 @@ func (s *OrganizationsService) PublicizeMembership(ctx context.Context, org, use // ConcealMembership conceals a user's membership in an organization. // -// GitHub API docs: https://developer.github.com/v3/orgs/members/#remove-public-organization-membership-for-the-authenticated-user +// GitHub API docs: https://docs.github.com/en/rest/reference/orgs/#remove-public-organization-membership-for-the-authenticated-user func (s *OrganizationsService) ConcealMembership(ctx context.Context, org, user string) (*Response, error) { u := fmt.Sprintf("orgs/%v/public_members/%v", org, user) req, err := s.client.NewRequest("DELETE", u, nil) @@ -181,7 +181,7 @@ type ListOrgMembershipsOptions struct { // ListOrgMemberships lists the organization memberships for the authenticated user. // -// GitHub API docs: https://developer.github.com/v3/orgs/members/#list-organization-memberships-for-the-authenticated-user +// GitHub API docs: https://docs.github.com/en/rest/reference/orgs/#list-organization-memberships-for-the-authenticated-user func (s *OrganizationsService) ListOrgMemberships(ctx context.Context, opts *ListOrgMembershipsOptions) ([]*Membership, *Response, error) { u := "user/memberships/orgs" u, err := addOptions(u, opts) @@ -207,8 +207,8 @@ func (s *OrganizationsService) ListOrgMemberships(ctx context.Context, opts *Lis // Passing an empty string for user will get the membership for the // authenticated user. // -// GitHub API docs: https://developer.github.com/v3/orgs/members/#get-an-organization-membership-for-the-authenticated-user -// GitHub API docs: https://developer.github.com/v3/orgs/members/#get-organization-membership-for-a-user +// GitHub API docs: https://docs.github.com/en/rest/reference/orgs/#get-an-organization-membership-for-the-authenticated-user +// GitHub API docs: https://docs.github.com/en/rest/reference/orgs/#get-organization-membership-for-a-user func (s *OrganizationsService) GetOrgMembership(ctx context.Context, user, org string) (*Membership, *Response, error) { var u string if user != "" { @@ -235,8 +235,8 @@ func (s *OrganizationsService) GetOrgMembership(ctx context.Context, user, org s // Passing an empty string for user will edit the membership for the // authenticated user. // -// GitHub API docs: https://developer.github.com/v3/orgs/members/#update-an-organization-membership-for-the-authenticated-user -// GitHub API docs: https://developer.github.com/v3/orgs/members/#set-organization-membership-for-a-user +// GitHub API docs: https://docs.github.com/en/rest/reference/orgs/#update-an-organization-membership-for-the-authenticated-user +// GitHub API docs: https://docs.github.com/en/rest/reference/orgs/#set-organization-membership-for-a-user func (s *OrganizationsService) EditOrgMembership(ctx context.Context, user, org string, membership *Membership) (*Membership, *Response, error) { var u, method string if user != "" { @@ -264,7 +264,7 @@ func (s *OrganizationsService) EditOrgMembership(ctx context.Context, user, org // RemoveOrgMembership removes user from the specified organization. If the // user has been invited to the organization, this will cancel their invitation. // -// GitHub API docs: https://developer.github.com/v3/orgs/members/#remove-organization-membership-for-a-user +// GitHub API docs: https://docs.github.com/en/rest/reference/orgs/#remove-organization-membership-for-a-user func (s *OrganizationsService) RemoveOrgMembership(ctx context.Context, user, org string) (*Response, error) { u := fmt.Sprintf("orgs/%v/memberships/%v", org, user) req, err := s.client.NewRequest("DELETE", u, nil) @@ -277,7 +277,7 @@ func (s *OrganizationsService) RemoveOrgMembership(ctx context.Context, user, or // ListPendingOrgInvitations returns a list of pending invitations. // -// GitHub API docs: https://developer.github.com/v3/orgs/members/#list-pending-organization-invitations +// GitHub API docs: https://docs.github.com/en/rest/reference/orgs/#list-pending-organization-invitations func (s *OrganizationsService) ListPendingOrgInvitations(ctx context.Context, org string, opts *ListOptions) ([]*Invitation, *Response, error) { u := fmt.Sprintf("orgs/%v/invitations", org) u, err := addOptions(u, opts) @@ -322,7 +322,7 @@ type CreateOrgInvitationOptions struct { // In order to create invitations in an organization, // the authenticated user must be an organization owner. // -// GitHub API docs: https://developer.github.com/v3/orgs/members/#create-an-organization-invitation +// GitHub API docs: https://docs.github.com/en/rest/reference/orgs/#create-an-organization-invitation func (s *OrganizationsService) CreateOrgInvitation(ctx context.Context, org string, opts *CreateOrgInvitationOptions) (*Invitation, *Response, error) { u := fmt.Sprintf("orgs/%v/invitations", org) @@ -342,7 +342,7 @@ func (s *OrganizationsService) CreateOrgInvitation(ctx context.Context, org stri // ListOrgInvitationTeams lists all teams associated with an invitation. In order to see invitations in an organization, // the authenticated user must be an organization owner. // -// GitHub API docs: https://developer.github.com/v3/orgs/members/#list-organization-invitation-teams +// GitHub API docs: https://docs.github.com/en/rest/reference/orgs/#list-organization-invitation-teams func (s *OrganizationsService) ListOrgInvitationTeams(ctx context.Context, org, invitationID string, opts *ListOptions) ([]*Team, *Response, error) { u := fmt.Sprintf("orgs/%v/invitations/%v/teams", org, invitationID) u, err := addOptions(u, opts) diff --git a/github/orgs_outside_collaborators.go b/github/orgs_outside_collaborators.go index 4dc3912ac71..9a9ae332e0d 100644 --- a/github/orgs_outside_collaborators.go +++ b/github/orgs_outside_collaborators.go @@ -27,7 +27,7 @@ type ListOutsideCollaboratorsOptions struct { // Warning: The API may change without advance notice during the preview period. // Preview features are not supported for production use. // -// GitHub API docs: https://developer.github.com/v3/orgs/outside_collaborators/#list-outside-collaborators-for-an-organization +// GitHub API docs: https://docs.github.com/en/rest/reference/orgs/#list-outside-collaborators-for-an-organization func (s *OrganizationsService) ListOutsideCollaborators(ctx context.Context, org string, opts *ListOutsideCollaboratorsOptions) ([]*User, *Response, error) { u := fmt.Sprintf("orgs/%v/outside_collaborators", org) u, err := addOptions(u, opts) @@ -52,7 +52,7 @@ func (s *OrganizationsService) ListOutsideCollaborators(ctx context.Context, org // RemoveOutsideCollaborator removes a user from the list of outside collaborators; // consequently, removing them from all the organization's repositories. // -// GitHub API docs: https://developer.github.com/v3/orgs/outside_collaborators/#remove-outside-collaborator-from-an-organization +// GitHub API docs: https://docs.github.com/en/rest/reference/orgs/#remove-outside-collaborator-from-an-organization func (s *OrganizationsService) RemoveOutsideCollaborator(ctx context.Context, org string, user string) (*Response, error) { u := fmt.Sprintf("orgs/%v/outside_collaborators/%v", org, user) req, err := s.client.NewRequest("DELETE", u, nil) @@ -69,7 +69,7 @@ func (s *OrganizationsService) RemoveOutsideCollaborator(ctx context.Context, or // Responses for converting a non-member or the last owner to an outside collaborator // are listed in GitHub API docs. // -// GitHub API docs: https://developer.github.com/v3/orgs/outside_collaborators/#convert-an-organization-member-to-outside-collaborator +// GitHub API docs: https://docs.github.com/en/rest/reference/orgs/#convert-an-organization-member-to-outside-collaborator func (s *OrganizationsService) ConvertMemberToOutsideCollaborator(ctx context.Context, org string, user string) (*Response, error) { u := fmt.Sprintf("orgs/%v/outside_collaborators/%v", org, user) req, err := s.client.NewRequest("PUT", u, nil) diff --git a/github/orgs_projects.go b/github/orgs_projects.go index cc3ed3b1bb6..2015ca29eda 100644 --- a/github/orgs_projects.go +++ b/github/orgs_projects.go @@ -12,7 +12,7 @@ import ( // ListProjects lists the projects for an organization. // -// GitHub API docs: https://developer.github.com/v3/projects/#list-organization-projects +// GitHub API docs: https://docs.github.com/en/rest/reference/projects/#list-organization-projects func (s *OrganizationsService) ListProjects(ctx context.Context, org string, opts *ProjectListOptions) ([]*Project, *Response, error) { u := fmt.Sprintf("orgs/%v/projects", org) u, err := addOptions(u, opts) @@ -39,7 +39,7 @@ func (s *OrganizationsService) ListProjects(ctx context.Context, org string, opt // CreateProject creates a GitHub Project for the specified organization. // -// GitHub API docs: https://developer.github.com/v3/projects/#create-an-organization-project +// GitHub API docs: https://docs.github.com/en/rest/reference/projects/#create-an-organization-project func (s *OrganizationsService) CreateProject(ctx context.Context, org string, opts *ProjectOptions) (*Project, *Response, error) { u := fmt.Sprintf("orgs/%v/projects", org) req, err := s.client.NewRequest("POST", u, opts) diff --git a/github/orgs_users_blocking.go b/github/orgs_users_blocking.go index 7795d781ad9..2bc9445115a 100644 --- a/github/orgs_users_blocking.go +++ b/github/orgs_users_blocking.go @@ -12,7 +12,7 @@ import ( // ListBlockedUsers lists all the users blocked by an organization. // -// GitHub API docs: https://developer.github.com/v3/orgs/blocking/#list-users-blocked-by-an-organization +// GitHub API docs: https://docs.github.com/en/rest/reference/orgs/#list-users-blocked-by-an-organization func (s *OrganizationsService) ListBlockedUsers(ctx context.Context, org string, opts *ListOptions) ([]*User, *Response, error) { u := fmt.Sprintf("orgs/%v/blocks", org) u, err := addOptions(u, opts) @@ -39,7 +39,7 @@ func (s *OrganizationsService) ListBlockedUsers(ctx context.Context, org string, // IsBlocked reports whether specified user is blocked from an organization. // -// GitHub API docs: https://developer.github.com/v3/orgs/blocking/#check-if-a-user-is-blocked-by-an-organization +// GitHub API docs: https://docs.github.com/en/rest/reference/orgs/#check-if-a-user-is-blocked-by-an-organization func (s *OrganizationsService) IsBlocked(ctx context.Context, org string, user string) (bool, *Response, error) { u := fmt.Sprintf("orgs/%v/blocks/%v", org, user) @@ -58,7 +58,7 @@ func (s *OrganizationsService) IsBlocked(ctx context.Context, org string, user s // BlockUser blocks specified user from an organization. // -// GitHub API docs: https://developer.github.com/v3/orgs/blocking/#block-a-user-from-an-organization +// GitHub API docs: https://docs.github.com/en/rest/reference/orgs/#block-a-user-from-an-organization func (s *OrganizationsService) BlockUser(ctx context.Context, org string, user string) (*Response, error) { u := fmt.Sprintf("orgs/%v/blocks/%v", org, user) @@ -75,7 +75,7 @@ func (s *OrganizationsService) BlockUser(ctx context.Context, org string, user s // UnblockUser unblocks specified user from an organization. // -// GitHub API docs: https://developer.github.com/v3/orgs/blocking/#unblock-a-user-from-an-organization +// GitHub API docs: https://docs.github.com/en/rest/reference/orgs/#unblock-a-user-from-an-organization func (s *OrganizationsService) UnblockUser(ctx context.Context, org string, user string) (*Response, error) { u := fmt.Sprintf("orgs/%v/blocks/%v", org, user) diff --git a/github/projects.go b/github/projects.go index 1a4d8443cd3..414ea636f49 100644 --- a/github/projects.go +++ b/github/projects.go @@ -13,7 +13,7 @@ import ( // ProjectsService provides access to the projects functions in the // GitHub API. // -// GitHub API docs: https://developer.github.com/v3/projects/ +// GitHub API docs: https://docs.github.com/en/rest/reference/projects/ type ProjectsService service // Project represents a GitHub Project. @@ -41,7 +41,7 @@ func (p Project) String() string { // GetProject gets a GitHub Project for a repo. // -// GitHub API docs: https://developer.github.com/v3/projects/#get-a-project +// GitHub API docs: https://docs.github.com/en/rest/reference/projects/#get-a-project func (s *ProjectsService) GetProject(ctx context.Context, id int64) (*Project, *Response, error) { u := fmt.Sprintf("projects/%v", id) req, err := s.client.NewRequest("GET", u, nil) @@ -88,7 +88,7 @@ type ProjectOptions struct { // UpdateProject updates a repository project. // -// GitHub API docs: https://developer.github.com/v3/projects/#update-a-project +// GitHub API docs: https://docs.github.com/en/rest/reference/projects/#update-a-project func (s *ProjectsService) UpdateProject(ctx context.Context, id int64, opts *ProjectOptions) (*Project, *Response, error) { u := fmt.Sprintf("projects/%v", id) req, err := s.client.NewRequest("PATCH", u, opts) @@ -110,7 +110,7 @@ func (s *ProjectsService) UpdateProject(ctx context.Context, id int64, opts *Pro // DeleteProject deletes a GitHub Project from a repository. // -// GitHub API docs: https://developer.github.com/v3/projects/#delete-a-project +// GitHub API docs: https://docs.github.com/en/rest/reference/projects/#delete-a-project func (s *ProjectsService) DeleteProject(ctx context.Context, id int64) (*Response, error) { u := fmt.Sprintf("projects/%v", id) req, err := s.client.NewRequest("DELETE", u, nil) @@ -126,7 +126,7 @@ func (s *ProjectsService) DeleteProject(ctx context.Context, id int64) (*Respons // ProjectColumn represents a column of a GitHub Project. // -// GitHub API docs: https://developer.github.com/v3/repos/projects/ +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/projects/ type ProjectColumn struct { ID *int64 `json:"id,omitempty"` Name *string `json:"name,omitempty"` @@ -140,7 +140,7 @@ type ProjectColumn struct { // ListProjectColumns lists the columns of a GitHub Project for a repo. // -// GitHub API docs: https://developer.github.com/v3/projects/columns/#list-project-columns +// GitHub API docs: https://docs.github.com/en/rest/reference/projects/#list-project-columns func (s *ProjectsService) ListProjectColumns(ctx context.Context, projectID int64, opts *ListOptions) ([]*ProjectColumn, *Response, error) { u := fmt.Sprintf("projects/%v/columns", projectID) u, err := addOptions(u, opts) @@ -167,7 +167,7 @@ func (s *ProjectsService) ListProjectColumns(ctx context.Context, projectID int6 // GetProjectColumn gets a column of a GitHub Project for a repo. // -// GitHub API docs: https://developer.github.com/v3/projects/columns/#get-a-project-column +// GitHub API docs: https://docs.github.com/en/rest/reference/projects/#get-a-project-column func (s *ProjectsService) GetProjectColumn(ctx context.Context, id int64) (*ProjectColumn, *Response, error) { u := fmt.Sprintf("projects/columns/%v", id) req, err := s.client.NewRequest("GET", u, nil) @@ -197,7 +197,7 @@ type ProjectColumnOptions struct { // CreateProjectColumn creates a column for the specified (by number) project. // -// GitHub API docs: https://developer.github.com/v3/projects/columns/#create-a-project-column +// GitHub API docs: https://docs.github.com/en/rest/reference/projects/#create-a-project-column func (s *ProjectsService) CreateProjectColumn(ctx context.Context, projectID int64, opts *ProjectColumnOptions) (*ProjectColumn, *Response, error) { u := fmt.Sprintf("projects/%v/columns", projectID) req, err := s.client.NewRequest("POST", u, opts) @@ -219,7 +219,7 @@ func (s *ProjectsService) CreateProjectColumn(ctx context.Context, projectID int // UpdateProjectColumn updates a column of a GitHub Project. // -// GitHub API docs: https://developer.github.com/v3/projects/columns/#update-a-project-column +// GitHub API docs: https://docs.github.com/en/rest/reference/projects/#update-a-project-column func (s *ProjectsService) UpdateProjectColumn(ctx context.Context, columnID int64, opts *ProjectColumnOptions) (*ProjectColumn, *Response, error) { u := fmt.Sprintf("projects/columns/%v", columnID) req, err := s.client.NewRequest("PATCH", u, opts) @@ -241,7 +241,7 @@ func (s *ProjectsService) UpdateProjectColumn(ctx context.Context, columnID int6 // DeleteProjectColumn deletes a column from a GitHub Project. // -// GitHub API docs: https://developer.github.com/v3/projects/columns/#delete-a-project-column +// GitHub API docs: https://docs.github.com/en/rest/reference/projects/#delete-a-project-column func (s *ProjectsService) DeleteProjectColumn(ctx context.Context, columnID int64) (*Response, error) { u := fmt.Sprintf("projects/columns/%v", columnID) req, err := s.client.NewRequest("DELETE", u, nil) @@ -265,7 +265,7 @@ type ProjectColumnMoveOptions struct { // MoveProjectColumn moves a column within a GitHub Project. // -// GitHub API docs: https://developer.github.com/v3/projects/columns/#move-a-project-column +// GitHub API docs: https://docs.github.com/en/rest/reference/projects/#move-a-project-column func (s *ProjectsService) MoveProjectColumn(ctx context.Context, columnID int64, opts *ProjectColumnMoveOptions) (*Response, error) { u := fmt.Sprintf("projects/columns/%v/moves", columnID) req, err := s.client.NewRequest("POST", u, opts) @@ -281,7 +281,7 @@ func (s *ProjectsService) MoveProjectColumn(ctx context.Context, columnID int64, // ProjectCard represents a card in a column of a GitHub Project. // -// GitHub API docs: https://developer.github.com/v3/projects/cards/#get-a-project-card +// GitHub API docs: https://docs.github.com/en/rest/reference/projects/cards/#get-a-project-card type ProjectCard struct { URL *string `json:"url,omitempty"` ColumnURL *string `json:"column_url,omitempty"` @@ -316,7 +316,7 @@ type ProjectCardListOptions struct { // ListProjectCards lists the cards in a column of a GitHub Project. // -// GitHub API docs: https://developer.github.com/v3/projects/cards/#list-project-cards +// GitHub API docs: https://docs.github.com/en/rest/reference/projects/#list-project-cards func (s *ProjectsService) ListProjectCards(ctx context.Context, columnID int64, opts *ProjectCardListOptions) ([]*ProjectCard, *Response, error) { u := fmt.Sprintf("projects/columns/%v/cards", columnID) u, err := addOptions(u, opts) @@ -343,7 +343,7 @@ func (s *ProjectsService) ListProjectCards(ctx context.Context, columnID int64, // GetProjectCard gets a card in a column of a GitHub Project. // -// GitHub API docs: https://developer.github.com/v3/projects/cards/#get-a-project-card +// GitHub API docs: https://docs.github.com/en/rest/reference/projects/#get-a-project-card func (s *ProjectsService) GetProjectCard(ctx context.Context, cardID int64) (*ProjectCard, *Response, error) { u := fmt.Sprintf("projects/columns/cards/%v", cardID) req, err := s.client.NewRequest("GET", u, nil) @@ -381,7 +381,7 @@ type ProjectCardOptions struct { // CreateProjectCard creates a card in the specified column of a GitHub Project. // -// GitHub API docs: https://developer.github.com/v3/projects/cards/#create-a-project-card +// GitHub API docs: https://docs.github.com/en/rest/reference/projects/#create-a-project-card func (s *ProjectsService) CreateProjectCard(ctx context.Context, columnID int64, opts *ProjectCardOptions) (*ProjectCard, *Response, error) { u := fmt.Sprintf("projects/columns/%v/cards", columnID) req, err := s.client.NewRequest("POST", u, opts) @@ -403,7 +403,7 @@ func (s *ProjectsService) CreateProjectCard(ctx context.Context, columnID int64, // UpdateProjectCard updates a card of a GitHub Project. // -// GitHub API docs: https://developer.github.com/v3/projects/cards/#update-a-project-card +// GitHub API docs: https://docs.github.com/en/rest/reference/projects/#update-a-project-card func (s *ProjectsService) UpdateProjectCard(ctx context.Context, cardID int64, opts *ProjectCardOptions) (*ProjectCard, *Response, error) { u := fmt.Sprintf("projects/columns/cards/%v", cardID) req, err := s.client.NewRequest("PATCH", u, opts) @@ -425,7 +425,7 @@ func (s *ProjectsService) UpdateProjectCard(ctx context.Context, cardID int64, o // DeleteProjectCard deletes a card from a GitHub Project. // -// GitHub API docs: https://developer.github.com/v3/projects/cards/#delete-a-project-card +// GitHub API docs: https://docs.github.com/en/rest/reference/projects/#delete-a-project-card func (s *ProjectsService) DeleteProjectCard(ctx context.Context, cardID int64) (*Response, error) { u := fmt.Sprintf("projects/columns/cards/%v", cardID) req, err := s.client.NewRequest("DELETE", u, nil) @@ -453,7 +453,7 @@ type ProjectCardMoveOptions struct { // MoveProjectCard moves a card within a GitHub Project. // -// GitHub API docs: https://developer.github.com/v3/projects/cards/#move-a-project-card +// GitHub API docs: https://docs.github.com/en/rest/reference/projects/#move-a-project-card func (s *ProjectsService) MoveProjectCard(ctx context.Context, cardID int64, opts *ProjectCardMoveOptions) (*Response, error) { u := fmt.Sprintf("projects/columns/cards/%v/moves", cardID) req, err := s.client.NewRequest("POST", u, opts) @@ -483,7 +483,7 @@ type ProjectCollaboratorOptions struct { // AddProjectCollaborator adds a collaborator to an organization project and sets // their permission level. You must be an organization owner or a project admin to add a collaborator. // -// GitHub API docs: https://developer.github.com/v3/projects/collaborators/#add-project-collaborator +// GitHub API docs: https://docs.github.com/en/rest/reference/projects/#add-project-collaborator func (s *ProjectsService) AddProjectCollaborator(ctx context.Context, id int64, username string, opts *ProjectCollaboratorOptions) (*Response, error) { u := fmt.Sprintf("projects/%v/collaborators/%v", id, username) req, err := s.client.NewRequest("PUT", u, opts) @@ -500,7 +500,7 @@ func (s *ProjectsService) AddProjectCollaborator(ctx context.Context, id int64, // RemoveProjectCollaborator removes a collaborator from an organization project. // You must be an organization owner or a project admin to remove a collaborator. // -// GitHub API docs: https://developer.github.com/v3/projects/collaborators/#remove-project-collaborator +// GitHub API docs: https://docs.github.com/en/rest/reference/projects/#remove-project-collaborator func (s *ProjectsService) RemoveProjectCollaborator(ctx context.Context, id int64, username string) (*Response, error) { u := fmt.Sprintf("projects/%v/collaborators/%v", id, username) req, err := s.client.NewRequest("DELETE", u, nil) @@ -536,7 +536,7 @@ type ListCollaboratorOptions struct { // with access through default organization permissions, and organization owners. You must be an // organization owner or a project admin to list collaborators. // -// GitHub API docs: https://developer.github.com/v3/projects/collaborators/#list-project-collaborators +// GitHub API docs: https://docs.github.com/en/rest/reference/projects/#list-project-collaborators func (s *ProjectsService) ListProjectCollaborators(ctx context.Context, id int64, opts *ListCollaboratorOptions) ([]*User, *Response, error) { u := fmt.Sprintf("projects/%v/collaborators", id) u, err := addOptions(u, opts) @@ -574,7 +574,7 @@ type ProjectPermissionLevel struct { // project. Possible values for the permission key: "admin", "write", "read", "none". // You must be an organization owner or a project admin to review a user's permission level. // -// GitHub API docs: https://developer.github.com/v3/projects/collaborators/#get-project-permission-for-a-user +// GitHub API docs: https://docs.github.com/en/rest/reference/projects/#get-project-permission-for-a-user func (s *ProjectsService) ReviewProjectCollaboratorPermission(ctx context.Context, id int64, username string) (*ProjectPermissionLevel, *Response, error) { u := fmt.Sprintf("projects/%v/collaborators/%v/permission", id, username) req, err := s.client.NewRequest("GET", u, nil) diff --git a/github/pulls.go b/github/pulls.go index b0876d8a2ae..9a20cb2a37f 100644 --- a/github/pulls.go +++ b/github/pulls.go @@ -16,7 +16,7 @@ import ( // PullRequestsService handles communication with the pull request related // methods of the GitHub API. // -// GitHub API docs: https://developer.github.com/v3/pulls/ +// GitHub API docs: https://docs.github.com/en/rest/reference/pulls/ type PullRequestsService service // PullRequest represents a GitHub pull request on a repository. @@ -65,7 +65,7 @@ type PullRequest struct { RequestedReviewers []*User `json:"requested_reviewers,omitempty"` // RequestedTeams is populated as part of the PullRequestEvent. - // See, https://developer.github.com/v3/activity/events/types/#pullrequestevent for an example. + // See, https://docs.github.com/en/rest/reference/activity/events/types/#pullrequestevent for an example. RequestedTeams []*Team `json:"requested_teams,omitempty"` Links *PRLinks `json:"_links,omitempty"` @@ -135,7 +135,7 @@ type PullRequestListOptions struct { // List the pull requests for the specified repository. // -// GitHub API docs: https://developer.github.com/v3/pulls/#list-pull-requests +// GitHub API docs: https://docs.github.com/en/rest/reference/pulls/#list-pull-requests func (s *PullRequestsService) List(ctx context.Context, owner string, repo string, opts *PullRequestListOptions) ([]*PullRequest, *Response, error) { u := fmt.Sprintf("repos/%v/%v/pulls", owner, repo) u, err := addOptions(u, opts) @@ -165,7 +165,7 @@ func (s *PullRequestsService) List(ctx context.Context, owner string, repo strin // // The results will include open and closed pull requests. // -// GitHub API docs: https://developer.github.com/v3/repos/commits/#list-pull-requests-associated-with-a-commit +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#list-pull-requests-associated-with-a-commit func (s *PullRequestsService) ListPullRequestsWithCommit(ctx context.Context, owner, repo, sha string, opts *PullRequestListOptions) ([]*PullRequest, *Response, error) { u := fmt.Sprintf("repos/%v/%v/commits/%v/pulls", owner, repo, sha) u, err := addOptions(u, opts) @@ -192,7 +192,7 @@ func (s *PullRequestsService) ListPullRequestsWithCommit(ctx context.Context, ow // Get a single pull request. // -// GitHub API docs: https://developer.github.com/v3/pulls/#get-a-pull-request +// GitHub API docs: https://docs.github.com/en/rest/reference/pulls/#get-a-pull-request func (s *PullRequestsService) Get(ctx context.Context, owner string, repo string, number int) (*PullRequest, *Response, error) { u := fmt.Sprintf("repos/%v/%v/pulls/%d", owner, repo, number) req, err := s.client.NewRequest("GET", u, nil) @@ -215,7 +215,7 @@ func (s *PullRequestsService) Get(ctx context.Context, owner string, repo string // GetRaw gets a single pull request in raw (diff or patch) format. // -// GitHub API docs: https://developer.github.com/v3/pulls/#get-a-pull-request +// GitHub API docs: https://docs.github.com/en/rest/reference/pulls/#get-a-pull-request func (s *PullRequestsService) GetRaw(ctx context.Context, owner string, repo string, number int, opts RawOptions) (string, *Response, error) { u := fmt.Sprintf("repos/%v/%v/pulls/%d", owner, repo, number) req, err := s.client.NewRequest("GET", u, nil) @@ -254,7 +254,7 @@ type NewPullRequest struct { // Create a new pull request on the specified repository. // -// GitHub API docs: https://developer.github.com/v3/pulls/#create-a-pull-request +// GitHub API docs: https://docs.github.com/en/rest/reference/pulls/#create-a-pull-request func (s *PullRequestsService) Create(ctx context.Context, owner string, repo string, pull *NewPullRequest) (*PullRequest, *Response, error) { u := fmt.Sprintf("repos/%v/%v/pulls", owner, repo) req, err := s.client.NewRequest("POST", u, pull) @@ -293,7 +293,7 @@ type PullRequestBranchUpdateResponse struct { // A follow up request, after a delay of a second or so, should result // in a successful request. // -// GitHub API docs: https://developer.github.com/v3/pulls/#update-a-pull-request-branch +// GitHub API docs: https://docs.github.com/en/rest/reference/pulls/#update-a-pull-request-branch func (s *PullRequestsService) UpdateBranch(ctx context.Context, owner, repo string, number int, opts *PullRequestBranchUpdateOptions) (*PullRequestBranchUpdateResponse, *Response, error) { u := fmt.Sprintf("repos/%v/%v/pulls/%d/update-branch", owner, repo, number) @@ -328,7 +328,7 @@ type pullRequestUpdate struct { // The following fields are editable: Title, Body, State, Base.Ref and MaintainerCanModify. // Base.Ref updates the base branch of the pull request. // -// GitHub API docs: https://developer.github.com/v3/pulls/#update-a-pull-request +// GitHub API docs: https://docs.github.com/en/rest/reference/pulls/#update-a-pull-request func (s *PullRequestsService) Edit(ctx context.Context, owner string, repo string, number int, pull *PullRequest) (*PullRequest, *Response, error) { if pull == nil { return nil, nil, fmt.Errorf("pull must be provided") @@ -369,7 +369,7 @@ func (s *PullRequestsService) Edit(ctx context.Context, owner string, repo strin // ListCommits lists the commits in a pull request. // -// GitHub API docs: https://developer.github.com/v3/pulls/#list-commits-on-a-pull-request +// GitHub API docs: https://docs.github.com/en/rest/reference/pulls/#list-commits-on-a-pull-request func (s *PullRequestsService) ListCommits(ctx context.Context, owner string, repo string, number int, opts *ListOptions) ([]*RepositoryCommit, *Response, error) { u := fmt.Sprintf("repos/%v/%v/pulls/%d/commits", owner, repo, number) u, err := addOptions(u, opts) @@ -393,7 +393,7 @@ func (s *PullRequestsService) ListCommits(ctx context.Context, owner string, rep // ListFiles lists the files in a pull request. // -// GitHub API docs: https://developer.github.com/v3/pulls/#list-pull-requests-files +// GitHub API docs: https://docs.github.com/en/rest/reference/pulls/#list-pull-requests-files func (s *PullRequestsService) ListFiles(ctx context.Context, owner string, repo string, number int, opts *ListOptions) ([]*CommitFile, *Response, error) { u := fmt.Sprintf("repos/%v/%v/pulls/%d/files", owner, repo, number) u, err := addOptions(u, opts) @@ -417,7 +417,7 @@ func (s *PullRequestsService) ListFiles(ctx context.Context, owner string, repo // IsMerged checks if a pull request has been merged. // -// GitHub API docs: https://developer.github.com/v3/pulls/#check-if-a-pull-request-has-been-merged +// GitHub API docs: https://docs.github.com/en/rest/reference/pulls/#check-if-a-pull-request-has-been-merged func (s *PullRequestsService) IsMerged(ctx context.Context, owner string, repo string, number int) (bool, *Response, error) { u := fmt.Sprintf("repos/%v/%v/pulls/%d/merge", owner, repo, number) req, err := s.client.NewRequest("GET", u, nil) @@ -456,7 +456,7 @@ type pullRequestMergeRequest struct { // Merge a pull request. // commitMessage is an extra detail to append to automatic commit message. // -// GitHub API docs: https://developer.github.com/v3/pulls/#merge-a-pull-request +// GitHub API docs: https://docs.github.com/en/rest/reference/pulls/#merge-a-pull-request func (s *PullRequestsService) Merge(ctx context.Context, owner string, repo string, number int, commitMessage string, options *PullRequestOptions) (*PullRequestMergeResult, *Response, error) { u := fmt.Sprintf("repos/%v/%v/pulls/%d/merge", owner, repo, number) diff --git a/github/pulls_comments.go b/github/pulls_comments.go index 13de971b4a1..3de3b2d92c5 100644 --- a/github/pulls_comments.go +++ b/github/pulls_comments.go @@ -66,8 +66,8 @@ type PullRequestListCommentsOptions struct { // pull request number of 0 will return all comments on all pull requests for // the repository. // -// GitHub API docs: https://developer.github.com/v3/pulls/comments/#list-review-comments-on-a-pull-request -// GitHub API docs: https://developer.github.com/v3/pulls/comments/#list-review-comments-in-a-repository +// GitHub API docs: https://docs.github.com/en/rest/reference/pulls/#list-review-comments-on-a-pull-request +// GitHub API docs: https://docs.github.com/en/rest/reference/pulls/#list-review-comments-in-a-repository func (s *PullRequestsService) ListComments(ctx context.Context, owner string, repo string, number int, opts *PullRequestListCommentsOptions) ([]*PullRequestComment, *Response, error) { var u string if number == 0 { @@ -100,7 +100,7 @@ func (s *PullRequestsService) ListComments(ctx context.Context, owner string, re // GetComment fetches the specified pull request comment. // -// GitHub API docs: https://developer.github.com/v3/pulls/comments/#get-a-review-comment-for-a-pull-request +// GitHub API docs: https://docs.github.com/en/rest/reference/pulls/#get-a-review-comment-for-a-pull-request func (s *PullRequestsService) GetComment(ctx context.Context, owner string, repo string, commentID int64) (*PullRequestComment, *Response, error) { u := fmt.Sprintf("repos/%v/%v/pulls/comments/%d", owner, repo, commentID) req, err := s.client.NewRequest("GET", u, nil) @@ -123,7 +123,7 @@ func (s *PullRequestsService) GetComment(ctx context.Context, owner string, repo // CreateComment creates a new comment on the specified pull request. // -// GitHub API docs: https://developer.github.com/v3/pulls/comments/#create-a-review-comment-for-a-pull-request +// GitHub API docs: https://docs.github.com/en/rest/reference/pulls/#create-a-review-comment-for-a-pull-request func (s *PullRequestsService) CreateComment(ctx context.Context, owner string, repo string, number int, comment *PullRequestComment) (*PullRequestComment, *Response, error) { u := fmt.Sprintf("repos/%v/%v/pulls/%d/comments", owner, repo, number) req, err := s.client.NewRequest("POST", u, comment) @@ -145,7 +145,7 @@ func (s *PullRequestsService) CreateComment(ctx context.Context, owner string, r // CreateCommentInReplyTo creates a new comment as a reply to an existing pull request comment. // -// GitHub API docs: https://developer.github.com/v3/pulls/comments/#create-a-review-comment-for-a-pull-request +// GitHub API docs: https://docs.github.com/en/rest/reference/pulls/#create-a-review-comment-for-a-pull-request func (s *PullRequestsService) CreateCommentInReplyTo(ctx context.Context, owner string, repo string, number int, body string, commentID int64) (*PullRequestComment, *Response, error) { comment := &struct { Body string `json:"body,omitempty"` @@ -172,7 +172,7 @@ func (s *PullRequestsService) CreateCommentInReplyTo(ctx context.Context, owner // EditComment updates a pull request comment. // A non-nil comment.Body must be provided. Other comment fields should be left nil. // -// GitHub API docs: https://developer.github.com/v3/pulls/comments/#update-a-review-comment-for-a-pull-request +// GitHub API docs: https://docs.github.com/en/rest/reference/pulls/#update-a-review-comment-for-a-pull-request func (s *PullRequestsService) EditComment(ctx context.Context, owner string, repo string, commentID int64, comment *PullRequestComment) (*PullRequestComment, *Response, error) { u := fmt.Sprintf("repos/%v/%v/pulls/comments/%d", owner, repo, commentID) req, err := s.client.NewRequest("PATCH", u, comment) @@ -191,7 +191,7 @@ func (s *PullRequestsService) EditComment(ctx context.Context, owner string, rep // DeleteComment deletes a pull request comment. // -// GitHub API docs: https://developer.github.com/v3/pulls/comments/#delete-a-review-comment-for-a-pull-request +// GitHub API docs: https://docs.github.com/en/rest/reference/pulls/#delete-a-review-comment-for-a-pull-request func (s *PullRequestsService) DeleteComment(ctx context.Context, owner string, repo string, commentID int64) (*Response, error) { u := fmt.Sprintf("repos/%v/%v/pulls/comments/%d", owner, repo, commentID) req, err := s.client.NewRequest("DELETE", u, nil) diff --git a/github/pulls_reviewers.go b/github/pulls_reviewers.go index 510dfb83000..a988b7023ac 100644 --- a/github/pulls_reviewers.go +++ b/github/pulls_reviewers.go @@ -25,7 +25,7 @@ type Reviewers struct { // RequestReviewers creates a review request for the provided reviewers for the specified pull request. // -// GitHub API docs: https://developer.github.com/v3/pulls/review_requests/#request-reviewers-for-a-pull-request +// GitHub API docs: https://docs.github.com/en/rest/reference/pulls/#request-reviewers-for-a-pull-request func (s *PullRequestsService) RequestReviewers(ctx context.Context, owner, repo string, number int, reviewers ReviewersRequest) (*PullRequest, *Response, error) { u := fmt.Sprintf("repos/%s/%s/pulls/%d/requested_reviewers", owner, repo, number) req, err := s.client.NewRequest("POST", u, &reviewers) @@ -44,7 +44,7 @@ func (s *PullRequestsService) RequestReviewers(ctx context.Context, owner, repo // ListReviewers lists reviewers whose reviews have been requested on the specified pull request. // -// GitHub API docs: https://developer.github.com/v3/pulls/review_requests/#list-requested-reviewers-for-a-pull-request +// GitHub API docs: https://docs.github.com/en/rest/reference/pulls/#list-requested-reviewers-for-a-pull-request func (s *PullRequestsService) ListReviewers(ctx context.Context, owner, repo string, number int, opts *ListOptions) (*Reviewers, *Response, error) { u := fmt.Sprintf("repos/%v/%v/pulls/%d/requested_reviewers", owner, repo, number) u, err := addOptions(u, opts) @@ -68,7 +68,7 @@ func (s *PullRequestsService) ListReviewers(ctx context.Context, owner, repo str // RemoveReviewers removes the review request for the provided reviewers for the specified pull request. // -// GitHub API docs: https://developer.github.com/v3/pulls/review_requests/#remove-requested-reviewers-from-a-pull-request +// GitHub API docs: https://docs.github.com/en/rest/reference/pulls/#remove-requested-reviewers-from-a-pull-request func (s *PullRequestsService) RemoveReviewers(ctx context.Context, owner, repo string, number int, reviewers ReviewersRequest) (*Response, error) { u := fmt.Sprintf("repos/%s/%s/pulls/%d/requested_reviewers", owner, repo, number) req, err := s.client.NewRequest("DELETE", u, &reviewers) diff --git a/github/pulls_reviews.go b/github/pulls_reviews.go index 30a4585cbb5..421994ca91c 100644 --- a/github/pulls_reviews.go +++ b/github/pulls_reviews.go @@ -64,7 +64,7 @@ func (r PullRequestReviewRequest) String() string { return Stringify(r) } -func (r PullRequestReviewRequest) isComfortFadePreview() (bool, error) { +func (r *PullRequestReviewRequest) isComfortFadePreview() (bool, error) { var isCF *bool for _, comment := range r.Comments { if comment == nil { @@ -105,7 +105,7 @@ func (r PullRequestReviewDismissalRequest) String() string { // returned error format and remove this comment once it's fixed. // Read more about it here - https://github.com/google/go-github/issues/540 // -// GitHub API docs: https://developer.github.com/v3/pulls/reviews/#list-reviews-for-a-pull-request +// GitHub API docs: https://docs.github.com/en/rest/reference/pulls/#list-reviews-for-a-pull-request func (s *PullRequestsService) ListReviews(ctx context.Context, owner, repo string, number int, opts *ListOptions) ([]*PullRequestReview, *Response, error) { u := fmt.Sprintf("repos/%v/%v/pulls/%d/reviews", owner, repo, number) u, err := addOptions(u, opts) @@ -133,7 +133,7 @@ func (s *PullRequestsService) ListReviews(ctx context.Context, owner, repo strin // returned error format and remove this comment once it's fixed. // Read more about it here - https://github.com/google/go-github/issues/540 // -// GitHub API docs: https://developer.github.com/v3/pulls/reviews/#get-a-review-for-a-pull-request +// GitHub API docs: https://docs.github.com/en/rest/reference/pulls/#get-a-review-for-a-pull-request func (s *PullRequestsService) GetReview(ctx context.Context, owner, repo string, number int, reviewID int64) (*PullRequestReview, *Response, error) { u := fmt.Sprintf("repos/%v/%v/pulls/%d/reviews/%d", owner, repo, number, reviewID) @@ -157,7 +157,7 @@ func (s *PullRequestsService) GetReview(ctx context.Context, owner, repo string, // returned error format and remove this comment once it's fixed. // Read more about it here - https://github.com/google/go-github/issues/540 // -// GitHub API docs: https://developer.github.com/v3/pulls/reviews/#delete-a-pending-review-for-a-pull-request +// GitHub API docs: https://docs.github.com/en/rest/reference/pulls/#delete-a-pending-review-for-a-pull-request func (s *PullRequestsService) DeletePendingReview(ctx context.Context, owner, repo string, number int, reviewID int64) (*PullRequestReview, *Response, error) { u := fmt.Sprintf("repos/%v/%v/pulls/%d/reviews/%d", owner, repo, number, reviewID) @@ -181,7 +181,7 @@ func (s *PullRequestsService) DeletePendingReview(ctx context.Context, owner, re // returned error format and remove this comment once it's fixed. // Read more about it here - https://github.com/google/go-github/issues/540 // -// GitHub API docs: https://developer.github.com/v3/pulls/reviews/#list-comments-for-a-pull-request-review +// GitHub API docs: https://docs.github.com/en/rest/reference/pulls/#list-comments-for-a-pull-request-review func (s *PullRequestsService) ListReviewComments(ctx context.Context, owner, repo string, number int, reviewID int64, opts *ListOptions) ([]*PullRequestComment, *Response, error) { u := fmt.Sprintf("repos/%v/%v/pulls/%d/reviews/%d/comments", owner, repo, number, reviewID) u, err := addOptions(u, opts) @@ -209,7 +209,7 @@ func (s *PullRequestsService) ListReviewComments(ctx context.Context, owner, rep // returned error format and remove this comment once it's fixed. // Read more about it here - https://github.com/google/go-github/issues/540 // -// GitHub API docs: https://developer.github.com/v3/pulls/reviews/#create-a-review-for-a-pull-request +// GitHub API docs: https://docs.github.com/en/rest/reference/pulls/#create-a-review-for-a-pull-request // // In order to use multi-line comments, you must use the "comfort fade" preview. // This replaces the use of the "Position" field in comments with 4 new fields: @@ -270,7 +270,7 @@ func (s *PullRequestsService) CreateReview(ctx context.Context, owner, repo stri // UpdateReview updates the review summary on the specified pull request. // -// GitHub API docs: https://developer.github.com/v3/pulls/reviews/#update-a-review-for-a-pull-request +// GitHub API docs: https://docs.github.com/en/rest/reference/pulls/#update-a-review-for-a-pull-request func (s *PullRequestsService) UpdateReview(ctx context.Context, owner, repo string, number int, reviewID int64, body string) (*PullRequestReview, *Response, error) { opts := &struct { Body string `json:"body"` @@ -297,7 +297,7 @@ func (s *PullRequestsService) UpdateReview(ctx context.Context, owner, repo stri // returned error format and remove this comment once it's fixed. // Read more about it here - https://github.com/google/go-github/issues/540 // -// GitHub API docs: https://developer.github.com/v3/pulls/reviews/#submit-a-review-for-a-pull-request +// GitHub API docs: https://docs.github.com/en/rest/reference/pulls/#submit-a-review-for-a-pull-request func (s *PullRequestsService) SubmitReview(ctx context.Context, owner, repo string, number int, reviewID int64, review *PullRequestReviewRequest) (*PullRequestReview, *Response, error) { u := fmt.Sprintf("repos/%v/%v/pulls/%d/reviews/%d/events", owner, repo, number, reviewID) @@ -321,7 +321,7 @@ func (s *PullRequestsService) SubmitReview(ctx context.Context, owner, repo stri // returned error format and remove this comment once it's fixed. // Read more about it here - https://github.com/google/go-github/issues/540 // -// GitHub API docs: https://developer.github.com/v3/pulls/reviews/#dismiss-a-review-for-a-pull-request +// GitHub API docs: https://docs.github.com/en/rest/reference/pulls/#dismiss-a-review-for-a-pull-request func (s *PullRequestsService) DismissReview(ctx context.Context, owner, repo string, number int, reviewID int64, review *PullRequestReviewDismissalRequest) (*PullRequestReview, *Response, error) { u := fmt.Sprintf("repos/%v/%v/pulls/%d/reviews/%d/dismissals", owner, repo, number, reviewID) diff --git a/github/reactions.go b/github/reactions.go index 47eb41f0ee5..ec6149fe5cf 100644 --- a/github/reactions.go +++ b/github/reactions.go @@ -14,7 +14,7 @@ import ( // ReactionsService provides access to the reactions-related functions in the // GitHub API. // -// GitHub API docs: https://developer.github.com/v3/reactions/ +// GitHub API docs: https://docs.github.com/en/rest/reference/reactions/ type ReactionsService service // Reaction represents a GitHub reaction. @@ -60,7 +60,7 @@ type ListCommentReactionOptions struct { // ListCommentReactions lists the reactions for a commit comment. // -// GitHub API docs: https://developer.github.com/v3/reactions/#list-reactions-for-a-commit-comment +// GitHub API docs: https://docs.github.com/en/rest/reference/reactions/#list-reactions-for-a-commit-comment func (s *ReactionsService) ListCommentReactions(ctx context.Context, owner, repo string, id int64, opts *ListCommentReactionOptions) ([]*Reaction, *Response, error) { u := fmt.Sprintf("repos/%v/%v/comments/%v/reactions", owner, repo, id) u, err := addOptions(u, opts) @@ -90,7 +90,7 @@ func (s *ReactionsService) ListCommentReactions(ctx context.Context, owner, repo // previously created reaction will be returned with Status: 200 OK. // The content should have one of the following values: "+1", "-1", "laugh", "confused", "heart", "hooray", "rocket", or "eyes". // -// GitHub API docs: https://developer.github.com/v3/reactions/#create-reaction-for-a-commit-comment +// GitHub API docs: https://docs.github.com/en/rest/reference/reactions/#create-reaction-for-a-commit-comment func (s *ReactionsService) CreateCommentReaction(ctx context.Context, owner, repo string, id int64, content string) (*Reaction, *Response, error) { u := fmt.Sprintf("repos/%v/%v/comments/%v/reactions", owner, repo, id) @@ -114,7 +114,7 @@ func (s *ReactionsService) CreateCommentReaction(ctx context.Context, owner, rep // DeleteCommentReaction deletes the reaction for a commit comment. // -// GitHub API docs: https://developer.github.com/v3/reactions/#delete-a-commit-comment-reaction +// GitHub API docs: https://docs.github.com/en/rest/reference/reactions/#delete-a-commit-comment-reaction func (s *ReactionsService) DeleteCommentReaction(ctx context.Context, owner, repo string, commentID, reactionID int64) (*Response, error) { u := fmt.Sprintf("repos/%v/%v/comments/%v/reactions/%v", owner, repo, commentID, reactionID) @@ -123,7 +123,7 @@ func (s *ReactionsService) DeleteCommentReaction(ctx context.Context, owner, rep // DeleteCommentReactionByID deletes the reaction for a commit comment by repository ID. // -// GitHub API docs: https://developer.github.com/v3/reactions/#delete-a-commit-comment-reaction +// GitHub API docs: https://docs.github.com/en/rest/reference/reactions/#delete-a-commit-comment-reaction func (s *ReactionsService) DeleteCommentReactionByID(ctx context.Context, repoID, commentID, reactionID int64) (*Response, error) { u := fmt.Sprintf("repositories/%v/comments/%v/reactions/%v", repoID, commentID, reactionID) @@ -132,7 +132,7 @@ func (s *ReactionsService) DeleteCommentReactionByID(ctx context.Context, repoID // ListIssueReactions lists the reactions for an issue. // -// GitHub API docs: https://developer.github.com/v3/reactions/#list-reactions-for-an-issue +// GitHub API docs: https://docs.github.com/en/rest/reference/reactions/#list-reactions-for-an-issue func (s *ReactionsService) ListIssueReactions(ctx context.Context, owner, repo string, number int, opts *ListOptions) ([]*Reaction, *Response, error) { u := fmt.Sprintf("repos/%v/%v/issues/%v/reactions", owner, repo, number) u, err := addOptions(u, opts) @@ -162,7 +162,7 @@ func (s *ReactionsService) ListIssueReactions(ctx context.Context, owner, repo s // previously created reaction will be returned with Status: 200 OK. // The content should have one of the following values: "+1", "-1", "laugh", "confused", "heart", "hooray", "rocket", or "eyes". // -// GitHub API docs: https://developer.github.com/v3/reactions/#create-reaction-for-an-issue +// GitHub API docs: https://docs.github.com/en/rest/reference/reactions/#create-reaction-for-an-issue func (s *ReactionsService) CreateIssueReaction(ctx context.Context, owner, repo string, number int, content string) (*Reaction, *Response, error) { u := fmt.Sprintf("repos/%v/%v/issues/%v/reactions", owner, repo, number) @@ -186,7 +186,7 @@ func (s *ReactionsService) CreateIssueReaction(ctx context.Context, owner, repo // DeleteIssueReaction deletes the reaction to an issue. // -// GitHub API docs: https://developer.github.com/v3/reactions/#delete-an-issue-reaction +// GitHub API docs: https://docs.github.com/en/rest/reference/reactions/#delete-an-issue-reaction func (s *ReactionsService) DeleteIssueReaction(ctx context.Context, owner, repo string, issueNumber int, reactionID int64) (*Response, error) { url := fmt.Sprintf("repos/%v/%v/issues/%v/reactions/%v", owner, repo, issueNumber, reactionID) @@ -195,7 +195,7 @@ func (s *ReactionsService) DeleteIssueReaction(ctx context.Context, owner, repo // DeleteIssueReactionByID deletes the reaction to an issue by repository ID. // -// GitHub API docs: https://developer.github.com/v3/reactions/#delete-an-issue-reaction +// GitHub API docs: https://docs.github.com/en/rest/reference/reactions/#delete-an-issue-reaction func (s *ReactionsService) DeleteIssueReactionByID(ctx context.Context, repoID, issueNumber int, reactionID int64) (*Response, error) { url := fmt.Sprintf("repositories/%v/issues/%v/reactions/%v", repoID, issueNumber, reactionID) @@ -204,7 +204,7 @@ func (s *ReactionsService) DeleteIssueReactionByID(ctx context.Context, repoID, // ListIssueCommentReactions lists the reactions for an issue comment. // -// GitHub API docs: https://developer.github.com/v3/reactions/#list-reactions-for-an-issue-comment +// GitHub API docs: https://docs.github.com/en/rest/reference/reactions/#list-reactions-for-an-issue-comment func (s *ReactionsService) ListIssueCommentReactions(ctx context.Context, owner, repo string, id int64, opts *ListOptions) ([]*Reaction, *Response, error) { u := fmt.Sprintf("repos/%v/%v/issues/comments/%v/reactions", owner, repo, id) u, err := addOptions(u, opts) @@ -234,7 +234,7 @@ func (s *ReactionsService) ListIssueCommentReactions(ctx context.Context, owner, // previously created reaction will be returned with Status: 200 OK. // The content should have one of the following values: "+1", "-1", "laugh", "confused", "heart", "hooray", "rocket", or "eyes". // -// GitHub API docs: https://developer.github.com/v3/reactions/#create-reaction-for-an-issue-comment +// GitHub API docs: https://docs.github.com/en/rest/reference/reactions/#create-reaction-for-an-issue-comment func (s *ReactionsService) CreateIssueCommentReaction(ctx context.Context, owner, repo string, id int64, content string) (*Reaction, *Response, error) { u := fmt.Sprintf("repos/%v/%v/issues/comments/%v/reactions", owner, repo, id) @@ -258,7 +258,7 @@ func (s *ReactionsService) CreateIssueCommentReaction(ctx context.Context, owner // DeleteIssueCommentReaction deletes the reaction to an issue comment. // -// GitHub API docs: https://developer.github.com/v3/reactions/#delete-an-issue-comment-reaction +// GitHub API docs: https://docs.github.com/en/rest/reference/reactions/#delete-an-issue-comment-reaction func (s *ReactionsService) DeleteIssueCommentReaction(ctx context.Context, owner, repo string, commentID, reactionID int64) (*Response, error) { url := fmt.Sprintf("repos/%v/%v/issues/comments/%v/reactions/%v", owner, repo, commentID, reactionID) @@ -267,7 +267,7 @@ func (s *ReactionsService) DeleteIssueCommentReaction(ctx context.Context, owner // DeleteIssueCommentReactionByID deletes the reaction to an issue comment by repository ID. // -// GitHub API docs: https://developer.github.com/v3/reactions/#delete-an-issue-comment-reaction +// GitHub API docs: https://docs.github.com/en/rest/reference/reactions/#delete-an-issue-comment-reaction func (s *ReactionsService) DeleteIssueCommentReactionByID(ctx context.Context, repoID, commentID, reactionID int64) (*Response, error) { url := fmt.Sprintf("repositories/%v/issues/comments/%v/reactions/%v", repoID, commentID, reactionID) @@ -276,7 +276,7 @@ func (s *ReactionsService) DeleteIssueCommentReactionByID(ctx context.Context, r // ListPullRequestCommentReactions lists the reactions for a pull request review comment. // -// GitHub API docs: https://developer.github.com/v3/reactions/#list-reactions-for-a-pull-request-review-comment +// GitHub API docs: https://docs.github.com/en/rest/reference/reactions/#list-reactions-for-a-pull-request-review-comment func (s *ReactionsService) ListPullRequestCommentReactions(ctx context.Context, owner, repo string, id int64, opts *ListOptions) ([]*Reaction, *Response, error) { u := fmt.Sprintf("repos/%v/%v/pulls/comments/%v/reactions", owner, repo, id) u, err := addOptions(u, opts) @@ -306,7 +306,7 @@ func (s *ReactionsService) ListPullRequestCommentReactions(ctx context.Context, // previously created reaction will be returned with Status: 200 OK. // The content should have one of the following values: "+1", "-1", "laugh", "confused", "heart", "hooray", "rocket", or "eyes". // -// GitHub API docs: https://developer.github.com/v3/reactions/#create-reaction-for-a-pull-request-review-comment +// GitHub API docs: https://docs.github.com/en/rest/reference/reactions/#create-reaction-for-a-pull-request-review-comment func (s *ReactionsService) CreatePullRequestCommentReaction(ctx context.Context, owner, repo string, id int64, content string) (*Reaction, *Response, error) { u := fmt.Sprintf("repos/%v/%v/pulls/comments/%v/reactions", owner, repo, id) @@ -330,7 +330,7 @@ func (s *ReactionsService) CreatePullRequestCommentReaction(ctx context.Context, // DeletePullRequestCommentReaction deletes the reaction to a pull request review comment. // -// GitHub API docs: https://developer.github.com/v3/reactions/#delete-a-pull-request-comment-reaction +// GitHub API docs: https://docs.github.com/en/rest/reference/reactions/#delete-a-pull-request-comment-reaction func (s *ReactionsService) DeletePullRequestCommentReaction(ctx context.Context, owner, repo string, commentID, reactionID int64) (*Response, error) { url := fmt.Sprintf("repos/%v/%v/pulls/comments/%v/reactions/%v", owner, repo, commentID, reactionID) @@ -339,7 +339,7 @@ func (s *ReactionsService) DeletePullRequestCommentReaction(ctx context.Context, // DeletePullRequestCommentReactionByID deletes the reaction to a pull request review comment by repository ID. // -// GitHub API docs: https://developer.github.com/v3/reactions/#delete-a-pull-request-comment-reaction +// GitHub API docs: https://docs.github.com/en/rest/reference/reactions/#delete-a-pull-request-comment-reaction func (s *ReactionsService) DeletePullRequestCommentReactionByID(ctx context.Context, repoID, commentID, reactionID int64) (*Response, error) { url := fmt.Sprintf("repositories/%v/pulls/comments/%v/reactions/%v", repoID, commentID, reactionID) @@ -348,7 +348,7 @@ func (s *ReactionsService) DeletePullRequestCommentReactionByID(ctx context.Cont // ListTeamDiscussionReactions lists the reactions for a team discussion. // -// GitHub API docs: https://developer.github.com/v3/reactions/#list-reactions-for-a-team-discussion-legacy +// GitHub API docs: https://docs.github.com/en/rest/reference/reactions/#list-reactions-for-a-team-discussion-legacy func (s *ReactionsService) ListTeamDiscussionReactions(ctx context.Context, teamID int64, discussionNumber int, opts *ListOptions) ([]*Reaction, *Response, error) { u := fmt.Sprintf("teams/%v/discussions/%v/reactions", teamID, discussionNumber) u, err := addOptions(u, opts) @@ -375,7 +375,7 @@ func (s *ReactionsService) ListTeamDiscussionReactions(ctx context.Context, team // CreateTeamDiscussionReaction creates a reaction for a team discussion. // The content should have one of the following values: "+1", "-1", "laugh", "confused", "heart", "hooray", "rocket", or "eyes". // -// GitHub API docs: https://developer.github.com/v3/reactions/#create-reaction-for-a-team-discussion-legacy +// GitHub API docs: https://docs.github.com/en/rest/reference/reactions/#create-reaction-for-a-team-discussion-legacy func (s *ReactionsService) CreateTeamDiscussionReaction(ctx context.Context, teamID int64, discussionNumber int, content string) (*Reaction, *Response, error) { u := fmt.Sprintf("teams/%v/discussions/%v/reactions", teamID, discussionNumber) @@ -398,7 +398,7 @@ func (s *ReactionsService) CreateTeamDiscussionReaction(ctx context.Context, tea // DeleteTeamDiscussionReaction deletes the reaction to a team discussion. // -// GitHub API docs: https://developer.github.com/v3/reactions/#delete-team-discussion-reaction +// GitHub API docs: https://docs.github.com/en/rest/reference/reactions/#delete-team-discussion-reaction func (s *ReactionsService) DeleteTeamDiscussionReaction(ctx context.Context, org, teamSlug string, discussionNumber int, reactionID int64) (*Response, error) { url := fmt.Sprintf("orgs/%v/teams/%v/discussions/%v/reactions/%v", org, teamSlug, discussionNumber, reactionID) @@ -407,7 +407,7 @@ func (s *ReactionsService) DeleteTeamDiscussionReaction(ctx context.Context, org // DeleteTeamDiscussionReactionByOrgIDAndTeamID deletes the reaction to a team discussion by organization ID and team ID. // -// GitHub API docs: https://developer.github.com/v3/reactions/#delete-team-discussion-reaction +// GitHub API docs: https://docs.github.com/en/rest/reference/reactions/#delete-team-discussion-reaction func (s *ReactionsService) DeleteTeamDiscussionReactionByOrgIDAndTeamID(ctx context.Context, orgID, teamID, discussionNumber int, reactionID int64) (*Response, error) { url := fmt.Sprintf("organizations/%v/team/%v/discussions/%v/reactions/%v", orgID, teamID, discussionNumber, reactionID) @@ -416,7 +416,7 @@ func (s *ReactionsService) DeleteTeamDiscussionReactionByOrgIDAndTeamID(ctx cont // ListTeamDiscussionCommentReactions lists the reactions for a team discussion comment. // -// GitHub API docs: https://developer.github.com/v3/reactions/#list-reactions-for-a-team-discussion-comment-legacy +// GitHub API docs: https://docs.github.com/en/rest/reference/reactions/#list-reactions-for-a-team-discussion-comment-legacy func (s *ReactionsService) ListTeamDiscussionCommentReactions(ctx context.Context, teamID int64, discussionNumber, commentNumber int, opts *ListOptions) ([]*Reaction, *Response, error) { u := fmt.Sprintf("teams/%v/discussions/%v/comments/%v/reactions", teamID, discussionNumber, commentNumber) u, err := addOptions(u, opts) @@ -442,7 +442,7 @@ func (s *ReactionsService) ListTeamDiscussionCommentReactions(ctx context.Contex // CreateTeamDiscussionCommentReaction creates a reaction for a team discussion comment. // The content should have one of the following values: "+1", "-1", "laugh", "confused", "heart", "hooray", "rocket", or "eyes". // -// GitHub API docs: https://developer.github.com/v3/reactions/#create-reaction-for-a-team-discussion-comment-legacy +// GitHub API docs: https://docs.github.com/en/rest/reference/reactions/#create-reaction-for-a-team-discussion-comment-legacy func (s *ReactionsService) CreateTeamDiscussionCommentReaction(ctx context.Context, teamID int64, discussionNumber, commentNumber int, content string) (*Reaction, *Response, error) { u := fmt.Sprintf("teams/%v/discussions/%v/comments/%v/reactions", teamID, discussionNumber, commentNumber) @@ -465,7 +465,7 @@ func (s *ReactionsService) CreateTeamDiscussionCommentReaction(ctx context.Conte // DeleteTeamDiscussionCommentReaction deletes the reaction to a team discussion comment. // -// GitHub API docs: https://developer.github.com/v3/reactions/#delete-team-discussion-comment-reaction +// GitHub API docs: https://docs.github.com/en/rest/reference/reactions/#delete-team-discussion-comment-reaction func (s *ReactionsService) DeleteTeamDiscussionCommentReaction(ctx context.Context, org, teamSlug string, discussionNumber, commentNumber int, reactionID int64) (*Response, error) { url := fmt.Sprintf("orgs/%v/teams/%v/discussions/%v/comments/%v/reactions/%v", org, teamSlug, discussionNumber, commentNumber, reactionID) @@ -474,7 +474,7 @@ func (s *ReactionsService) DeleteTeamDiscussionCommentReaction(ctx context.Conte // DeleteTeamDiscussionCommentReactionByOrgIDAndTeamID deletes the reaction to a team discussion comment by organization ID and team ID. // -// GitHub API docs: https://developer.github.com/v3/reactions/#delete-team-discussion-comment-reaction +// GitHub API docs: https://docs.github.com/en/rest/reference/reactions/#delete-team-discussion-comment-reaction func (s *ReactionsService) DeleteTeamDiscussionCommentReactionByOrgIDAndTeamID(ctx context.Context, orgID, teamID, discussionNumber, commentNumber int, reactionID int64) (*Response, error) { url := fmt.Sprintf("organizations/%v/team/%v/discussions/%v/comments/%v/reactions/%v", orgID, teamID, discussionNumber, commentNumber, reactionID) diff --git a/github/repos.go b/github/repos.go index 4f15ac18673..71b3a041cd3 100644 --- a/github/repos.go +++ b/github/repos.go @@ -15,7 +15,7 @@ import ( // RepositoriesService handles communication with the repository related // methods of the GitHub API. // -// GitHub API docs: https://developer.github.com/v3/repos/ +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/ type RepositoriesService service // Repository represents a GitHub repository. @@ -119,7 +119,7 @@ type Repository struct { TeamsURL *string `json:"teams_url,omitempty"` // TextMatches is only populated from search results that request text matches - // See: search.go and https://developer.github.com/v3/search/#text-match-metadata + // See: search.go and https://docs.github.com/en/rest/reference/search/#text-match-metadata TextMatches []*TextMatch `json:"text_matches,omitempty"` // Visibility is only used for Create and Edit endpoints. The visibility field @@ -182,8 +182,8 @@ type RepositoryListOptions struct { // List the repositories for a user. Passing the empty string will list // repositories for the authenticated user. // -// GitHub API docs: https://developer.github.com/v3/repos/#list-repositories-for-a-user -// GitHub API docs: https://developer.github.com/v3/repos/#list-repositories-for-the-authenticated-user +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#list-repositories-for-the-authenticated-user +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#list-repositories-for-a-user func (s *RepositoriesService) List(ctx context.Context, user string, opts *RepositoryListOptions) ([]*Repository, *Response, error) { var u string if user != "" { @@ -234,7 +234,7 @@ type RepositoryListByOrgOptions struct { // ListByOrg lists the repositories for an organization. // -// GitHub API docs: https://developer.github.com/v3/repos/#list-organization-repositories +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#list-organization-repositories func (s *RepositoriesService) ListByOrg(ctx context.Context, org string, opts *RepositoryListByOrgOptions) ([]*Repository, *Response, error) { u := fmt.Sprintf("orgs/%v/repos", org) u, err := addOptions(u, opts) @@ -269,7 +269,7 @@ type RepositoryListAllOptions struct { // ListAll lists all GitHub repositories in the order that they were created. // -// GitHub API docs: https://developer.github.com/v3/repos/#list-public-repositories +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#list-public-repositories func (s *RepositoriesService) ListAll(ctx context.Context, opts *RepositoryListAllOptions) ([]*Repository, *Response, error) { u, err := addOptions("repositories", opts) if err != nil { @@ -332,8 +332,8 @@ type createRepoRequest struct { // changes propagate throughout its servers. You may set up a loop with // exponential back-off to verify repository's creation. // -// GitHub API docs: https://developer.github.com/v3/repos/#create-a-repository-for-the-authenticated-user -// GitHub API docs: https://developer.github.com/v3/repos/#create-an-organization-repository +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#create-a-repository-for-the-authenticated-user +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#create-an-organization-repository func (s *RepositoriesService) Create(ctx context.Context, org string, repo *Repository) (*Repository, *Response, error) { var u string if org != "" { @@ -390,7 +390,7 @@ type TemplateRepoRequest struct { // CreateFromTemplate generates a repository from a template. // -// GitHub API docs: https://developer.github.com/v3/repos/#create-a-repository-using-a-template +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#create-a-repository-using-a-template func (s *RepositoriesService) CreateFromTemplate(ctx context.Context, templateOwner, templateRepo string, templateRepoReq *TemplateRepoRequest) (*Repository, *Response, error) { u := fmt.Sprintf("repos/%v/%v/generate", templateOwner, templateRepo) @@ -411,7 +411,7 @@ func (s *RepositoriesService) CreateFromTemplate(ctx context.Context, templateOw // Get fetches a repository. // -// GitHub API docs: https://developer.github.com/v3/repos/#get-a-repository +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#get-a-repository func (s *RepositoriesService) Get(ctx context.Context, owner, repo string) (*Repository, *Response, error) { u := fmt.Sprintf("repos/%v/%v", owner, repo) req, err := s.client.NewRequest("GET", u, nil) @@ -420,7 +420,7 @@ func (s *RepositoriesService) Get(ctx context.Context, owner, repo string) (*Rep } // TODO: remove custom Accept header when the license support fully launches - // https://developer.github.com/v3/licenses/#get-a-repositorys-license + // https://docs.github.com/en/rest/reference/licenses/#get-a-repositorys-license acceptHeaders := []string{ mediaTypeCodesOfConductPreview, mediaTypeTopicsPreview, @@ -440,7 +440,7 @@ func (s *RepositoriesService) Get(ctx context.Context, owner, repo string) (*Rep // GetCodeOfConduct gets the contents of a repository's code of conduct. // -// GitHub API docs: https://developer.github.com/v3/codes_of_conduct/#get-the-code-of-conduct-for-a-repository +// GitHub API docs: https://docs.github.com/en/rest/reference/codes-of-conduct/#get-the-code-of-conduct-for-a-repository func (s *RepositoriesService) GetCodeOfConduct(ctx context.Context, owner, repo string) (*CodeOfConduct, *Response, error) { u := fmt.Sprintf("repos/%v/%v/community/code_of_conduct", owner, repo) req, err := s.client.NewRequest("GET", u, nil) @@ -481,7 +481,7 @@ func (s *RepositoriesService) GetByID(ctx context.Context, id int64) (*Repositor // Edit updates a repository. // -// GitHub API docs: https://developer.github.com/v3/repos/#update-a-repository +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#update-a-repository func (s *RepositoriesService) Edit(ctx context.Context, owner, repo string, repository *Repository) (*Repository, *Response, error) { u := fmt.Sprintf("repos/%v/%v", owner, repo) req, err := s.client.NewRequest("PATCH", u, repository) @@ -502,7 +502,7 @@ func (s *RepositoriesService) Edit(ctx context.Context, owner, repo string, repo // Delete a repository. // -// GitHub API docs: https://developer.github.com/v3/repos/#delete-a-repository +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#delete-a-repository func (s *RepositoriesService) Delete(ctx context.Context, owner, repo string) (*Response, error) { u := fmt.Sprintf("repos/%v/%v", owner, repo) req, err := s.client.NewRequest("DELETE", u, nil) @@ -547,7 +547,7 @@ type ListContributorsOptions struct { // GetVulnerabilityAlerts checks if vulnerability alerts are enabled for a repository. // -// GitHub API docs: https://developer.github.com/v3/repos/#check-if-vulnerability-alerts-are-enabled-for-a-repository +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#check-if-vulnerability-alerts-are-enabled-for-a-repository func (s *RepositoriesService) GetVulnerabilityAlerts(ctx context.Context, owner, repository string) (bool, *Response, error) { u := fmt.Sprintf("repos/%v/%v/vulnerability-alerts", owner, repository) @@ -567,7 +567,7 @@ func (s *RepositoriesService) GetVulnerabilityAlerts(ctx context.Context, owner, // EnableVulnerabilityAlerts enables vulnerability alerts and the dependency graph for a repository. // -// GitHub API docs: https://developer.github.com/v3/repos/#enable-vulnerability-alerts +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#enable-vulnerability-alerts func (s *RepositoriesService) EnableVulnerabilityAlerts(ctx context.Context, owner, repository string) (*Response, error) { u := fmt.Sprintf("repos/%v/%v/vulnerability-alerts", owner, repository) @@ -584,7 +584,7 @@ func (s *RepositoriesService) EnableVulnerabilityAlerts(ctx context.Context, own // DisableVulnerabilityAlerts disables vulnerability alerts and the dependency graph for a repository. // -// GitHub API docs: https://developer.github.com/v3/repos/#disable-vulnerability-alerts +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#disable-vulnerability-alerts func (s *RepositoriesService) DisableVulnerabilityAlerts(ctx context.Context, owner, repository string) (*Response, error) { u := fmt.Sprintf("repos/%v/%v/vulnerability-alerts", owner, repository) @@ -601,7 +601,7 @@ func (s *RepositoriesService) DisableVulnerabilityAlerts(ctx context.Context, ow // EnableAutomatedSecurityFixes enables the automated security fixes for a repository. // -// GitHub API docs: https://developer.github.com/v3/repos/#enable-automated-security-fixes +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#enable-automated-security-fixes func (s *RepositoriesService) EnableAutomatedSecurityFixes(ctx context.Context, owner, repository string) (*Response, error) { u := fmt.Sprintf("repos/%v/%v/automated-security-fixes", owner, repository) @@ -618,7 +618,7 @@ func (s *RepositoriesService) EnableAutomatedSecurityFixes(ctx context.Context, // DisableAutomatedSecurityFixes disables vulnerability alerts and the dependency graph for a repository. // -// GitHub API docs: https://developer.github.com/v3/repos/#disable-automated-security-fixes +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#disable-automated-security-fixes func (s *RepositoriesService) DisableAutomatedSecurityFixes(ctx context.Context, owner, repository string) (*Response, error) { u := fmt.Sprintf("repos/%v/%v/automated-security-fixes", owner, repository) @@ -635,7 +635,7 @@ func (s *RepositoriesService) DisableAutomatedSecurityFixes(ctx context.Context, // ListContributors lists contributors for a repository. // -// GitHub API docs: https://developer.github.com/v3/repos/#list-repository-contributors +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#list-repository-contributors func (s *RepositoriesService) ListContributors(ctx context.Context, owner string, repository string, opts *ListContributorsOptions) ([]*Contributor, *Response, error) { u := fmt.Sprintf("repos/%v/%v/contributors", owner, repository) u, err := addOptions(u, opts) @@ -666,7 +666,7 @@ func (s *RepositoriesService) ListContributors(ctx context.Context, owner string // "Python": 7769 // } // -// GitHub API docs: https://developer.github.com/v3/repos/#list-repository-languages +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#list-repository-languages func (s *RepositoriesService) ListLanguages(ctx context.Context, owner string, repo string) (map[string]int, *Response, error) { u := fmt.Sprintf("repos/%v/%v/languages", owner, repo) req, err := s.client.NewRequest("GET", u, nil) @@ -685,7 +685,7 @@ func (s *RepositoriesService) ListLanguages(ctx context.Context, owner string, r // ListTeams lists the teams for the specified repository. // -// GitHub API docs: https://developer.github.com/v3/repos/#list-repository-teams +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#list-repository-teams func (s *RepositoriesService) ListTeams(ctx context.Context, owner string, repo string, opts *ListOptions) ([]*Team, *Response, error) { u := fmt.Sprintf("repos/%v/%v/teams", owner, repo) u, err := addOptions(u, opts) @@ -717,7 +717,7 @@ type RepositoryTag struct { // ListTags lists tags for the specified repository. // -// GitHub API docs: https://developer.github.com/v3/repos/#list-repository-tags +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#list-repository-tags func (s *RepositoriesService) ListTags(ctx context.Context, owner string, repo string, opts *ListOptions) ([]*RepositoryTag, *Response, error) { u := fmt.Sprintf("repos/%v/%v/tags", owner, repo) u, err := addOptions(u, opts) @@ -905,7 +905,7 @@ type SignaturesProtectedBranch struct { // ListBranches lists branches for the specified repository. // -// GitHub API docs: https://developer.github.com/v3/repos/branches/#list-branches +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#list-branches func (s *RepositoriesService) ListBranches(ctx context.Context, owner string, repo string, opts *BranchListOptions) ([]*Branch, *Response, error) { u := fmt.Sprintf("repos/%v/%v/branches", owner, repo) u, err := addOptions(u, opts) @@ -932,7 +932,7 @@ func (s *RepositoriesService) ListBranches(ctx context.Context, owner string, re // GetBranch gets the specified branch for a repository. // -// GitHub API docs: https://developer.github.com/v3/repos/branches/#get-a-branch +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#get-a-branch func (s *RepositoriesService) GetBranch(ctx context.Context, owner, repo, branch string) (*Branch, *Response, error) { u := fmt.Sprintf("repos/%v/%v/branches/%v", owner, repo, branch) req, err := s.client.NewRequest("GET", u, nil) @@ -954,7 +954,7 @@ func (s *RepositoriesService) GetBranch(ctx context.Context, owner, repo, branch // GetBranchProtection gets the protection of a given branch. // -// GitHub API docs: https://developer.github.com/v3/repos/branches/#get-branch-protection +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#get-branch-protection func (s *RepositoriesService) GetBranchProtection(ctx context.Context, owner, repo, branch string) (*Protection, *Response, error) { u := fmt.Sprintf("repos/%v/%v/branches/%v/protection", owner, repo, branch) req, err := s.client.NewRequest("GET", u, nil) @@ -976,7 +976,7 @@ func (s *RepositoriesService) GetBranchProtection(ctx context.Context, owner, re // GetRequiredStatusChecks gets the required status checks for a given protected branch. // -// GitHub API docs: https://developer.github.com/v3/repos/branches/#get-status-checks-protection +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#get-status-checks-protection func (s *RepositoriesService) GetRequiredStatusChecks(ctx context.Context, owner, repo, branch string) (*RequiredStatusChecks, *Response, error) { u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/required_status_checks", owner, repo, branch) req, err := s.client.NewRequest("GET", u, nil) @@ -998,7 +998,7 @@ func (s *RepositoriesService) GetRequiredStatusChecks(ctx context.Context, owner // ListRequiredStatusChecksContexts lists the required status checks contexts for a given protected branch. // -// GitHub API docs: https://developer.github.com/v3/repos/branches/#get-all-status-check-contexts +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#get-all-status-check-contexts func (s *RepositoriesService) ListRequiredStatusChecksContexts(ctx context.Context, owner, repo, branch string) (contexts []string, resp *Response, err error) { u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/required_status_checks/contexts", owner, repo, branch) req, err := s.client.NewRequest("GET", u, nil) @@ -1019,7 +1019,7 @@ func (s *RepositoriesService) ListRequiredStatusChecksContexts(ctx context.Conte // UpdateBranchProtection updates the protection of a given branch. // -// GitHub API docs: https://developer.github.com/v3/repos/branches/#update-branch-protection +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#update-branch-protection func (s *RepositoriesService) UpdateBranchProtection(ctx context.Context, owner, repo, branch string, preq *ProtectionRequest) (*Protection, *Response, error) { u := fmt.Sprintf("repos/%v/%v/branches/%v/protection", owner, repo, branch) req, err := s.client.NewRequest("PUT", u, preq) @@ -1041,7 +1041,7 @@ func (s *RepositoriesService) UpdateBranchProtection(ctx context.Context, owner, // RemoveBranchProtection removes the protection of a given branch. // -// GitHub API docs: https://developer.github.com/v3/repos/branches/#delete-branch-protection +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#delete-branch-protection func (s *RepositoriesService) RemoveBranchProtection(ctx context.Context, owner, repo, branch string) (*Response, error) { u := fmt.Sprintf("repos/%v/%v/branches/%v/protection", owner, repo, branch) req, err := s.client.NewRequest("DELETE", u, nil) @@ -1057,7 +1057,7 @@ func (s *RepositoriesService) RemoveBranchProtection(ctx context.Context, owner, // GetSignaturesProtectedBranch gets required signatures of protected branch. // -// GitHub API docs: https://developer.github.com/v3/repos/branches/#get-commit-signature-protection +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#get-commit-signature-protection func (s *RepositoriesService) GetSignaturesProtectedBranch(ctx context.Context, owner, repo, branch string) (*SignaturesProtectedBranch, *Response, error) { u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/required_signatures", owner, repo, branch) req, err := s.client.NewRequest("GET", u, nil) @@ -1080,7 +1080,7 @@ func (s *RepositoriesService) GetSignaturesProtectedBranch(ctx context.Context, // RequireSignaturesOnProtectedBranch makes signed commits required on a protected branch. // It requires admin access and branch protection to be enabled. // -// GitHub API docs: https://developer.github.com/v3/repos/branches/#create-commit-signature-protection +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#create-commit-signature-protection func (s *RepositoriesService) RequireSignaturesOnProtectedBranch(ctx context.Context, owner, repo, branch string) (*SignaturesProtectedBranch, *Response, error) { u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/required_signatures", owner, repo, branch) req, err := s.client.NewRequest("POST", u, nil) @@ -1102,7 +1102,7 @@ func (s *RepositoriesService) RequireSignaturesOnProtectedBranch(ctx context.Con // OptionalSignaturesOnProtectedBranch removes required signed commits on a given branch. // -// GitHub API docs: https://developer.github.com/v3/repos/branches/#delete-commit-signature-protection +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#delete-commit-signature-protection func (s *RepositoriesService) OptionalSignaturesOnProtectedBranch(ctx context.Context, owner, repo, branch string) (*Response, error) { u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/required_signatures", owner, repo, branch) req, err := s.client.NewRequest("DELETE", u, nil) @@ -1118,7 +1118,7 @@ func (s *RepositoriesService) OptionalSignaturesOnProtectedBranch(ctx context.Co // UpdateRequiredStatusChecks updates the required status checks for a given protected branch. // -// GitHub API docs: https://developer.github.com/v3/repos/branches/#update-status-check-potection +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#update-status-check-potection func (s *RepositoriesService) UpdateRequiredStatusChecks(ctx context.Context, owner, repo, branch string, sreq *RequiredStatusChecksRequest) (*RequiredStatusChecks, *Response, error) { u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/required_status_checks", owner, repo, branch) req, err := s.client.NewRequest("PATCH", u, sreq) @@ -1137,7 +1137,7 @@ func (s *RepositoriesService) UpdateRequiredStatusChecks(ctx context.Context, ow // License gets the contents of a repository's license if one is detected. // -// GitHub API docs: https://developer.github.com/v3/licenses/#get-the-license-for-a-repository +// GitHub API docs: https://docs.github.com/en/rest/reference/licenses/#get-the-license-for-a-repository func (s *RepositoriesService) License(ctx context.Context, owner, repo string) (*RepositoryLicense, *Response, error) { u := fmt.Sprintf("repos/%v/%v/license", owner, repo) req, err := s.client.NewRequest("GET", u, nil) @@ -1156,7 +1156,7 @@ func (s *RepositoriesService) License(ctx context.Context, owner, repo string) ( // GetPullRequestReviewEnforcement gets pull request review enforcement of a protected branch. // -// GitHub API docs: https://developer.github.com/v3/repos/branches/#get-pull-request-review-protection +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#get-pull-request-review-protection func (s *RepositoriesService) GetPullRequestReviewEnforcement(ctx context.Context, owner, repo, branch string) (*PullRequestReviewsEnforcement, *Response, error) { u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/required_pull_request_reviews", owner, repo, branch) req, err := s.client.NewRequest("GET", u, nil) @@ -1179,7 +1179,7 @@ func (s *RepositoriesService) GetPullRequestReviewEnforcement(ctx context.Contex // UpdatePullRequestReviewEnforcement patches pull request review enforcement of a protected branch. // It requires admin access and branch protection to be enabled. // -// GitHub API docs: https://developer.github.com/v3/repos/branches/#update-pull-request-review-protection +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#update-pull-request-review-protection func (s *RepositoriesService) UpdatePullRequestReviewEnforcement(ctx context.Context, owner, repo, branch string, patch *PullRequestReviewsEnforcementUpdate) (*PullRequestReviewsEnforcement, *Response, error) { u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/required_pull_request_reviews", owner, repo, branch) req, err := s.client.NewRequest("PATCH", u, patch) @@ -1202,7 +1202,7 @@ func (s *RepositoriesService) UpdatePullRequestReviewEnforcement(ctx context.Con // DisableDismissalRestrictions disables dismissal restrictions of a protected branch. // It requires admin access and branch protection to be enabled. // -// GitHub API docs: https://developer.github.com/v3/repos/branches/#update-pull-request-review-protection +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#update-pull-request-review-protection func (s *RepositoriesService) DisableDismissalRestrictions(ctx context.Context, owner, repo, branch string) (*PullRequestReviewsEnforcement, *Response, error) { u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/required_pull_request_reviews", owner, repo, branch) @@ -1229,7 +1229,7 @@ func (s *RepositoriesService) DisableDismissalRestrictions(ctx context.Context, // RemovePullRequestReviewEnforcement removes pull request enforcement of a protected branch. // -// GitHub API docs: https://developer.github.com/v3/repos/branches/#delete-pull-request-review-protection +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#delete-pull-request-review-protection func (s *RepositoriesService) RemovePullRequestReviewEnforcement(ctx context.Context, owner, repo, branch string) (*Response, error) { u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/required_pull_request_reviews", owner, repo, branch) req, err := s.client.NewRequest("DELETE", u, nil) @@ -1245,7 +1245,7 @@ func (s *RepositoriesService) RemovePullRequestReviewEnforcement(ctx context.Con // GetAdminEnforcement gets admin enforcement information of a protected branch. // -// GitHub API docs: https://developer.github.com/v3/repos/branches/#get-admin-branch-protection +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#get-admin-branch-protection func (s *RepositoriesService) GetAdminEnforcement(ctx context.Context, owner, repo, branch string) (*AdminEnforcement, *Response, error) { u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/enforce_admins", owner, repo, branch) req, err := s.client.NewRequest("GET", u, nil) @@ -1268,7 +1268,7 @@ func (s *RepositoriesService) GetAdminEnforcement(ctx context.Context, owner, re // AddAdminEnforcement adds admin enforcement to a protected branch. // It requires admin access and branch protection to be enabled. // -// GitHub API docs: https://developer.github.com/v3/repos/branches/#set-admin-branch-protection +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#set-admin-branch-protection func (s *RepositoriesService) AddAdminEnforcement(ctx context.Context, owner, repo, branch string) (*AdminEnforcement, *Response, error) { u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/enforce_admins", owner, repo, branch) req, err := s.client.NewRequest("POST", u, nil) @@ -1290,7 +1290,7 @@ func (s *RepositoriesService) AddAdminEnforcement(ctx context.Context, owner, re // RemoveAdminEnforcement removes admin enforcement from a protected branch. // -// GitHub API docs: https://developer.github.com/v3/repos/branches/#delete-admin-branch-protection +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#delete-admin-branch-protection func (s *RepositoriesService) RemoveAdminEnforcement(ctx context.Context, owner, repo, branch string) (*Response, error) { u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/enforce_admins", owner, repo, branch) req, err := s.client.NewRequest("DELETE", u, nil) @@ -1311,7 +1311,7 @@ type repositoryTopics struct { // ListAllTopics lists topics for a repository. // -// GitHub API docs: https://developer.github.com/v3/repos/#get-all-repository-topics +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#get-all-repository-topics func (s *RepositoriesService) ListAllTopics(ctx context.Context, owner, repo string) ([]string, *Response, error) { u := fmt.Sprintf("repos/%v/%v/topics", owner, repo) req, err := s.client.NewRequest("GET", u, nil) @@ -1333,7 +1333,7 @@ func (s *RepositoriesService) ListAllTopics(ctx context.Context, owner, repo str // ReplaceAllTopics replaces topics for a repository. // -// GitHub API docs: https://developer.github.com/v3/repos/#replace-all-repository-topics +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#replace-all-repository-topics func (s *RepositoriesService) ReplaceAllTopics(ctx context.Context, owner, repo string, topics []string) ([]string, *Response, error) { u := fmt.Sprintf("repos/%v/%v/topics", owner, repo) t := &repositoryTopics{ @@ -1362,7 +1362,7 @@ func (s *RepositoriesService) ReplaceAllTopics(ctx context.Context, owner, repo // ListApps lists the GitHub apps that have push access to a given protected branch. // It requires the GitHub apps to have `write` access to the `content` permission. // -// GitHub API docs: https://developer.github.com/v3/repos/branches/#list-apps-with-access-to-the-protected-branch +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#get-apps-with-access-to-the-protected-branch func (s *RepositoriesService) ListApps(ctx context.Context, owner, repo, branch string) ([]*App, *Response, error) { u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/restrictions/apps", owner, repo, branch) req, err := s.client.NewRequest("GET", u, nil) @@ -1385,7 +1385,7 @@ func (s *RepositoriesService) ListApps(ctx context.Context, owner, repo, branch // // Note: The list of users, apps, and teams in total is limited to 100 items. // -// GitHub API docs: https://developer.github.com/v3/repos/branches/#set-app-access-restrictions +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#set-app-access-restrictions func (s *RepositoriesService) ReplaceAppRestrictions(ctx context.Context, owner, repo, branch string, slug []string) ([]*App, *Response, error) { u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/restrictions/apps", owner, repo, branch) req, err := s.client.NewRequest("PUT", u, slug) @@ -1407,7 +1407,7 @@ func (s *RepositoriesService) ReplaceAppRestrictions(ctx context.Context, owner, // // Note: The list of users, apps, and teams in total is limited to 100 items. // -// GitHub API docs: https://developer.github.com/v3/repos/branches/#add-app-access-restrictions +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#add-app-access-restrictions func (s *RepositoriesService) AddAppRestrictions(ctx context.Context, owner, repo, branch string, slug []string) ([]*App, *Response, error) { u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/restrictions/apps", owner, repo, branch) req, err := s.client.NewRequest("POST", u, slug) @@ -1429,7 +1429,7 @@ func (s *RepositoriesService) AddAppRestrictions(ctx context.Context, owner, rep // // Note: The list of users, apps, and teams in total is limited to 100 items. // -// GitHub API docs: https://developer.github.com/v3/repos/branches/#remove-app-access-restrictions +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#remove-app-access-restrictions func (s *RepositoriesService) RemoveAppRestrictions(ctx context.Context, owner, repo, branch string, slug []string) ([]*App, *Response, error) { u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/restrictions/apps", owner, repo, branch) req, err := s.client.NewRequest("DELETE", u, slug) @@ -1460,7 +1460,7 @@ type TransferRequest struct { // A follow up request, after a delay of a second or so, should result // in a successful request. // -// GitHub API docs: https://developer.github.com/v3/repos/#transfer-a-repository +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#transfer-a-repository func (s *RepositoriesService) Transfer(ctx context.Context, owner, repo string, transfer TransferRequest) (*Repository, *Response, error) { u := fmt.Sprintf("repos/%v/%v/transfer", owner, repo) @@ -1489,7 +1489,7 @@ type DispatchRequestOptions struct { // Dispatch triggers a repository_dispatch event in a GitHub Actions workflow. // -// GitHub API docs: https://developer.github.com/v3/repos/#create-a-repository-dispatch-event +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#create-a-repository-dispatch-event func (s *RepositoriesService) Dispatch(ctx context.Context, owner, repo string, opts DispatchRequestOptions) (*Repository, *Response, error) { u := fmt.Sprintf("repos/%v/%v/dispatches", owner, repo) diff --git a/github/repos_collaborators.go b/github/repos_collaborators.go index ec8e68535b7..bbb7cbb97aa 100644 --- a/github/repos_collaborators.go +++ b/github/repos_collaborators.go @@ -27,7 +27,7 @@ type ListCollaboratorsOptions struct { } // CollaboratorInvitation represents an invitation created when adding a collaborator. -// GitHub API docs: https://developer.github.com/v3/repos/collaborators/#response-when-a-new-invitation-is-created +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/collaborators/#response-when-a-new-invitation-is-created type CollaboratorInvitation struct { ID *int64 `json:"id,omitempty"` Repo *Repository `json:"repository,omitempty"` @@ -41,7 +41,7 @@ type CollaboratorInvitation struct { // ListCollaborators lists the GitHub users that have access to the repository. // -// GitHub API docs: https://developer.github.com/v3/repos/collaborators/#list-repository-collaborators +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#list-repository-collaborators func (s *RepositoriesService) ListCollaborators(ctx context.Context, owner, repo string, opts *ListCollaboratorsOptions) ([]*User, *Response, error) { u := fmt.Sprintf("repos/%v/%v/collaborators", owner, repo) u, err := addOptions(u, opts) @@ -68,7 +68,7 @@ func (s *RepositoriesService) ListCollaborators(ctx context.Context, owner, repo // Note: This will return false if the user is not a collaborator OR the user // is not a GitHub user. // -// GitHub API docs: https://developer.github.com/v3/repos/collaborators/#check-if-a-user-is-a-repository-collaborator +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#check-if-a-user-is-a-repository-collaborator func (s *RepositoriesService) IsCollaborator(ctx context.Context, owner, repo, user string) (bool, *Response, error) { u := fmt.Sprintf("repos/%v/%v/collaborators/%v", owner, repo, user) req, err := s.client.NewRequest("GET", u, nil) @@ -91,7 +91,7 @@ type RepositoryPermissionLevel struct { } // GetPermissionLevel retrieves the specific permission level a collaborator has for a given repository. -// GitHub API docs: https://developer.github.com/v3/repos/collaborators/#get-repository-permissions-for-a-user +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#get-repository-permissions-for-a-user func (s *RepositoriesService) GetPermissionLevel(ctx context.Context, owner, repo, user string) (*RepositoryPermissionLevel, *Response, error) { u := fmt.Sprintf("repos/%v/%v/collaborators/%v/permission", owner, repo, user) req, err := s.client.NewRequest("GET", u, nil) @@ -125,7 +125,7 @@ type RepositoryAddCollaboratorOptions struct { // AddCollaborator sends an invitation to the specified GitHub user // to become a collaborator to the given repo. // -// GitHub API docs: https://developer.github.com/v3/repos/collaborators/#add-a-repository-collaborator +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#add-a-repository-collaborator func (s *RepositoriesService) AddCollaborator(ctx context.Context, owner, repo, user string, opts *RepositoryAddCollaboratorOptions) (*CollaboratorInvitation, *Response, error) { u := fmt.Sprintf("repos/%v/%v/collaborators/%v", owner, repo, user) req, err := s.client.NewRequest("PUT", u, opts) @@ -143,7 +143,7 @@ func (s *RepositoriesService) AddCollaborator(ctx context.Context, owner, repo, // RemoveCollaborator removes the specified GitHub user as collaborator from the given repo. // Note: Does not return error if a valid user that is not a collaborator is removed. // -// GitHub API docs: https://developer.github.com/v3/repos/collaborators/#remove-a-repository-collaborator +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#remove-a-repository-collaborator func (s *RepositoriesService) RemoveCollaborator(ctx context.Context, owner, repo, user string) (*Response, error) { u := fmt.Sprintf("repos/%v/%v/collaborators/%v", owner, repo, user) req, err := s.client.NewRequest("DELETE", u, nil) diff --git a/github/repos_comments.go b/github/repos_comments.go index 0ccdca37236..e378855a852 100644 --- a/github/repos_comments.go +++ b/github/repos_comments.go @@ -36,7 +36,7 @@ func (r RepositoryComment) String() string { // ListComments lists all the comments for the repository. // -// GitHub API docs: https://developer.github.com/v3/repos/comments/#list-commit-comments-for-a-repository +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#list-commit-comments-for-a-repository func (s *RepositoriesService) ListComments(ctx context.Context, owner, repo string, opts *ListOptions) ([]*RepositoryComment, *Response, error) { u := fmt.Sprintf("repos/%v/%v/comments", owner, repo) u, err := addOptions(u, opts) @@ -63,7 +63,7 @@ func (s *RepositoriesService) ListComments(ctx context.Context, owner, repo stri // ListCommitComments lists all the comments for a given commit SHA. // -// GitHub API docs: https://developer.github.com/v3/repos/comments/#list-commit-comments +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#list-commit-comments func (s *RepositoriesService) ListCommitComments(ctx context.Context, owner, repo, sha string, opts *ListOptions) ([]*RepositoryComment, *Response, error) { u := fmt.Sprintf("repos/%v/%v/commits/%v/comments", owner, repo, sha) u, err := addOptions(u, opts) @@ -91,7 +91,7 @@ func (s *RepositoriesService) ListCommitComments(ctx context.Context, owner, rep // CreateComment creates a comment for the given commit. // Note: GitHub allows for comments to be created for non-existing files and positions. // -// GitHub API docs: https://developer.github.com/v3/repos/comments/#create-a-commit-comment +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#create-a-commit-comment func (s *RepositoriesService) CreateComment(ctx context.Context, owner, repo, sha string, comment *RepositoryComment) (*RepositoryComment, *Response, error) { u := fmt.Sprintf("repos/%v/%v/commits/%v/comments", owner, repo, sha) req, err := s.client.NewRequest("POST", u, comment) @@ -110,7 +110,7 @@ func (s *RepositoriesService) CreateComment(ctx context.Context, owner, repo, sh // GetComment gets a single comment from a repository. // -// GitHub API docs: https://developer.github.com/v3/repos/comments/#get-a-commit-comment +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#get-a-commit-comment func (s *RepositoriesService) GetComment(ctx context.Context, owner, repo string, id int64) (*RepositoryComment, *Response, error) { u := fmt.Sprintf("repos/%v/%v/comments/%v", owner, repo, id) req, err := s.client.NewRequest("GET", u, nil) @@ -132,7 +132,7 @@ func (s *RepositoriesService) GetComment(ctx context.Context, owner, repo string // UpdateComment updates the body of a single comment. // -// GitHub API docs: https://developer.github.com/v3/repos/comments/#update-a-commit-comment +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#update-a-commit-comment func (s *RepositoriesService) UpdateComment(ctx context.Context, owner, repo string, id int64, comment *RepositoryComment) (*RepositoryComment, *Response, error) { u := fmt.Sprintf("repos/%v/%v/comments/%v", owner, repo, id) req, err := s.client.NewRequest("PATCH", u, comment) @@ -151,7 +151,7 @@ func (s *RepositoriesService) UpdateComment(ctx context.Context, owner, repo str // DeleteComment deletes a single comment from a repository. // -// GitHub API docs: https://developer.github.com/v3/repos/comments/#delete-a-commit-comment +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#delete-a-commit-comment func (s *RepositoriesService) DeleteComment(ctx context.Context, owner, repo string, id int64) (*Response, error) { u := fmt.Sprintf("repos/%v/%v/comments/%v", owner, repo, id) req, err := s.client.NewRequest("DELETE", u, nil) diff --git a/github/repos_commits.go b/github/repos_commits.go index b5e5b99c60f..5d3784a3d71 100644 --- a/github/repos_commits.go +++ b/github/repos_commits.go @@ -123,7 +123,7 @@ type BranchCommit struct { // ListCommits lists the commits of a repository. // -// GitHub API docs: https://developer.github.com/v3/repos/commits/#list-commits +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#list-commits func (s *RepositoriesService) ListCommits(ctx context.Context, owner, repo string, opts *CommitsListOptions) ([]*RepositoryCommit, *Response, error) { u := fmt.Sprintf("repos/%v/%v/commits", owner, repo) u, err := addOptions(u, opts) @@ -147,8 +147,8 @@ func (s *RepositoriesService) ListCommits(ctx context.Context, owner, repo strin // GetCommit fetches the specified commit, including all details about it. // -// GitHub API docs: https://developer.github.com/v3/repos/commits/#get-a-single-commit -// GitHub API docs: https://developer.github.com/v3/repos/commits/#get-a-commit +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/commits/#get-a-single-commit +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#get-a-commit func (s *RepositoriesService) GetCommit(ctx context.Context, owner, repo, sha string) (*RepositoryCommit, *Response, error) { u := fmt.Sprintf("repos/%v/%v/commits/%v", owner, repo, sha) @@ -168,7 +168,7 @@ func (s *RepositoriesService) GetCommit(ctx context.Context, owner, repo, sha st // GetCommitRaw fetches the specified commit in raw (diff or patch) format. // -// GitHub API docs: https://developer.github.com/v3/repos/commits/#get-a-commit +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#get-a-commit func (s *RepositoriesService) GetCommitRaw(ctx context.Context, owner string, repo string, sha string, opts RawOptions) (string, *Response, error) { u := fmt.Sprintf("repos/%v/%v/commits/%v", owner, repo, sha) req, err := s.client.NewRequest("GET", u, nil) @@ -197,7 +197,7 @@ func (s *RepositoriesService) GetCommitRaw(ctx context.Context, owner string, re // GetCommitSHA1 gets the SHA-1 of a commit reference. If a last-known SHA1 is // supplied and no new commits have occurred, a 304 Unmodified response is returned. // -// GitHub API docs: https://developer.github.com/v3/repos/commits/#get-a-commit +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#get-a-commit func (s *RepositoriesService) GetCommitSHA1(ctx context.Context, owner, repo, ref, lastSHA string) (string, *Response, error) { u := fmt.Sprintf("repos/%v/%v/commits/%v", owner, repo, refURLEscape(ref)) @@ -222,7 +222,7 @@ func (s *RepositoriesService) GetCommitSHA1(ctx context.Context, owner, repo, re // CompareCommits compares a range of commits with each other. // -// GitHub API docs: https://developer.github.com/v3/repos/commits/#compare-two-commits +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#compare-two-commits func (s *RepositoriesService) CompareCommits(ctx context.Context, owner, repo string, base, head string) (*CommitsComparison, *Response, error) { u := fmt.Sprintf("repos/%v/%v/compare/%v...%v", owner, repo, base, head) @@ -246,7 +246,7 @@ func (s *RepositoriesService) CompareCommits(ctx context.Context, owner, repo st // To compare branches across other repositories in the same network as "repo", // use the format ":branch". // -// GitHub API docs: https://developer.github.com/v3/repos/commits/#compare-two-commits +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#compare-two-commits func (s *RepositoriesService) CompareCommitsRaw(ctx context.Context, owner, repo, base, head string, opts RawOptions) (string, *Response, error) { u := fmt.Sprintf("repos/%v/%v/compare/%v...%v", owner, repo, base, head) req, err := s.client.NewRequest("GET", u, nil) @@ -275,7 +275,7 @@ func (s *RepositoriesService) CompareCommitsRaw(ctx context.Context, owner, repo // 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 +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#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) diff --git a/github/repos_community_health.go b/github/repos_community_health.go index 255c6fe7a58..0527ca8cfba 100644 --- a/github/repos_community_health.go +++ b/github/repos_community_health.go @@ -38,7 +38,7 @@ type CommunityHealthMetrics struct { // GetCommunityHealthMetrics retrieves all the community health metrics for a repository. // -// GitHub API docs: https://developer.github.com/v3/repos/community/#get-community-profile-metrics +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#get-community-profile-metrics func (s *RepositoriesService) GetCommunityHealthMetrics(ctx context.Context, owner, repo string) (*CommunityHealthMetrics, *Response, error) { u := fmt.Sprintf("repos/%v/%v/community/profile", owner, repo) req, err := s.client.NewRequest("GET", u, nil) diff --git a/github/repos_contents.go b/github/repos_contents.go index d6a3272e827..e156efcb572 100644 --- a/github/repos_contents.go +++ b/github/repos_contents.go @@ -4,7 +4,7 @@ // license that can be found in the LICENSE file. // Repository contents API methods. -// GitHub API docs: https://developer.github.com/v3/repos/contents/ +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/contents/ package github @@ -94,7 +94,7 @@ func (r *RepositoryContent) GetContent() (string, error) { // GetReadme gets the Readme file for the repository. // -// GitHub API docs: https://developer.github.com/v3/repos/contents/#get-a-repository-readme +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#get-a-repository-readme func (s *RepositoriesService) GetReadme(ctx context.Context, owner, repo string, opts *RepositoryContentGetOptions) (*RepositoryContent, *Response, error) { u := fmt.Sprintf("repos/%v/%v/readme", owner, repo) u, err := addOptions(u, opts) @@ -150,7 +150,7 @@ func (s *RepositoriesService) DownloadContents(ctx context.Context, owner, repo, // as possible, both result types will be returned but only one will contain a // value and the other will be nil. // -// GitHub API docs: https://developer.github.com/v3/repos/contents/#get-repository-content +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#get-repository-content func (s *RepositoriesService) GetContents(ctx context.Context, owner, repo, path string, opts *RepositoryContentGetOptions) (fileContent *RepositoryContent, directoryContent []*RepositoryContent, resp *Response, err error) { escapedPath := (&url.URL{Path: path}).String() u := fmt.Sprintf("repos/%s/%s/contents/%s", owner, repo, escapedPath) @@ -181,7 +181,7 @@ func (s *RepositoriesService) GetContents(ctx context.Context, owner, repo, path // CreateFile creates a new file in a repository at the given path and returns // the commit and file metadata. // -// GitHub API docs: https://developer.github.com/v3/repos/contents/#create-or-update-file-contents +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#create-or-update-file-contents func (s *RepositoriesService) CreateFile(ctx context.Context, owner, repo, path string, opts *RepositoryContentFileOptions) (*RepositoryContentResponse, *Response, error) { u := fmt.Sprintf("repos/%s/%s/contents/%s", owner, repo, path) req, err := s.client.NewRequest("PUT", u, opts) @@ -199,7 +199,7 @@ func (s *RepositoriesService) CreateFile(ctx context.Context, owner, repo, path // UpdateFile updates a file in a repository at the given path and returns the // commit and file metadata. Requires the blob SHA of the file being updated. // -// GitHub API docs: https://developer.github.com/v3/repos/contents/#create-or-update-file-contents +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#create-or-update-file-contents func (s *RepositoriesService) UpdateFile(ctx context.Context, owner, repo, path string, opts *RepositoryContentFileOptions) (*RepositoryContentResponse, *Response, error) { u := fmt.Sprintf("repos/%s/%s/contents/%s", owner, repo, path) req, err := s.client.NewRequest("PUT", u, opts) @@ -217,7 +217,7 @@ func (s *RepositoriesService) UpdateFile(ctx context.Context, owner, repo, path // DeleteFile deletes a file from a repository and returns the commit. // Requires the blob SHA of the file to be deleted. // -// GitHub API docs: https://developer.github.com/v3/repos/contents/#delete-a-file +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#delete-a-file func (s *RepositoriesService) DeleteFile(ctx context.Context, owner, repo, path string, opts *RepositoryContentFileOptions) (*RepositoryContentResponse, *Response, error) { u := fmt.Sprintf("repos/%s/%s/contents/%s", owner, repo, path) req, err := s.client.NewRequest("DELETE", u, opts) @@ -247,7 +247,7 @@ const ( // repository. The archiveFormat can be specified by either the github.Tarball // or github.Zipball constant. // -// GitHub API docs: https://developer.github.com/v3/repos/contents/#get-archive-link +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/contents/#get-archive-link func (s *RepositoriesService) GetArchiveLink(ctx context.Context, owner, repo string, archiveformat ArchiveFormat, opts *RepositoryContentGetOptions, followRedirects bool) (*url.URL, *Response, error) { u := fmt.Sprintf("repos/%s/%s/%s", owner, repo, archiveformat) if opts != nil && opts.Ref != "" { diff --git a/github/repos_deployments.go b/github/repos_deployments.go index 648c7506703..ec70280da74 100644 --- a/github/repos_deployments.go +++ b/github/repos_deployments.go @@ -63,7 +63,7 @@ type DeploymentsListOptions struct { // ListDeployments lists the deployments of a repository. // -// GitHub API docs: https://developer.github.com/v3/repos/deployments/#list-deployments +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#list-deployments func (s *RepositoriesService) ListDeployments(ctx context.Context, owner, repo string, opts *DeploymentsListOptions) ([]*Deployment, *Response, error) { u := fmt.Sprintf("repos/%v/%v/deployments", owner, repo) u, err := addOptions(u, opts) @@ -87,7 +87,7 @@ func (s *RepositoriesService) ListDeployments(ctx context.Context, owner, repo s // GetDeployment returns a single deployment of a repository. // -// GitHub API docs: https://developer.github.com/v3/repos/deployments/#get-a-deployment +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#get-a-deployment func (s *RepositoriesService) GetDeployment(ctx context.Context, owner, repo string, deploymentID int64) (*Deployment, *Response, error) { u := fmt.Sprintf("repos/%v/%v/deployments/%v", owner, repo, deploymentID) @@ -107,7 +107,7 @@ func (s *RepositoriesService) GetDeployment(ctx context.Context, owner, repo str // CreateDeployment creates a new deployment for a repository. // -// GitHub API docs: https://developer.github.com/v3/repos/deployments/#create-a-deployment +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#create-a-deployment func (s *RepositoriesService) CreateDeployment(ctx context.Context, owner, repo string, request *DeploymentRequest) (*Deployment, *Response, error) { u := fmt.Sprintf("repos/%v/%v/deployments", owner, repo) @@ -131,7 +131,7 @@ func (s *RepositoriesService) CreateDeployment(ctx context.Context, owner, repo // DeleteDeployment deletes an existing deployment for a repository. // -// GitHub API docs: https://developer.github.com/v3/repos/deployments/#delete-a-deployment +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#delete-a-deployment func (s *RepositoriesService) DeleteDeployment(ctx context.Context, owner, repo string, deploymentID int64) (*Response, error) { u := fmt.Sprintf("repos/%v/%v/deployments/%v", owner, repo, deploymentID) req, err := s.client.NewRequest("DELETE", u, nil) @@ -175,7 +175,7 @@ type DeploymentStatusRequest struct { // ListDeploymentStatuses lists the statuses of a given deployment of a repository. // -// GitHub API docs: https://developer.github.com/v3/repos/deployments/#list-deployment-statuses +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#list-deployment-statuses func (s *RepositoriesService) ListDeploymentStatuses(ctx context.Context, owner, repo string, deployment int64, opts *ListOptions) ([]*DeploymentStatus, *Response, error) { u := fmt.Sprintf("repos/%v/%v/deployments/%v/statuses", owner, repo, deployment) u, err := addOptions(u, opts) @@ -203,7 +203,7 @@ func (s *RepositoriesService) ListDeploymentStatuses(ctx context.Context, owner, // GetDeploymentStatus returns a single deployment status of a repository. // -// GitHub API docs: https://developer.github.com/v3/repos/deployments/#get-a-deployment-status +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#get-a-deployment-status func (s *RepositoriesService) GetDeploymentStatus(ctx context.Context, owner, repo string, deploymentID, deploymentStatusID int64) (*DeploymentStatus, *Response, error) { u := fmt.Sprintf("repos/%v/%v/deployments/%v/statuses/%v", owner, repo, deploymentID, deploymentStatusID) @@ -227,7 +227,7 @@ func (s *RepositoriesService) GetDeploymentStatus(ctx context.Context, owner, re // CreateDeploymentStatus creates a new status for a deployment. // -// GitHub API docs: https://developer.github.com/v3/repos/deployments/#create-a-deployment-status +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#create-a-deployment-status func (s *RepositoriesService) CreateDeploymentStatus(ctx context.Context, owner, repo string, deployment int64, request *DeploymentStatusRequest) (*DeploymentStatus, *Response, error) { u := fmt.Sprintf("repos/%v/%v/deployments/%v/statuses", owner, repo, deployment) diff --git a/github/repos_forks.go b/github/repos_forks.go index 5973587dd50..1c202cc4bf6 100644 --- a/github/repos_forks.go +++ b/github/repos_forks.go @@ -24,7 +24,7 @@ type RepositoryListForksOptions struct { // ListForks lists the forks of the specified repository. // -// GitHub API docs: https://developer.github.com/v3/repos/forks/#list-forks +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#list-forks func (s *RepositoriesService) ListForks(ctx context.Context, owner, repo string, opts *RepositoryListForksOptions) ([]*Repository, *Response, error) { u := fmt.Sprintf("repos/%v/%v/forks", owner, repo) u, err := addOptions(u, opts) @@ -65,7 +65,7 @@ type RepositoryCreateForkOptions struct { // A follow up request, after a delay of a second or so, should result // in a successful request. // -// GitHub API docs: https://developer.github.com/v3/repos/forks/#create-a-fork +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#create-a-fork func (s *RepositoriesService) CreateFork(ctx context.Context, owner, repo string, opts *RepositoryCreateForkOptions) (*Repository, *Response, error) { u := fmt.Sprintf("repos/%v/%v/forks", owner, repo) u, err := addOptions(u, opts) diff --git a/github/repos_hooks.go b/github/repos_hooks.go index 5c64027a915..c7e49351795 100644 --- a/github/repos_hooks.go +++ b/github/repos_hooks.go @@ -104,7 +104,7 @@ type createHookRequest struct { // Note that only a subset of the hook fields are used and hook must // not be nil. // -// GitHub API docs: https://developer.github.com/v3/repos/hooks/#create-a-repository-webhook +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#create-a-repository-webhook func (s *RepositoriesService) CreateHook(ctx context.Context, owner, repo string, hook *Hook) (*Hook, *Response, error) { u := fmt.Sprintf("repos/%v/%v/hooks", owner, repo) @@ -131,7 +131,7 @@ func (s *RepositoriesService) CreateHook(ctx context.Context, owner, repo string // ListHooks lists all Hooks for the specified repository. // -// GitHub API docs: https://developer.github.com/v3/repos/hooks/#list-repository-webhooks +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#list-repository-webhooks func (s *RepositoriesService) ListHooks(ctx context.Context, owner, repo string, opts *ListOptions) ([]*Hook, *Response, error) { u := fmt.Sprintf("repos/%v/%v/hooks", owner, repo) u, err := addOptions(u, opts) @@ -155,7 +155,7 @@ func (s *RepositoriesService) ListHooks(ctx context.Context, owner, repo string, // GetHook returns a single specified Hook. // -// GitHub API docs: https://developer.github.com/v3/repos/hooks/#get-a-repository-webhook +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#get-a-repository-webhook func (s *RepositoriesService) GetHook(ctx context.Context, owner, repo string, id int64) (*Hook, *Response, error) { u := fmt.Sprintf("repos/%v/%v/hooks/%d", owner, repo, id) req, err := s.client.NewRequest("GET", u, nil) @@ -173,7 +173,7 @@ func (s *RepositoriesService) GetHook(ctx context.Context, owner, repo string, i // EditHook updates a specified Hook. // -// GitHub API docs: https://developer.github.com/v3/repos/hooks/#update-a-repository-webhook +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#update-a-repository-webhook func (s *RepositoriesService) EditHook(ctx context.Context, owner, repo string, id int64, hook *Hook) (*Hook, *Response, error) { u := fmt.Sprintf("repos/%v/%v/hooks/%d", owner, repo, id) req, err := s.client.NewRequest("PATCH", u, hook) @@ -191,7 +191,7 @@ func (s *RepositoriesService) EditHook(ctx context.Context, owner, repo string, // DeleteHook deletes a specified Hook. // -// GitHub API docs: https://developer.github.com/v3/repos/hooks/#delete-a-repository-webhook +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#delete-a-repository-webhook func (s *RepositoriesService) DeleteHook(ctx context.Context, owner, repo string, id int64) (*Response, error) { u := fmt.Sprintf("repos/%v/%v/hooks/%d", owner, repo, id) req, err := s.client.NewRequest("DELETE", u, nil) @@ -203,7 +203,7 @@ func (s *RepositoriesService) DeleteHook(ctx context.Context, owner, repo string // PingHook triggers a 'ping' event to be sent to the Hook. // -// GitHub API docs: https://developer.github.com/v3/repos/hooks/#ping-a-repository-webhook +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#ping-a-repository-webhook func (s *RepositoriesService) PingHook(ctx context.Context, owner, repo string, id int64) (*Response, error) { u := fmt.Sprintf("repos/%v/%v/hooks/%d/pings", owner, repo, id) req, err := s.client.NewRequest("POST", u, nil) @@ -215,7 +215,7 @@ func (s *RepositoriesService) PingHook(ctx context.Context, owner, repo string, // TestHook triggers a test Hook by github. // -// GitHub API docs: https://developer.github.com/v3/repos/hooks/#test-the-push-repository-webhook +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#test-the-push-repository-webhook func (s *RepositoriesService) TestHook(ctx context.Context, owner, repo string, id int64) (*Response, error) { u := fmt.Sprintf("repos/%v/%v/hooks/%d/tests", owner, repo, id) req, err := s.client.NewRequest("POST", u, nil) diff --git a/github/repos_invitations.go b/github/repos_invitations.go index 98d72a85558..87a83b4a5d8 100644 --- a/github/repos_invitations.go +++ b/github/repos_invitations.go @@ -27,7 +27,7 @@ type RepositoryInvitation struct { // ListInvitations lists all currently-open repository invitations. // -// GitHub API docs: https://developer.github.com/v3/repos/invitations/#list-repository-invitations +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#list-repository-invitations func (s *RepositoriesService) ListInvitations(ctx context.Context, owner, repo string, opts *ListOptions) ([]*RepositoryInvitation, *Response, error) { u := fmt.Sprintf("repos/%v/%v/invitations", owner, repo) u, err := addOptions(u, opts) @@ -51,7 +51,7 @@ func (s *RepositoriesService) ListInvitations(ctx context.Context, owner, repo s // DeleteInvitation deletes a repository invitation. // -// GitHub API docs: https://developer.github.com/v3/repos/invitations/#delete-a-repository-invitation +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#delete-a-repository-invitation func (s *RepositoriesService) DeleteInvitation(ctx context.Context, owner, repo string, invitationID int64) (*Response, error) { u := fmt.Sprintf("repos/%v/%v/invitations/%v", owner, repo, invitationID) req, err := s.client.NewRequest("DELETE", u, nil) @@ -68,7 +68,7 @@ func (s *RepositoriesService) DeleteInvitation(ctx context.Context, owner, repo // permissions represents the permissions that the associated user will have // on the repository. Possible values are: "read", "write", "admin". // -// GitHub API docs: https://developer.github.com/v3/repos/invitations/#update-a-repository-invitation +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#update-a-repository-invitation func (s *RepositoriesService) UpdateInvitation(ctx context.Context, owner, repo string, invitationID int64, permissions string) (*RepositoryInvitation, *Response, error) { opts := &struct { Permissions string `json:"permissions"` diff --git a/github/repos_keys.go b/github/repos_keys.go index d35e6027b19..576185d051e 100644 --- a/github/repos_keys.go +++ b/github/repos_keys.go @@ -14,7 +14,7 @@ import ( // ListKeys lists the deploy keys for a repository. // -// GitHub API docs: https://developer.github.com/v3/repos/keys/#list-deploy-keys +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#list-deploy-keys func (s *RepositoriesService) ListKeys(ctx context.Context, owner string, repo string, opts *ListOptions) ([]*Key, *Response, error) { u := fmt.Sprintf("repos/%v/%v/keys", owner, repo) u, err := addOptions(u, opts) @@ -38,7 +38,7 @@ func (s *RepositoriesService) ListKeys(ctx context.Context, owner string, repo s // GetKey fetches a single deploy key. // -// GitHub API docs: https://developer.github.com/v3/repos/keys/#get-a-deploy-key +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#get-a-deploy-key func (s *RepositoriesService) GetKey(ctx context.Context, owner string, repo string, id int64) (*Key, *Response, error) { u := fmt.Sprintf("repos/%v/%v/keys/%v", owner, repo, id) @@ -58,7 +58,7 @@ func (s *RepositoriesService) GetKey(ctx context.Context, owner string, repo str // CreateKey adds a deploy key for a repository. // -// GitHub API docs: https://developer.github.com/v3/repos/keys/#create-a-deploy-key +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#create-a-deploy-key func (s *RepositoriesService) CreateKey(ctx context.Context, owner string, repo string, key *Key) (*Key, *Response, error) { u := fmt.Sprintf("repos/%v/%v/keys", owner, repo) @@ -78,7 +78,7 @@ func (s *RepositoriesService) CreateKey(ctx context.Context, owner string, repo // DeleteKey deletes a deploy key. // -// GitHub API docs: https://developer.github.com/v3/repos/keys/#delete-a-deploy-key +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#delete-a-deploy-key func (s *RepositoriesService) DeleteKey(ctx context.Context, owner string, repo string, id int64) (*Response, error) { u := fmt.Sprintf("repos/%v/%v/keys/%v", owner, repo, id) diff --git a/github/repos_merging.go b/github/repos_merging.go index b0a5dd08798..4fff98cfda3 100644 --- a/github/repos_merging.go +++ b/github/repos_merging.go @@ -20,7 +20,7 @@ type RepositoryMergeRequest struct { // Merge a branch in the specified repository. // -// GitHub API docs: https://developer.github.com/v3/repos/merging/#merge-a-branch +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#merge-a-branch func (s *RepositoriesService) Merge(ctx context.Context, owner, repo string, request *RepositoryMergeRequest) (*RepositoryCommit, *Response, error) { u := fmt.Sprintf("repos/%v/%v/merges", owner, repo) req, err := s.client.NewRequest("POST", u, request) diff --git a/github/repos_pages.go b/github/repos_pages.go index 8a3bc5ae378..b8f174260e2 100644 --- a/github/repos_pages.go +++ b/github/repos_pages.go @@ -51,7 +51,7 @@ type createPagesRequest struct { // EnablePages enables GitHub Pages for the named repo. // -// GitHub API docs: https://developer.github.com/v3/repos/pages/#create-a-github-pages-site +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#create-a-github-pages-site func (s *RepositoriesService) EnablePages(ctx context.Context, owner, repo string, pages *Pages) (*Pages, *Response, error) { u := fmt.Sprintf("repos/%v/%v/pages", owner, repo) @@ -87,7 +87,7 @@ type PagesUpdate struct { // UpdatePages updates GitHub Pages for the named repo. // -// GitHub API docs: https://developer.github.com/v3/repos/pages/#update-information-about-a-github-pages-site +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#update-information-about-a-github-pages-site func (s *RepositoriesService) UpdatePages(ctx context.Context, owner, repo string, opts *PagesUpdate) (*Response, error) { u := fmt.Sprintf("repos/%v/%v/pages", owner, repo) @@ -106,7 +106,7 @@ func (s *RepositoriesService) UpdatePages(ctx context.Context, owner, repo strin // DisablePages disables GitHub Pages for the named repo. // -// GitHub API docs: https://developer.github.com/v3/repos/pages/#delete-a-github-pages-site +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#delete-a-github-pages-site func (s *RepositoriesService) DisablePages(ctx context.Context, owner, repo string) (*Response, error) { u := fmt.Sprintf("repos/%v/%v/pages", owner, repo) req, err := s.client.NewRequest("DELETE", u, nil) @@ -122,7 +122,7 @@ func (s *RepositoriesService) DisablePages(ctx context.Context, owner, repo stri // GetPagesInfo fetches information about a GitHub Pages site. // -// GitHub API docs: https://developer.github.com/v3/repos/pages/#get-a-github-pages-site +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#get-a-github-pages-site func (s *RepositoriesService) GetPagesInfo(ctx context.Context, owner, repo string) (*Pages, *Response, error) { u := fmt.Sprintf("repos/%v/%v/pages", owner, repo) req, err := s.client.NewRequest("GET", u, nil) @@ -141,7 +141,7 @@ func (s *RepositoriesService) GetPagesInfo(ctx context.Context, owner, repo stri // ListPagesBuilds lists the builds for a GitHub Pages site. // -// GitHub API docs: https://developer.github.com/v3/repos/pages/#list-github-pages-builds +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#list-github-pages-builds func (s *RepositoriesService) ListPagesBuilds(ctx context.Context, owner, repo string, opts *ListOptions) ([]*PagesBuild, *Response, error) { u := fmt.Sprintf("repos/%v/%v/pages/builds", owner, repo) u, err := addOptions(u, opts) @@ -165,7 +165,7 @@ func (s *RepositoriesService) ListPagesBuilds(ctx context.Context, owner, repo s // GetLatestPagesBuild fetches the latest build information for a GitHub pages site. // -// GitHub API docs: https://developer.github.com/v3/repos/pages/#get-latest-pages-build +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#get-latest-pages-build func (s *RepositoriesService) GetLatestPagesBuild(ctx context.Context, owner, repo string) (*PagesBuild, *Response, error) { u := fmt.Sprintf("repos/%v/%v/pages/builds/latest", owner, repo) req, err := s.client.NewRequest("GET", u, nil) @@ -184,7 +184,7 @@ func (s *RepositoriesService) GetLatestPagesBuild(ctx context.Context, owner, re // GetPageBuild fetches the specific build information for a GitHub pages site. // -// GitHub API docs: https://developer.github.com/v3/repos/pages/#get-github-pages-build +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#get-github-pages-build func (s *RepositoriesService) GetPageBuild(ctx context.Context, owner, repo string, id int64) (*PagesBuild, *Response, error) { u := fmt.Sprintf("repos/%v/%v/pages/builds/%v", owner, repo, id) req, err := s.client.NewRequest("GET", u, nil) @@ -203,7 +203,7 @@ func (s *RepositoriesService) GetPageBuild(ctx context.Context, owner, repo stri // RequestPageBuild requests a build of a GitHub Pages site without needing to push new commit. // -// GitHub API docs: https://developer.github.com/v3/repos/pages/#request-a-github-pages-build +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#request-a-github-pages-build func (s *RepositoriesService) RequestPageBuild(ctx context.Context, owner, repo string) (*PagesBuild, *Response, error) { u := fmt.Sprintf("repos/%v/%v/pages/builds", owner, repo) req, err := s.client.NewRequest("POST", u, nil) diff --git a/github/repos_projects.go b/github/repos_projects.go index 442f5232a39..6f23e348d62 100644 --- a/github/repos_projects.go +++ b/github/repos_projects.go @@ -21,7 +21,7 @@ type ProjectListOptions struct { // ListProjects lists the projects for a repo. // -// GitHub API docs: https://developer.github.com/v3/projects/#list-repository-projects +// GitHub API docs: https://docs.github.com/en/rest/reference/projects/#list-repository-projects func (s *RepositoriesService) ListProjects(ctx context.Context, owner, repo string, opts *ProjectListOptions) ([]*Project, *Response, error) { u := fmt.Sprintf("repos/%v/%v/projects", owner, repo) u, err := addOptions(u, opts) @@ -48,7 +48,7 @@ func (s *RepositoriesService) ListProjects(ctx context.Context, owner, repo stri // CreateProject creates a GitHub Project for the specified repository. // -// GitHub API docs: https://developer.github.com/v3/projects/#create-a-repository-project +// GitHub API docs: https://docs.github.com/en/rest/reference/projects/#create-a-repository-project func (s *RepositoriesService) CreateProject(ctx context.Context, owner, repo string, opts *ProjectOptions) (*Project, *Response, error) { u := fmt.Sprintf("repos/%v/%v/projects", owner, repo) req, err := s.client.NewRequest("POST", u, opts) diff --git a/github/repos_releases.go b/github/repos_releases.go index de42952a612..a6cae3aafa0 100644 --- a/github/repos_releases.go +++ b/github/repos_releases.go @@ -68,7 +68,7 @@ func (r ReleaseAsset) String() string { // ListReleases lists the releases for a repository. // -// GitHub API docs: https://developer.github.com/v3/repos/releases/#list-releases +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#list-releases func (s *RepositoriesService) ListReleases(ctx context.Context, owner, repo string, opts *ListOptions) ([]*RepositoryRelease, *Response, error) { u := fmt.Sprintf("repos/%s/%s/releases", owner, repo) u, err := addOptions(u, opts) @@ -91,7 +91,7 @@ func (s *RepositoriesService) ListReleases(ctx context.Context, owner, repo stri // GetRelease fetches a single release. // -// GitHub API docs: https://developer.github.com/v3/repos/releases/#get-a-release +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#get-a-release func (s *RepositoriesService) GetRelease(ctx context.Context, owner, repo string, id int64) (*RepositoryRelease, *Response, error) { u := fmt.Sprintf("repos/%s/%s/releases/%d", owner, repo, id) return s.getSingleRelease(ctx, u) @@ -99,7 +99,7 @@ func (s *RepositoriesService) GetRelease(ctx context.Context, owner, repo string // GetLatestRelease fetches the latest published release for the repository. // -// GitHub API docs: https://developer.github.com/v3/repos/releases/#get-the-latest-release +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#get-the-latest-release func (s *RepositoriesService) GetLatestRelease(ctx context.Context, owner, repo string) (*RepositoryRelease, *Response, error) { u := fmt.Sprintf("repos/%s/%s/releases/latest", owner, repo) return s.getSingleRelease(ctx, u) @@ -107,7 +107,7 @@ func (s *RepositoriesService) GetLatestRelease(ctx context.Context, owner, repo // GetReleaseByTag fetches a release with the specified tag. // -// GitHub API docs: https://developer.github.com/v3/repos/releases/#get-a-release-by-tag-name +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#get-a-release-by-tag-name func (s *RepositoriesService) GetReleaseByTag(ctx context.Context, owner, repo, tag string) (*RepositoryRelease, *Response, error) { u := fmt.Sprintf("repos/%s/%s/releases/tags/%s", owner, repo, tag) return s.getSingleRelease(ctx, u) @@ -147,7 +147,7 @@ type repositoryReleaseRequest struct { // Note that only a subset of the release fields are used. // See RepositoryRelease for more information. // -// GitHub API docs: https://developer.github.com/v3/repos/releases/#create-a-release +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#create-a-release func (s *RepositoriesService) CreateRelease(ctx context.Context, owner, repo string, release *RepositoryRelease) (*RepositoryRelease, *Response, error) { u := fmt.Sprintf("repos/%s/%s/releases", owner, repo) @@ -178,7 +178,7 @@ func (s *RepositoriesService) CreateRelease(ctx context.Context, owner, repo str // Note that only a subset of the release fields are used. // See RepositoryRelease for more information. // -// GitHub API docs: https://developer.github.com/v3/repos/releases/#update-a-release +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#update-a-release func (s *RepositoriesService) EditRelease(ctx context.Context, owner, repo string, id int64, release *RepositoryRelease) (*RepositoryRelease, *Response, error) { u := fmt.Sprintf("repos/%s/%s/releases/%d", owner, repo, id) @@ -206,7 +206,7 @@ func (s *RepositoriesService) EditRelease(ctx context.Context, owner, repo strin // DeleteRelease delete a single release from a repository. // -// GitHub API docs: https://developer.github.com/v3/repos/releases/#delete-a-release +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#delete-a-release func (s *RepositoriesService) DeleteRelease(ctx context.Context, owner, repo string, id int64) (*Response, error) { u := fmt.Sprintf("repos/%s/%s/releases/%d", owner, repo, id) @@ -219,7 +219,7 @@ func (s *RepositoriesService) DeleteRelease(ctx context.Context, owner, repo str // ListReleaseAssets lists the release's assets. // -// GitHub API docs: https://developer.github.com/v3/repos/releases/#list-release-assets +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#list-release-assets func (s *RepositoriesService) ListReleaseAssets(ctx context.Context, owner, repo string, id int64, opts *ListOptions) ([]*ReleaseAsset, *Response, error) { u := fmt.Sprintf("repos/%s/%s/releases/%d/assets", owner, repo, id) u, err := addOptions(u, opts) @@ -242,7 +242,7 @@ func (s *RepositoriesService) ListReleaseAssets(ctx context.Context, owner, repo // GetReleaseAsset fetches a single release asset. // -// GitHub API docs: https://developer.github.com/v3/repos/releases/#get-a-release-asset +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#get-a-release-asset func (s *RepositoriesService) GetReleaseAsset(ctx context.Context, owner, repo string, id int64) (*ReleaseAsset, *Response, error) { u := fmt.Sprintf("repos/%s/%s/releases/assets/%d", owner, repo, id) @@ -271,7 +271,7 @@ func (s *RepositoriesService) GetReleaseAsset(ctx context.Context, owner, repo s // exist, but it's possible to pass any http.Client. If nil is passed the // redirectURL will be returned instead. // -// GitHub API docs: https://developer.github.com/v3/repos/releases/#get-a-release-asset +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#get-a-release-asset func (s *RepositoriesService) DownloadReleaseAsset(ctx context.Context, owner, repo string, id int64, followRedirectsClient *http.Client) (rc io.ReadCloser, redirectURL string, err error) { u := fmt.Sprintf("repos/%s/%s/releases/assets/%d", owner, repo, id) @@ -333,7 +333,7 @@ func (s *RepositoriesService) downloadReleaseAssetFromURL(ctx context.Context, f // EditReleaseAsset edits a repository release asset. // -// GitHub API docs: https://developer.github.com/v3/repos/releases/#update-a-release-asset +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#update-a-release-asset func (s *RepositoriesService) EditReleaseAsset(ctx context.Context, owner, repo string, id int64, release *ReleaseAsset) (*ReleaseAsset, *Response, error) { u := fmt.Sprintf("repos/%s/%s/releases/assets/%d", owner, repo, id) @@ -352,7 +352,7 @@ func (s *RepositoriesService) EditReleaseAsset(ctx context.Context, owner, repo // DeleteReleaseAsset delete a single release asset from a repository. // -// GitHub API docs: https://developer.github.com/v3/repos/releases/#delete-a-release-asset +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#delete-a-release-asset func (s *RepositoriesService) DeleteReleaseAsset(ctx context.Context, owner, repo string, id int64) (*Response, error) { u := fmt.Sprintf("repos/%s/%s/releases/assets/%d", owner, repo, id) @@ -366,7 +366,7 @@ func (s *RepositoriesService) DeleteReleaseAsset(ctx context.Context, owner, rep // UploadReleaseAsset creates an asset by uploading a file into a release repository. // To upload assets that cannot be represented by an os.File, call NewUploadRequest directly. // -// GitHub API docs: https://developer.github.com/v3/repos/releases/#upload-a-release-asset +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#upload-a-release-asset func (s *RepositoriesService) UploadReleaseAsset(ctx context.Context, owner, repo string, id int64, opts *UploadOptions, file *os.File) (*ReleaseAsset, *Response, error) { u := fmt.Sprintf("repos/%s/%s/releases/%d/assets", owner, repo, id) u, err := addOptions(u, opts) diff --git a/github/repos_stats.go b/github/repos_stats.go index 633ca7c2a17..31c860e3692 100644 --- a/github/repos_stats.go +++ b/github/repos_stats.go @@ -45,7 +45,7 @@ func (w WeeklyStats) String() string { // it is now computing the requested statistics. A follow up request, after a // delay of a second or so, should result in a successful request. // -// GitHub API docs: https://developer.github.com/v3/repos/statistics/#get-all-contributor-commit-activity +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#get-all-contributor-commit-activity func (s *RepositoriesService) ListContributorsStats(ctx context.Context, owner, repo string) ([]*ContributorStats, *Response, error) { u := fmt.Sprintf("repos/%v/%v/stats/contributors", owner, repo) req, err := s.client.NewRequest("GET", u, nil) @@ -84,7 +84,7 @@ func (w WeeklyCommitActivity) String() string { // it is now computing the requested statistics. A follow up request, after a // delay of a second or so, should result in a successful request. // -// GitHub API docs: https://developer.github.com/v3/repos/statistics/#get-the-last-year-of-commit-activity +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#get-the-last-year-of-commit-activity func (s *RepositoriesService) ListCommitActivity(ctx context.Context, owner, repo string) ([]*WeeklyCommitActivity, *Response, error) { u := fmt.Sprintf("repos/%v/%v/stats/commit_activity", owner, repo) req, err := s.client.NewRequest("GET", u, nil) @@ -111,7 +111,7 @@ func (s *RepositoriesService) ListCommitActivity(ctx context.Context, owner, rep // it is now computing the requested statistics. A follow up request, after a // delay of a second or so, should result in a successful request. // -// GitHub API docs: https://developer.github.com/v3/repos/statistics/#get-the-weekly-commit-activity +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#get-the-weekly-commit-activity func (s *RepositoriesService) ListCodeFrequency(ctx context.Context, owner, repo string) ([]*WeeklyStats, *Response, error) { u := fmt.Sprintf("repos/%v/%v/stats/code_frequency", owner, repo) req, err := s.client.NewRequest("GET", u, nil) @@ -164,7 +164,7 @@ func (r RepositoryParticipation) String() string { // it is now computing the requested statistics. A follow up request, after a // delay of a second or so, should result in a successful request. // -// GitHub API docs: https://developer.github.com/v3/repos/statistics/#get-the-weekly-commit-count +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#get-the-weekly-commit-count func (s *RepositoriesService) ListParticipation(ctx context.Context, owner, repo string) (*RepositoryParticipation, *Response, error) { u := fmt.Sprintf("repos/%v/%v/stats/participation", owner, repo) req, err := s.client.NewRequest("GET", u, nil) @@ -197,7 +197,7 @@ type PunchCard struct { // it is now computing the requested statistics. A follow up request, after a // delay of a second or so, should result in a successful request. // -// GitHub API docs: https://developer.github.com/v3/repos/statistics/#get-the-hourly-commit-count-for-each-day +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#get-the-hourly-commit-count-for-each-day func (s *RepositoriesService) ListPunchCard(ctx context.Context, owner, repo string) ([]*PunchCard, *Response, error) { u := fmt.Sprintf("repos/%v/%v/stats/punch_card", owner, repo) req, err := s.client.NewRequest("GET", u, nil) diff --git a/github/repos_statuses.go b/github/repos_statuses.go index 53478c75a63..c8625c75a78 100644 --- a/github/repos_statuses.go +++ b/github/repos_statuses.go @@ -43,7 +43,7 @@ func (r RepoStatus) String() string { // ListStatuses lists the statuses of a repository at the specified // reference. ref can be a SHA, a branch name, or a tag name. // -// GitHub API docs: https://developer.github.com/v3/repos/statuses/#list-commit-statuses-for-a-reference +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#list-commit-statuses-for-a-reference func (s *RepositoriesService) ListStatuses(ctx context.Context, owner, repo, ref string, opts *ListOptions) ([]*RepoStatus, *Response, error) { u := fmt.Sprintf("repos/%v/%v/commits/%v/statuses", owner, repo, refURLEscape(ref)) u, err := addOptions(u, opts) @@ -68,7 +68,7 @@ func (s *RepositoriesService) ListStatuses(ctx context.Context, owner, repo, ref // CreateStatus creates a new status for a repository at the specified // reference. Ref can be a SHA, a branch name, or a tag name. // -// GitHub API docs: https://developer.github.com/v3/repos/statuses/#create-a-commit-status +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#create-a-commit-status func (s *RepositoriesService) CreateStatus(ctx context.Context, owner, repo, ref string, status *RepoStatus) (*RepoStatus, *Response, error) { u := fmt.Sprintf("repos/%v/%v/statuses/%v", owner, repo, refURLEscape(ref)) req, err := s.client.NewRequest("POST", u, status) @@ -107,7 +107,7 @@ func (s CombinedStatus) String() string { // GetCombinedStatus returns the combined status of a repository at the specified // reference. ref can be a SHA, a branch name, or a tag name. // -// GitHub API docs: https://developer.github.com/v3/repos/statuses/#get-the-combined-status-for-a-specific-reference +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#get-the-combined-status-for-a-specific-reference func (s *RepositoriesService) GetCombinedStatus(ctx context.Context, owner, repo, ref string, opts *ListOptions) (*CombinedStatus, *Response, error) { u := fmt.Sprintf("repos/%v/%v/commits/%v/status", owner, repo, refURLEscape(ref)) u, err := addOptions(u, opts) diff --git a/github/repos_traffic.go b/github/repos_traffic.go index f2607287dd7..dd8a8868d3e 100644 --- a/github/repos_traffic.go +++ b/github/repos_traffic.go @@ -54,7 +54,7 @@ type TrafficBreakdownOptions struct { // ListTrafficReferrers list the top 10 referrers over the last 14 days. // -// GitHub API docs: https://developer.github.com/v3/repos/traffic/#get-top-referral-sources +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#get-top-referral-sources func (s *RepositoriesService) ListTrafficReferrers(ctx context.Context, owner, repo string) ([]*TrafficReferrer, *Response, error) { u := fmt.Sprintf("repos/%v/%v/traffic/popular/referrers", owner, repo) @@ -74,7 +74,7 @@ func (s *RepositoriesService) ListTrafficReferrers(ctx context.Context, owner, r // ListTrafficPaths list the top 10 popular content over the last 14 days. // -// GitHub API docs: https://developer.github.com/v3/repos/traffic/#get-top-referral-paths +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#get-top-referral-paths func (s *RepositoriesService) ListTrafficPaths(ctx context.Context, owner, repo string) ([]*TrafficPath, *Response, error) { u := fmt.Sprintf("repos/%v/%v/traffic/popular/paths", owner, repo) @@ -94,7 +94,7 @@ func (s *RepositoriesService) ListTrafficPaths(ctx context.Context, owner, repo // ListTrafficViews get total number of views for the last 14 days and breaks it down either per day or week. // -// GitHub API docs: https://developer.github.com/v3/repos/traffic/#get-page-views +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#get-page-views func (s *RepositoriesService) ListTrafficViews(ctx context.Context, owner, repo string, opts *TrafficBreakdownOptions) (*TrafficViews, *Response, error) { u := fmt.Sprintf("repos/%v/%v/traffic/views", owner, repo) u, err := addOptions(u, opts) @@ -118,7 +118,7 @@ func (s *RepositoriesService) ListTrafficViews(ctx context.Context, owner, repo // ListTrafficClones get total number of clones for the last 14 days and breaks it down either per day or week for the last 14 days. // -// GitHub API docs: https://developer.github.com/v3/repos/traffic/#get-repository-clones +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#get-repository-clones func (s *RepositoriesService) ListTrafficClones(ctx context.Context, owner, repo string, opts *TrafficBreakdownOptions) (*TrafficClones, *Response, error) { u := fmt.Sprintf("repos/%v/%v/traffic/clones", owner, repo) u, err := addOptions(u, opts) diff --git a/github/search.go b/github/search.go index c15c1f2b272..a5b3beed695 100644 --- a/github/search.go +++ b/github/search.go @@ -29,7 +29,7 @@ import ( // For example, querying with "language:c++" and "leveldb", then query should be // "language:c++ leveldb" but not "language:c+++leveldb". // -// GitHub API docs: https://developer.github.com/v3/search/ +// GitHub API docs: https://docs.github.com/en/rest/reference/search/ type SearchService service // SearchOptions specifies optional parameters to the SearchService methods. @@ -69,7 +69,7 @@ type RepositoriesSearchResult struct { // Repositories searches repositories via various criteria. // -// GitHub API docs: https://developer.github.com/v3/search/#search-repositories +// GitHub API docs: https://docs.github.com/en/rest/reference/search/#search-repositories func (s *SearchService) Repositories(ctx context.Context, query string, opts *SearchOptions) (*RepositoriesSearchResult, *Response, error) { result := new(RepositoriesSearchResult) resp, err := s.search(ctx, "repositories", &searchParameters{Query: query}, opts, result) @@ -100,7 +100,7 @@ type TopicResult struct { // Please see https://help.github.com/en/articles/searching-topics for more // information about search qualifiers. // -// GitHub API docs: https://developer.github.com/v3/search/#search-topics +// GitHub API docs: https://docs.github.com/en/rest/reference/search/#search-topics func (s *SearchService) Topics(ctx context.Context, query string, opts *SearchOptions) (*TopicsSearchResult, *Response, error) { result := new(TopicsSearchResult) resp, err := s.search(ctx, "topics", &searchParameters{Query: query}, opts, result) @@ -131,7 +131,7 @@ type CommitResult struct { // Commits searches commits via various criteria. // -// GitHub API docs: https://developer.github.com/v3/search/#search-commits +// GitHub API docs: https://docs.github.com/en/rest/reference/search/#search-commits func (s *SearchService) Commits(ctx context.Context, query string, opts *SearchOptions) (*CommitsSearchResult, *Response, error) { result := new(CommitsSearchResult) resp, err := s.search(ctx, "commits", &searchParameters{Query: query}, opts, result) @@ -147,7 +147,7 @@ type IssuesSearchResult struct { // Issues searches issues via various criteria. // -// GitHub API docs: https://developer.github.com/v3/search/#search-issues-and-pull-requests +// GitHub API docs: https://docs.github.com/en/rest/reference/search/#search-issues-and-pull-requests func (s *SearchService) Issues(ctx context.Context, query string, opts *SearchOptions) (*IssuesSearchResult, *Response, error) { result := new(IssuesSearchResult) resp, err := s.search(ctx, "issues", &searchParameters{Query: query}, opts, result) @@ -163,7 +163,7 @@ type UsersSearchResult struct { // Users searches users via various criteria. // -// GitHub API docs: https://developer.github.com/v3/search/#search-users +// GitHub API docs: https://docs.github.com/en/rest/reference/search/#search-users func (s *SearchService) Users(ctx context.Context, query string, opts *SearchOptions) (*UsersSearchResult, *Response, error) { result := new(UsersSearchResult) resp, err := s.search(ctx, "users", &searchParameters{Query: query}, opts, result) @@ -212,7 +212,7 @@ func (c CodeResult) String() string { // Code searches code via various criteria. // -// GitHub API docs: https://developer.github.com/v3/search/#search-code +// GitHub API docs: https://docs.github.com/en/rest/reference/search/#search-code func (s *SearchService) Code(ctx context.Context, query string, opts *SearchOptions) (*CodeSearchResult, *Response, error) { result := new(CodeSearchResult) resp, err := s.search(ctx, "code", &searchParameters{Query: query}, opts, result) @@ -243,7 +243,7 @@ func (l LabelResult) String() string { // Labels searches labels in the repository with ID repoID via various criteria. // -// GitHub API docs: https://developer.github.com/v3/search/#search-labels +// GitHub API docs: https://docs.github.com/en/rest/reference/search/#search-labels func (s *SearchService) Labels(ctx context.Context, repoID int64, query string, opts *SearchOptions) (*LabelsSearchResult, *Response, error) { result := new(LabelsSearchResult) resp, err := s.search(ctx, "labels", &searchParameters{RepositoryID: &repoID, Query: query}, opts, result) diff --git a/github/teams.go b/github/teams.go index 8b3611225cf..4e5e09b6848 100644 --- a/github/teams.go +++ b/github/teams.go @@ -16,7 +16,7 @@ import ( // TeamsService provides access to the team-related functions // in the GitHub API. // -// GitHub API docs: https://developer.github.com/v3/teams/ +// GitHub API docs: https://docs.github.com/en/rest/reference/teams/ type TeamsService service // Team represents a team within a GitHub organization. Teams are used to @@ -75,7 +75,7 @@ func (i Invitation) String() string { // ListTeams lists all of the teams for an organization. // -// GitHub API docs: https://developer.github.com/v3/teams/#list-teams +// GitHub API docs: https://docs.github.com/en/rest/reference/teams/#list-teams func (s *TeamsService) ListTeams(ctx context.Context, org string, opts *ListOptions) ([]*Team, *Response, error) { u := fmt.Sprintf("orgs/%v/teams", org) u, err := addOptions(u, opts) @@ -99,7 +99,7 @@ func (s *TeamsService) ListTeams(ctx context.Context, org string, opts *ListOpti // GetTeamByID fetches a team, given a specified organization ID, by ID. // -// GitHub API docs: https://developer.github.com/v3/teams/#get-a-team-by-name +// GitHub API docs: https://docs.github.com/en/rest/reference/teams/#get-a-team-by-name func (s *TeamsService) GetTeamByID(ctx context.Context, orgID, teamID int64) (*Team, *Response, error) { u := fmt.Sprintf("organizations/%v/team/%v", orgID, teamID) req, err := s.client.NewRequest("GET", u, nil) @@ -118,7 +118,7 @@ func (s *TeamsService) GetTeamByID(ctx context.Context, orgID, teamID int64) (*T // GetTeamBySlug fetches a team, given a specified organization name, by slug. // -// GitHub API docs: https://developer.github.com/v3/teams/#get-a-team-by-name +// GitHub API docs: https://docs.github.com/en/rest/reference/teams/#get-a-team-by-name func (s *TeamsService) GetTeamBySlug(ctx context.Context, org, slug string) (*Team, *Response, error) { u := fmt.Sprintf("orgs/%v/teams/%v", org, slug) req, err := s.client.NewRequest("GET", u, nil) @@ -168,7 +168,7 @@ func (s NewTeam) String() string { // CreateTeam creates a new team within an organization. // -// GitHub API docs: https://developer.github.com/v3/teams/#create-a-team +// GitHub API docs: https://docs.github.com/en/rest/reference/teams/#create-a-team func (s *TeamsService) CreateTeam(ctx context.Context, org string, team NewTeam) (*Team, *Response, error) { u := fmt.Sprintf("orgs/%v/teams", org) req, err := s.client.NewRequest("POST", u, team) @@ -214,7 +214,7 @@ func copyNewTeamWithoutParent(team *NewTeam) *newTeamNoParent { // EditTeamByID edits a team, given an organization ID, selected by ID. // -// GitHub API docs: https://developer.github.com/v3/teams/#update-a-team +// GitHub API docs: https://docs.github.com/en/rest/reference/teams/#update-a-team func (s *TeamsService) EditTeamByID(ctx context.Context, orgID, teamID int64, team NewTeam, removeParent bool) (*Team, *Response, error) { u := fmt.Sprintf("organizations/%v/team/%v", orgID, teamID) @@ -241,7 +241,7 @@ func (s *TeamsService) EditTeamByID(ctx context.Context, orgID, teamID int64, te // EditTeamBySlug edits a team, given an organization name, by slug. // -// GitHub API docs: https://developer.github.com/v3/teams/#update-a-team +// GitHub API docs: https://docs.github.com/en/rest/reference/teams/#update-a-team func (s *TeamsService) EditTeamBySlug(ctx context.Context, org, slug string, team NewTeam, removeParent bool) (*Team, *Response, error) { u := fmt.Sprintf("orgs/%v/teams/%v", org, slug) @@ -268,7 +268,7 @@ func (s *TeamsService) EditTeamBySlug(ctx context.Context, org, slug string, tea // DeleteTeamByID deletes a team referenced by ID. // -// GitHub API docs: https://developer.github.com/v3/teams/#delete-a-team +// GitHub API docs: https://docs.github.com/en/rest/reference/teams/#delete-a-team func (s *TeamsService) DeleteTeamByID(ctx context.Context, orgID, teamID int64) (*Response, error) { u := fmt.Sprintf("organizations/%v/team/%v", orgID, teamID) req, err := s.client.NewRequest("DELETE", u, nil) @@ -281,7 +281,7 @@ func (s *TeamsService) DeleteTeamByID(ctx context.Context, orgID, teamID int64) // DeleteTeamBySlug deletes a team reference by slug. // -// GitHub API docs: https://developer.github.com/v3/teams/#delete-a-team +// GitHub API docs: https://docs.github.com/en/rest/reference/teams/#delete-a-team func (s *TeamsService) DeleteTeamBySlug(ctx context.Context, org, slug string) (*Response, error) { u := fmt.Sprintf("orgs/%v/teams/%v", org, slug) req, err := s.client.NewRequest("DELETE", u, nil) @@ -294,7 +294,7 @@ func (s *TeamsService) DeleteTeamBySlug(ctx context.Context, org, slug string) ( // ListChildTeamsByParentID lists child teams for a parent team given parent ID. // -// GitHub API docs: https://developer.github.com/v3/teams/#list-child-teams +// GitHub API docs: https://docs.github.com/en/rest/reference/teams/#list-child-teams func (s *TeamsService) ListChildTeamsByParentID(ctx context.Context, orgID, teamID int64, opts *ListOptions) ([]*Team, *Response, error) { u := fmt.Sprintf("organizations/%v/team/%v/teams", orgID, teamID) u, err := addOptions(u, opts) @@ -318,7 +318,7 @@ func (s *TeamsService) ListChildTeamsByParentID(ctx context.Context, orgID, team // ListChildTeamsByParentSlug lists child teams for a parent team given parent slug. // -// GitHub API docs: https://developer.github.com/v3/teams/#list-child-teams +// GitHub API docs: https://docs.github.com/en/rest/reference/teams/#list-child-teams func (s *TeamsService) ListChildTeamsByParentSlug(ctx context.Context, org, slug string, opts *ListOptions) ([]*Team, *Response, error) { u := fmt.Sprintf("orgs/%v/teams/%v/teams", org, slug) u, err := addOptions(u, opts) @@ -342,7 +342,7 @@ func (s *TeamsService) ListChildTeamsByParentSlug(ctx context.Context, org, slug // ListTeamReposByID lists the repositories given a team ID that the specified team has access to. // -// GitHub API docs: https://developer.github.com/v3/teams/#list-team-repositories +// GitHub API docs: https://docs.github.com/en/rest/reference/teams/#list-team-repositories func (s *TeamsService) ListTeamReposByID(ctx context.Context, orgID, teamID int64, opts *ListOptions) ([]*Repository, *Response, error) { u := fmt.Sprintf("organizations/%v/team/%v/repos", orgID, teamID) u, err := addOptions(u, opts) @@ -370,7 +370,7 @@ func (s *TeamsService) ListTeamReposByID(ctx context.Context, orgID, teamID int6 // ListTeamReposBySlug lists the repositories given a team slug that the specified team has access to. // -// GitHub API docs: https://developer.github.com/v3/teams/#list-team-repositories +// GitHub API docs: https://docs.github.com/en/rest/reference/teams/#list-team-repositories func (s *TeamsService) ListTeamReposBySlug(ctx context.Context, org, slug string, opts *ListOptions) ([]*Repository, *Response, error) { u := fmt.Sprintf("orgs/%v/teams/%v/repos", org, slug) u, err := addOptions(u, opts) @@ -400,7 +400,7 @@ func (s *TeamsService) ListTeamReposBySlug(ctx context.Context, org, slug string // repository is managed by team, a Repository is returned which includes the // permissions team has for that repo. // -// GitHub API docs: https://developer.github.com/v3/teams/#check-team-permissions-for-a-repository +// GitHub API docs: https://docs.github.com/en/rest/reference/teams/#check-team-permissions-for-a-repository func (s *TeamsService) IsTeamRepoByID(ctx context.Context, orgID, teamID int64, owner, repo string) (*Repository, *Response, error) { u := fmt.Sprintf("organizations/%v/team/%v/repos/%v/%v", orgID, teamID, owner, repo) req, err := s.client.NewRequest("GET", u, nil) @@ -424,7 +424,7 @@ func (s *TeamsService) IsTeamRepoByID(ctx context.Context, orgID, teamID int64, // repository is managed by team, a Repository is returned which includes the // permissions team has for that repo. // -// GitHub API docs: https://developer.github.com/v3/teams/#check-team-permissions-for-a-repository +// GitHub API docs: https://docs.github.com/en/rest/reference/teams/#check-team-permissions-for-a-repository func (s *TeamsService) IsTeamRepoBySlug(ctx context.Context, org, slug, owner, repo string) (*Repository, *Response, error) { u := fmt.Sprintf("orgs/%v/teams/%v/repos/%v/%v", org, slug, owner, repo) req, err := s.client.NewRequest("GET", u, nil) @@ -463,7 +463,7 @@ type TeamAddTeamRepoOptions struct { // The specified repository must be owned by the organization to which the team // belongs, or a direct fork of a repository owned by the organization. // -// GitHub API docs: https://developer.github.com/v3/teams/#add-or-update-team-repository-permissions +// GitHub API docs: https://docs.github.com/en/rest/reference/teams/#add-or-update-team-repository-permissions func (s *TeamsService) AddTeamRepoByID(ctx context.Context, orgID, teamID int64, owner, repo string, opts *TeamAddTeamRepoOptions) (*Response, error) { u := fmt.Sprintf("organizations/%v/team/%v/repos/%v/%v", orgID, teamID, owner, repo) req, err := s.client.NewRequest("PUT", u, opts) @@ -478,7 +478,7 @@ func (s *TeamsService) AddTeamRepoByID(ctx context.Context, orgID, teamID int64, // The specified repository must be owned by the organization to which the team // belongs, or a direct fork of a repository owned by the organization. // -// GitHub API docs: https://developer.github.com/v3/teams/#add-or-update-team-repository-permissions +// GitHub API docs: https://docs.github.com/en/rest/reference/teams/#add-or-update-team-repository-permissions func (s *TeamsService) AddTeamRepoBySlug(ctx context.Context, org, slug, owner, repo string, opts *TeamAddTeamRepoOptions) (*Response, error) { u := fmt.Sprintf("orgs/%v/teams/%v/repos/%v/%v", org, slug, owner, repo) req, err := s.client.NewRequest("PUT", u, opts) @@ -493,7 +493,7 @@ func (s *TeamsService) AddTeamRepoBySlug(ctx context.Context, org, slug, owner, // team given the team ID. Note that this does not delete the repository, it // just removes it from the team. // -// GitHub API docs: https://developer.github.com/v3/teams/#remove-a-repository-from-a-team +// GitHub API docs: https://docs.github.com/en/rest/reference/teams/#remove-a-repository-from-a-team func (s *TeamsService) RemoveTeamRepoByID(ctx context.Context, orgID, teamID int64, owner, repo string) (*Response, error) { u := fmt.Sprintf("organizations/%v/team/%v/repos/%v/%v", orgID, teamID, owner, repo) req, err := s.client.NewRequest("DELETE", u, nil) @@ -508,7 +508,7 @@ func (s *TeamsService) RemoveTeamRepoByID(ctx context.Context, orgID, teamID int // team given the team slug. Note that this does not delete the repository, it // just removes it from the team. // -// GitHub API docs: https://developer.github.com/v3/teams/#remove-a-repository-from-a-team +// GitHub API docs: https://docs.github.com/en/rest/reference/teams/#remove-a-repository-from-a-team func (s *TeamsService) RemoveTeamRepoBySlug(ctx context.Context, org, slug, owner, repo string) (*Response, error) { u := fmt.Sprintf("orgs/%v/teams/%v/repos/%v/%v", org, slug, owner, repo) req, err := s.client.NewRequest("DELETE", u, nil) @@ -520,7 +520,7 @@ func (s *TeamsService) RemoveTeamRepoBySlug(ctx context.Context, org, slug, owne } // ListUserTeams lists a user's teams -// GitHub API docs: https://developer.github.com/v3/teams/#list-teams-for-the-authenticated-user +// GitHub API docs: https://docs.github.com/en/rest/reference/teams/#list-teams-for-the-authenticated-user func (s *TeamsService) ListUserTeams(ctx context.Context, opts *ListOptions) ([]*Team, *Response, error) { u := "user/teams" u, err := addOptions(u, opts) @@ -544,7 +544,7 @@ func (s *TeamsService) ListUserTeams(ctx context.Context, opts *ListOptions) ([] // ListTeamProjectsByID lists the organization projects for a team given the team ID. // -// GitHub API docs: https://developer.github.com/v3/teams/#list-team-projects +// GitHub API docs: https://docs.github.com/en/rest/reference/teams/#list-team-projects func (s *TeamsService) ListTeamProjectsByID(ctx context.Context, orgID, teamID int64) ([]*Project, *Response, error) { u := fmt.Sprintf("organizations/%v/team/%v/projects", orgID, teamID) @@ -568,7 +568,7 @@ func (s *TeamsService) ListTeamProjectsByID(ctx context.Context, orgID, teamID i // ListTeamProjectsBySlug lists the organization projects for a team given the team slug. // -// GitHub API docs: https://developer.github.com/v3/teams/#list-team-projects +// GitHub API docs: https://docs.github.com/en/rest/reference/teams/#list-team-projects func (s *TeamsService) ListTeamProjectsBySlug(ctx context.Context, org, slug string) ([]*Project, *Response, error) { u := fmt.Sprintf("orgs/%v/teams/%v/projects", org, slug) @@ -593,7 +593,7 @@ func (s *TeamsService) ListTeamProjectsBySlug(ctx context.Context, org, slug str // ReviewTeamProjectsByID checks whether a team, given its ID, has read, write, or admin // permissions for an organization project. // -// GitHub API docs: https://developer.github.com/v3/teams/#check-team-permissions-for-a-project +// GitHub API docs: https://docs.github.com/en/rest/reference/teams/#check-team-permissions-for-a-project func (s *TeamsService) ReviewTeamProjectsByID(ctx context.Context, orgID, teamID, projectID int64) (*Project, *Response, error) { u := fmt.Sprintf("organizations/%v/team/%v/projects/%v", orgID, teamID, projectID) req, err := s.client.NewRequest("GET", u, nil) @@ -617,7 +617,7 @@ func (s *TeamsService) ReviewTeamProjectsByID(ctx context.Context, orgID, teamID // ReviewTeamProjectsBySlug checks whether a team, given its slug, has read, write, or admin // permissions for an organization project. // -// GitHub API docs: https://developer.github.com/v3/teams/#check-team-permissions-for-a-project +// GitHub API docs: https://docs.github.com/en/rest/reference/teams/#check-team-permissions-for-a-project func (s *TeamsService) ReviewTeamProjectsBySlug(ctx context.Context, org, slug string, projectID int64) (*Project, *Response, error) { u := fmt.Sprintf("orgs/%v/teams/%v/projects/%v", org, slug, projectID) req, err := s.client.NewRequest("GET", u, nil) @@ -654,7 +654,7 @@ type TeamProjectOptions struct { // To add a project to a team or update the team's permission on a project, the // authenticated user must have admin permissions for the project. // -// GitHub API docs: https://developer.github.com/v3/teams/#add-or-update-team-project-permissions +// GitHub API docs: https://docs.github.com/en/rest/reference/teams/#add-or-update-team-project-permissions func (s *TeamsService) AddTeamProjectByID(ctx context.Context, orgID, teamID, projectID int64, opts *TeamProjectOptions) (*Response, error) { u := fmt.Sprintf("organizations/%v/team/%v/projects/%v", orgID, teamID, projectID) req, err := s.client.NewRequest("PUT", u, opts) @@ -673,7 +673,7 @@ func (s *TeamsService) AddTeamProjectByID(ctx context.Context, orgID, teamID, pr // To add a project to a team or update the team's permission on a project, the // authenticated user must have admin permissions for the project. // -// GitHub API docs: https://developer.github.com/v3/teams/#add-or-update-team-project-permissions +// GitHub API docs: https://docs.github.com/en/rest/reference/teams/#add-or-update-team-project-permissions func (s *TeamsService) AddTeamProjectBySlug(ctx context.Context, org, slug string, projectID int64, opts *TeamProjectOptions) (*Response, error) { u := fmt.Sprintf("orgs/%v/teams/%v/projects/%v", org, slug, projectID) req, err := s.client.NewRequest("PUT", u, opts) @@ -695,7 +695,7 @@ func (s *TeamsService) AddTeamProjectBySlug(ctx context.Context, org, slug strin // or project. // Note: This endpoint removes the project from the team, but does not delete it. // -// GitHub API docs: https://developer.github.com/v3/teams/#remove-a-project-from-a-team +// GitHub API docs: https://docs.github.com/en/rest/reference/teams/#remove-a-project-from-a-team func (s *TeamsService) RemoveTeamProjectByID(ctx context.Context, orgID, teamID, projectID int64) (*Response, error) { u := fmt.Sprintf("organizations/%v/team/%v/projects/%v", orgID, teamID, projectID) req, err := s.client.NewRequest("DELETE", u, nil) @@ -717,7 +717,7 @@ func (s *TeamsService) RemoveTeamProjectByID(ctx context.Context, orgID, teamID, // or project. // Note: This endpoint removes the project from the team, but does not delete it. // -// GitHub API docs: https://developer.github.com/v3/teams/#remove-a-project-from-a-team +// GitHub API docs: https://docs.github.com/en/rest/reference/teams/#remove-a-project-from-a-team func (s *TeamsService) RemoveTeamProjectBySlug(ctx context.Context, org, slug string, projectID int64) (*Response, error) { u := fmt.Sprintf("orgs/%v/teams/%v/projects/%v", org, slug, projectID) req, err := s.client.NewRequest("DELETE", u, nil) @@ -746,7 +746,7 @@ type IDPGroup struct { // ListIDPGroupsInOrganization lists IDP groups available in an organization. // -// GitHub API docs: https://developer.github.com/v3/teams/team_sync/#list-idp-groups-for-an-organization +// GitHub API docs: https://docs.github.com/en/rest/reference/teams/#list-idp-groups-for-an-organization func (s *TeamsService) ListIDPGroupsInOrganization(ctx context.Context, org string, opts *ListCursorOptions) (*IDPGroupList, *Response, error) { u := fmt.Sprintf("orgs/%v/team-sync/groups", org) u, err := addOptions(u, opts) @@ -770,7 +770,7 @@ func (s *TeamsService) ListIDPGroupsInOrganization(ctx context.Context, org stri // ListIDPGroupsForTeamByID lists IDP groups connected to a team on GitHub // given organization and team IDs. // -// GitHub API docs: https://developer.github.com/v3/teams/team_sync/#list-idp-groups-for-a-team +// GitHub API docs: https://docs.github.com/en/rest/reference/teams/#list-idp-groups-for-a-team func (s *TeamsService) ListIDPGroupsForTeamByID(ctx context.Context, orgID, teamID int64) (*IDPGroupList, *Response, error) { u := fmt.Sprintf("organizations/%v/team/%v/team-sync/group-mappings", orgID, teamID) @@ -790,7 +790,7 @@ func (s *TeamsService) ListIDPGroupsForTeamByID(ctx context.Context, orgID, team // ListIDPGroupsForTeamBySlug lists IDP groups connected to a team on GitHub // given organization name and team slug. // -// GitHub API docs: https://developer.github.com/v3/teams/team_sync/#list-idp-groups-for-a-team +// GitHub API docs: https://docs.github.com/en/rest/reference/teams/#list-idp-groups-for-a-team func (s *TeamsService) ListIDPGroupsForTeamBySlug(ctx context.Context, org, slug string) (*IDPGroupList, *Response, error) { u := fmt.Sprintf("orgs/%v/teams/%v/team-sync/group-mappings", org, slug) @@ -810,7 +810,7 @@ func (s *TeamsService) ListIDPGroupsForTeamBySlug(ctx context.Context, org, slug // CreateOrUpdateIDPGroupConnectionsByID creates, updates, or removes a connection // between a team and an IDP group given organization and team IDs. // -// GitHub API docs: https://developer.github.com/v3/teams/team_sync/#create-or-update-idp-group-connections +// GitHub API docs: https://docs.github.com/en/rest/reference/teams/#create-or-update-idp-group-connections func (s *TeamsService) CreateOrUpdateIDPGroupConnectionsByID(ctx context.Context, orgID, teamID int64, opts IDPGroupList) (*IDPGroupList, *Response, error) { u := fmt.Sprintf("organizations/%v/team/%v/team-sync/group-mappings", orgID, teamID) @@ -831,7 +831,7 @@ func (s *TeamsService) CreateOrUpdateIDPGroupConnectionsByID(ctx context.Context // CreateOrUpdateIDPGroupConnectionsBySlug creates, updates, or removes a connection // between a team and an IDP group given organization name and team slug. // -// GitHub API docs: https://developer.github.com/v3/teams/team_sync/#create-or-update-idp-group-connections +// GitHub API docs: https://docs.github.com/en/rest/reference/teams/#create-or-update-idp-group-connections func (s *TeamsService) CreateOrUpdateIDPGroupConnectionsBySlug(ctx context.Context, org, slug string, opts IDPGroupList) (*IDPGroupList, *Response, error) { u := fmt.Sprintf("orgs/%v/teams/%v/team-sync/group-mappings", org, slug) diff --git a/github/teams_discussion_comments.go b/github/teams_discussion_comments.go index 5bdda665a0d..547927d6812 100644 --- a/github/teams_discussion_comments.go +++ b/github/teams_discussion_comments.go @@ -43,7 +43,7 @@ type DiscussionCommentListOptions struct { // ListCommentsByID lists all comments on a team discussion by team ID. // Authenticated user must grant read:discussion scope. // -// GitHub API docs: https://developer.github.com/v3/teams/discussion_comments/#list-discussion-comments +// GitHub API docs: https://docs.github.com/en/rest/reference/teams/#list-discussion-comments func (s *TeamsService) ListCommentsByID(ctx context.Context, orgID, teamID int64, discussionNumber int, options *DiscussionCommentListOptions) ([]*DiscussionComment, *Response, error) { u := fmt.Sprintf("organizations/%v/team/%v/discussions/%v/comments", orgID, teamID, discussionNumber) u, err := addOptions(u, options) @@ -68,7 +68,7 @@ func (s *TeamsService) ListCommentsByID(ctx context.Context, orgID, teamID int64 // ListCommentsBySlug lists all comments on a team discussion by team slug. // Authenticated user must grant read:discussion scope. // -// GitHub API docs: https://developer.github.com/v3/teams/discussion_comments/#list-discussion-comments +// GitHub API docs: https://docs.github.com/en/rest/reference/teams/#list-discussion-comments func (s *TeamsService) ListCommentsBySlug(ctx context.Context, org, slug string, discussionNumber int, options *DiscussionCommentListOptions) ([]*DiscussionComment, *Response, error) { u := fmt.Sprintf("orgs/%v/teams/%v/discussions/%v/comments", org, slug, discussionNumber) u, err := addOptions(u, options) @@ -93,7 +93,7 @@ func (s *TeamsService) ListCommentsBySlug(ctx context.Context, org, slug string, // GetCommentByID gets a specific comment on a team discussion by team ID. // Authenticated user must grant read:discussion scope. // -// GitHub API docs: https://developer.github.com/v3/teams/discussion_comments/#get-a-discussion-comment +// GitHub API docs: https://docs.github.com/en/rest/reference/teams/#get-a-discussion-comment func (s *TeamsService) GetCommentByID(ctx context.Context, orgID, teamID int64, discussionNumber, commentNumber int) (*DiscussionComment, *Response, error) { u := fmt.Sprintf("organizations/%v/team/%v/discussions/%v/comments/%v", orgID, teamID, discussionNumber, commentNumber) req, err := s.client.NewRequest("GET", u, nil) @@ -113,7 +113,7 @@ func (s *TeamsService) GetCommentByID(ctx context.Context, orgID, teamID int64, // GetCommentBySlug gets a specific comment on a team discussion by team slug. // Authenticated user must grant read:discussion scope. // -// GitHub API docs: https://developer.github.com/v3/teams/discussion_comments/#get-a-discussion-comment +// GitHub API docs: https://docs.github.com/en/rest/reference/teams/#get-a-discussion-comment func (s *TeamsService) GetCommentBySlug(ctx context.Context, org, slug string, discussionNumber, commentNumber int) (*DiscussionComment, *Response, error) { u := fmt.Sprintf("orgs/%v/teams/%v/discussions/%v/comments/%v", org, slug, discussionNumber, commentNumber) @@ -134,7 +134,7 @@ func (s *TeamsService) GetCommentBySlug(ctx context.Context, org, slug string, d // CreateCommentByID creates a new comment on a team discussion by team ID. // Authenticated user must grant write:discussion scope. // -// GitHub API docs: https://developer.github.com/v3/teams/discussion_comments/#create-a-discussion-comment +// GitHub API docs: https://docs.github.com/en/rest/reference/teams/#create-a-discussion-comment func (s *TeamsService) CreateCommentByID(ctx context.Context, orgID, teamID int64, discsusionNumber int, comment DiscussionComment) (*DiscussionComment, *Response, error) { u := fmt.Sprintf("organizations/%v/team/%v/discussions/%v/comments", orgID, teamID, discsusionNumber) req, err := s.client.NewRequest("POST", u, comment) @@ -154,7 +154,7 @@ func (s *TeamsService) CreateCommentByID(ctx context.Context, orgID, teamID int6 // CreateCommentBySlug creates a new comment on a team discussion by team slug. // Authenticated user must grant write:discussion scope. // -// GitHub API docs: https://developer.github.com/v3/teams/discussion_comments/#create-a-discussion-comment +// GitHub API docs: https://docs.github.com/en/rest/reference/teams/#create-a-discussion-comment func (s *TeamsService) CreateCommentBySlug(ctx context.Context, org, slug string, discsusionNumber int, comment DiscussionComment) (*DiscussionComment, *Response, error) { u := fmt.Sprintf("orgs/%v/teams/%v/discussions/%v/comments", org, slug, discsusionNumber) req, err := s.client.NewRequest("POST", u, comment) @@ -175,7 +175,7 @@ func (s *TeamsService) CreateCommentBySlug(ctx context.Context, org, slug string // Authenticated user must grant write:discussion scope. // User is allowed to edit body of a comment only. // -// GitHub API docs: https://developer.github.com/v3/teams/discussion_comments/#update-a-discussion-comment +// GitHub API docs: https://docs.github.com/en/rest/reference/teams/#update-a-discussion-comment func (s *TeamsService) EditCommentByID(ctx context.Context, orgID, teamID int64, discussionNumber, commentNumber int, comment DiscussionComment) (*DiscussionComment, *Response, error) { u := fmt.Sprintf("organizations/%v/team/%v/discussions/%v/comments/%v", orgID, teamID, discussionNumber, commentNumber) req, err := s.client.NewRequest("PATCH", u, comment) @@ -196,7 +196,7 @@ func (s *TeamsService) EditCommentByID(ctx context.Context, orgID, teamID int64, // Authenticated user must grant write:discussion scope. // User is allowed to edit body of a comment only. // -// GitHub API docs: https://developer.github.com/v3/teams/discussion_comments/#update-a-discussion-comment +// GitHub API docs: https://docs.github.com/en/rest/reference/teams/#update-a-discussion-comment func (s *TeamsService) EditCommentBySlug(ctx context.Context, org, slug string, discussionNumber, commentNumber int, comment DiscussionComment) (*DiscussionComment, *Response, error) { u := fmt.Sprintf("orgs/%v/teams/%v/discussions/%v/comments/%v", org, slug, discussionNumber, commentNumber) req, err := s.client.NewRequest("PATCH", u, comment) @@ -216,7 +216,7 @@ func (s *TeamsService) EditCommentBySlug(ctx context.Context, org, slug string, // DeleteCommentByID deletes a comment on a team discussion by team ID. // Authenticated user must grant write:discussion scope. // -// GitHub API docs: https://developer.github.com/v3/teams/discussion_comments/#delete-a-discussion-comment +// GitHub API docs: https://docs.github.com/en/rest/reference/teams/#delete-a-discussion-comment func (s *TeamsService) DeleteCommentByID(ctx context.Context, orgID, teamID int64, discussionNumber, commentNumber int) (*Response, error) { u := fmt.Sprintf("organizations/%v/team/%v/discussions/%v/comments/%v", orgID, teamID, discussionNumber, commentNumber) req, err := s.client.NewRequest("DELETE", u, nil) @@ -230,7 +230,7 @@ func (s *TeamsService) DeleteCommentByID(ctx context.Context, orgID, teamID int6 // DeleteCommentBySlug deletes a comment on a team discussion by team slug. // Authenticated user must grant write:discussion scope. // -// GitHub API docs: https://developer.github.com/v3/teams/discussion_comments/#delete-a-discussion-comment +// GitHub API docs: https://docs.github.com/en/rest/reference/teams/#delete-a-discussion-comment func (s *TeamsService) DeleteCommentBySlug(ctx context.Context, org, slug string, discussionNumber, commentNumber int) (*Response, error) { u := fmt.Sprintf("orgs/%v/teams/%v/discussions/%v/comments/%v", org, slug, discussionNumber, commentNumber) req, err := s.client.NewRequest("DELETE", u, nil) diff --git a/github/teams_discussions.go b/github/teams_discussions.go index 17abe5d5e65..976bd6b719b 100644 --- a/github/teams_discussions.go +++ b/github/teams_discussions.go @@ -49,7 +49,7 @@ type DiscussionListOptions struct { // ListDiscussionsByID lists all discussions on team's page given Organization and Team ID. // Authenticated user must grant read:discussion scope. // -// GitHub API docs: https://developer.github.com/v3/teams/discussions/#list-discussions +// GitHub API docs: https://docs.github.com/en/rest/reference/teams/#list-discussions func (s *TeamsService) ListDiscussionsByID(ctx context.Context, orgID, teamID int64, opts *DiscussionListOptions) ([]*TeamDiscussion, *Response, error) { u := fmt.Sprintf("organizations/%v/team/%v/discussions", orgID, teamID) u, err := addOptions(u, opts) @@ -74,7 +74,7 @@ func (s *TeamsService) ListDiscussionsByID(ctx context.Context, orgID, teamID in // ListDiscussionsBySlug lists all discussions on team's page given Organization name and Team's slug. // Authenticated user must grant read:discussion scope. // -// GitHub API docs: https://developer.github.com/v3/teams/discussions/#list-discussions +// GitHub API docs: https://docs.github.com/en/rest/reference/teams/#list-discussions func (s *TeamsService) ListDiscussionsBySlug(ctx context.Context, org, slug string, opts *DiscussionListOptions) ([]*TeamDiscussion, *Response, error) { u := fmt.Sprintf("orgs/%v/teams/%v/discussions", org, slug) u, err := addOptions(u, opts) @@ -99,7 +99,7 @@ func (s *TeamsService) ListDiscussionsBySlug(ctx context.Context, org, slug stri // GetDiscussionByID gets a specific discussion on a team's page given Organization and Team ID. // Authenticated user must grant read:discussion scope. // -// GitHub API docs: https://developer.github.com/v3/teams/discussions/#get-a-discussion +// GitHub API docs: https://docs.github.com/en/rest/reference/teams/#get-a-discussion func (s *TeamsService) GetDiscussionByID(ctx context.Context, orgID, teamID int64, discussionNumber int) (*TeamDiscussion, *Response, error) { u := fmt.Sprintf("organizations/%v/team/%v/discussions/%v", orgID, teamID, discussionNumber) req, err := s.client.NewRequest("GET", u, nil) @@ -119,7 +119,7 @@ func (s *TeamsService) GetDiscussionByID(ctx context.Context, orgID, teamID int6 // GetDiscussionBySlug gets a specific discussion on a team's page given Organization name and Team's slug. // Authenticated user must grant read:discussion scope. // -// GitHub API docs: https://developer.github.com/v3/teams/discussions/#get-a-discussion +// GitHub API docs: https://docs.github.com/en/rest/reference/teams/#get-a-discussion func (s *TeamsService) GetDiscussionBySlug(ctx context.Context, org, slug string, discussionNumber int) (*TeamDiscussion, *Response, error) { u := fmt.Sprintf("orgs/%v/teams/%v/discussions/%v", org, slug, discussionNumber) req, err := s.client.NewRequest("GET", u, nil) @@ -139,7 +139,7 @@ func (s *TeamsService) GetDiscussionBySlug(ctx context.Context, org, slug string // CreateDiscussionByID creates a new discussion post on a team's page given Organization and Team ID. // Authenticated user must grant write:discussion scope. // -// GitHub API docs: https://developer.github.com/v3/teams/discussions/#create-a-discussion +// GitHub API docs: https://docs.github.com/en/rest/reference/teams/#create-a-discussion func (s *TeamsService) CreateDiscussionByID(ctx context.Context, orgID, teamID int64, discussion TeamDiscussion) (*TeamDiscussion, *Response, error) { u := fmt.Sprintf("organizations/%v/team/%v/discussions", orgID, teamID) req, err := s.client.NewRequest("POST", u, discussion) @@ -159,7 +159,7 @@ func (s *TeamsService) CreateDiscussionByID(ctx context.Context, orgID, teamID i // CreateDiscussionBySlug creates a new discussion post on a team's page given Organization name and Team's slug. // Authenticated user must grant write:discussion scope. // -// GitHub API docs: https://developer.github.com/v3/teams/discussions/#create-a-discussion +// GitHub API docs: https://docs.github.com/en/rest/reference/teams/#create-a-discussion func (s *TeamsService) CreateDiscussionBySlug(ctx context.Context, org, slug string, discussion TeamDiscussion) (*TeamDiscussion, *Response, error) { u := fmt.Sprintf("orgs/%v/teams/%v/discussions", org, slug) req, err := s.client.NewRequest("POST", u, discussion) @@ -180,7 +180,7 @@ func (s *TeamsService) CreateDiscussionBySlug(ctx context.Context, org, slug str // Authenticated user must grant write:discussion scope. // User is allowed to change Title and Body of a discussion only. // -// GitHub API docs: https://developer.github.com/v3/teams/discussions/#update-a-discussion +// GitHub API docs: https://docs.github.com/en/rest/reference/teams/#update-a-discussion func (s *TeamsService) EditDiscussionByID(ctx context.Context, orgID, teamID int64, discussionNumber int, discussion TeamDiscussion) (*TeamDiscussion, *Response, error) { u := fmt.Sprintf("organizations/%v/team/%v/discussions/%v", orgID, teamID, discussionNumber) req, err := s.client.NewRequest("PATCH", u, discussion) @@ -201,7 +201,7 @@ func (s *TeamsService) EditDiscussionByID(ctx context.Context, orgID, teamID int // Authenticated user must grant write:discussion scope. // User is allowed to change Title and Body of a discussion only. // -// GitHub API docs: https://developer.github.com/v3/teams/discussions/#update-a-discussion +// GitHub API docs: https://docs.github.com/en/rest/reference/teams/#update-a-discussion func (s *TeamsService) EditDiscussionBySlug(ctx context.Context, org, slug string, discussionNumber int, discussion TeamDiscussion) (*TeamDiscussion, *Response, error) { u := fmt.Sprintf("orgs/%v/teams/%v/discussions/%v", org, slug, discussionNumber) req, err := s.client.NewRequest("PATCH", u, discussion) @@ -221,7 +221,7 @@ func (s *TeamsService) EditDiscussionBySlug(ctx context.Context, org, slug strin // DeleteDiscussionByID deletes a discussion from team's page given Organization and Team ID. // Authenticated user must grant write:discussion scope. // -// GitHub API docs: https://developer.github.com/v3/teams/discussions/#delete-a-discussion +// GitHub API docs: https://docs.github.com/en/rest/reference/teams/#delete-a-discussion func (s *TeamsService) DeleteDiscussionByID(ctx context.Context, orgID, teamID int64, discussionNumber int) (*Response, error) { u := fmt.Sprintf("organizations/%v/team/%v/discussions/%v", orgID, teamID, discussionNumber) req, err := s.client.NewRequest("DELETE", u, nil) @@ -235,7 +235,7 @@ func (s *TeamsService) DeleteDiscussionByID(ctx context.Context, orgID, teamID i // DeleteDiscussionBySlug deletes a discussion from team's page given Organization name and Team's slug. // Authenticated user must grant write:discussion scope. // -// GitHub API docs: https://developer.github.com/v3/teams/discussions/#delete-a-discussion +// GitHub API docs: https://docs.github.com/en/rest/reference/teams/#delete-a-discussion func (s *TeamsService) DeleteDiscussionBySlug(ctx context.Context, org, slug string, discussionNumber int) (*Response, error) { u := fmt.Sprintf("orgs/%v/teams/%v/discussions/%v", org, slug, discussionNumber) req, err := s.client.NewRequest("DELETE", u, nil) diff --git a/github/teams_members.go b/github/teams_members.go index c8c561f44b1..1dd59cef8bc 100644 --- a/github/teams_members.go +++ b/github/teams_members.go @@ -23,7 +23,7 @@ type TeamListTeamMembersOptions struct { // ListTeamMembersByID lists all of the users who are members of a team, given a specified // organization ID, by team ID. // -// GitHub API docs: https://developer.github.com/v3/teams/members/#list-team-members +// GitHub API docs: https://docs.github.com/en/rest/reference/teams/#list-team-members func (s *TeamsService) ListTeamMembersByID(ctx context.Context, orgID, teamID int64, opts *TeamListTeamMembersOptions) ([]*User, *Response, error) { u := fmt.Sprintf("organizations/%v/team/%v/members", orgID, teamID) u, err := addOptions(u, opts) @@ -48,7 +48,7 @@ func (s *TeamsService) ListTeamMembersByID(ctx context.Context, orgID, teamID in // ListTeamMembersBySlug lists all of the users who are members of a team, given a specified // organization name, by team slug. // -// GitHub API docs: https://developer.github.com/v3/teams/members/#list-team-members +// GitHub API docs: https://docs.github.com/en/rest/reference/teams/#list-team-members func (s *TeamsService) ListTeamMembersBySlug(ctx context.Context, org, slug string, opts *TeamListTeamMembersOptions) ([]*User, *Response, error) { u := fmt.Sprintf("orgs/%v/teams/%v/members", org, slug) u, err := addOptions(u, opts) @@ -73,7 +73,7 @@ func (s *TeamsService) ListTeamMembersBySlug(ctx context.Context, org, slug stri // GetTeamMembershipByID returns the membership status for a user in a team, given a specified // organization ID, by team ID. // -// GitHub API docs: https://developer.github.com/v3/teams/members/#get-team-membership-for-a-user +// GitHub API docs: https://docs.github.com/en/rest/reference/teams/#get-team-membership-for-a-user func (s *TeamsService) GetTeamMembershipByID(ctx context.Context, orgID, teamID int64, user string) (*Membership, *Response, error) { u := fmt.Sprintf("organizations/%v/team/%v/memberships/%v", orgID, teamID, user) req, err := s.client.NewRequest("GET", u, nil) @@ -93,7 +93,7 @@ func (s *TeamsService) GetTeamMembershipByID(ctx context.Context, orgID, teamID // GetTeamMembershipBySlug returns the membership status for a user in a team, given a specified // organization name, by team slug. // -// GitHub API docs: https://developer.github.com/v3/teams/members/#get-team-membership-for-a-user +// GitHub API docs: https://docs.github.com/en/rest/reference/teams/#get-team-membership-for-a-user func (s *TeamsService) GetTeamMembershipBySlug(ctx context.Context, org, slug, user string) (*Membership, *Response, error) { u := fmt.Sprintf("orgs/%v/teams/%v/memberships/%v", org, slug, user) req, err := s.client.NewRequest("GET", u, nil) @@ -127,7 +127,7 @@ type TeamAddTeamMembershipOptions struct { // AddTeamMembershipByID adds or invites a user to a team, given a specified // organization ID, by team ID. // -// GitHub API docs: https://developer.github.com/v3/teams/members/#add-or-update-team-membership-for-a-user +// GitHub API docs: https://docs.github.com/en/rest/reference/teams/#add-or-update-team-membership-for-a-user func (s *TeamsService) AddTeamMembershipByID(ctx context.Context, orgID, teamID int64, user string, opts *TeamAddTeamMembershipOptions) (*Membership, *Response, error) { u := fmt.Sprintf("organizations/%v/team/%v/memberships/%v", orgID, teamID, user) req, err := s.client.NewRequest("PUT", u, opts) @@ -147,7 +147,7 @@ func (s *TeamsService) AddTeamMembershipByID(ctx context.Context, orgID, teamID // AddTeamMembershipBySlug adds or invites a user to a team, given a specified // organization name, by team slug. // -// GitHub API docs: https://developer.github.com/v3/teams/members/#add-or-update-team-membership-for-a-user +// GitHub API docs: https://docs.github.com/en/rest/reference/teams/#add-or-update-team-membership-for-a-user func (s *TeamsService) AddTeamMembershipBySlug(ctx context.Context, org, slug, user string, opts *TeamAddTeamMembershipOptions) (*Membership, *Response, error) { u := fmt.Sprintf("orgs/%v/teams/%v/memberships/%v", org, slug, user) req, err := s.client.NewRequest("PUT", u, opts) @@ -167,7 +167,7 @@ func (s *TeamsService) AddTeamMembershipBySlug(ctx context.Context, org, slug, u // RemoveTeamMembershipByID removes a user from a team, given a specified // organization ID, by team ID. // -// GitHub API docs: https://developer.github.com/v3/teams/members/#remove-team-membership-for-a-user +// GitHub API docs: https://docs.github.com/en/rest/reference/teams/#remove-team-membership-for-a-user func (s *TeamsService) RemoveTeamMembershipByID(ctx context.Context, orgID, teamID int64, user string) (*Response, error) { u := fmt.Sprintf("organizations/%v/team/%v/memberships/%v", orgID, teamID, user) req, err := s.client.NewRequest("DELETE", u, nil) @@ -181,7 +181,7 @@ func (s *TeamsService) RemoveTeamMembershipByID(ctx context.Context, orgID, team // RemoveTeamMembershipBySlug removes a user from a team, given a specified // organization name, by team slug. // -// GitHub API docs: https://developer.github.com/v3/teams/members/#remove-team-membership-for-a-user +// GitHub API docs: https://docs.github.com/en/rest/reference/teams/#remove-team-membership-for-a-user func (s *TeamsService) RemoveTeamMembershipBySlug(ctx context.Context, org, slug, user string) (*Response, error) { u := fmt.Sprintf("orgs/%v/teams/%v/memberships/%v", org, slug, user) req, err := s.client.NewRequest("DELETE", u, nil) @@ -195,7 +195,7 @@ func (s *TeamsService) RemoveTeamMembershipBySlug(ctx context.Context, org, slug // ListPendingTeamInvitationsByID gets pending invitation list of a team, given a specified // organization ID, by team ID. // -// GitHub API docs: https://developer.github.com/v3/teams/members/#list-pending-team-invitations +// GitHub API docs: https://docs.github.com/en/rest/reference/teams/#list-pending-team-invitations func (s *TeamsService) ListPendingTeamInvitationsByID(ctx context.Context, orgID, teamID int64, opts *ListOptions) ([]*Invitation, *Response, error) { u := fmt.Sprintf("organizations/%v/team/%v/invitations", orgID, teamID) u, err := addOptions(u, opts) @@ -220,7 +220,7 @@ func (s *TeamsService) ListPendingTeamInvitationsByID(ctx context.Context, orgID // ListPendingTeamInvitationsBySlug get pending invitation list of a team, given a specified // organization name, by team slug. // -// GitHub API docs: https://developer.github.com/v3/teams/members/#list-pending-team-invitations +// GitHub API docs: https://docs.github.com/en/rest/reference/teams/#list-pending-team-invitations func (s *TeamsService) ListPendingTeamInvitationsBySlug(ctx context.Context, org, slug string, opts *ListOptions) ([]*Invitation, *Response, error) { u := fmt.Sprintf("orgs/%v/teams/%v/invitations", org, slug) u, err := addOptions(u, opts) diff --git a/github/users.go b/github/users.go index a387ee1f70e..129975a7fa5 100644 --- a/github/users.go +++ b/github/users.go @@ -13,7 +13,7 @@ import ( // UsersService handles communication with the user related // methods of the GitHub API. // -// GitHub API docs: https://developer.github.com/v3/users/ +// GitHub API docs: https://docs.github.com/en/rest/reference/users/ type UsersService service // User represents a GitHub user. @@ -63,7 +63,7 @@ type User struct { SubscriptionsURL *string `json:"subscriptions_url,omitempty"` // TextMatches is only populated from search results that request text matches - // See: search.go and https://developer.github.com/v3/search/#text-match-metadata + // See: search.go and https://docs.github.com/en/rest/reference/search/#text-match-metadata TextMatches []*TextMatch `json:"text_matches,omitempty"` // Permissions identifies the permissions that a user has on a given @@ -78,8 +78,8 @@ func (u User) String() string { // Get fetches a user. Passing the empty string will fetch the authenticated // user. // -// GitHub API docs: https://developer.github.com/v3/users/#get-the-authenticated-user -// GitHub API docs: https://developer.github.com/v3/users/#get-a-user +// GitHub API docs: https://docs.github.com/en/rest/reference/users/#get-the-authenticated-user +// GitHub API docs: https://docs.github.com/en/rest/reference/users/#get-a-user func (s *UsersService) Get(ctx context.Context, user string) (*User, *Response, error) { var u string if user != "" { @@ -122,7 +122,7 @@ func (s *UsersService) GetByID(ctx context.Context, id int64) (*User, *Response, // Edit the authenticated user. // -// GitHub API docs: https://developer.github.com/v3/users/#update-the-authenticated-user +// GitHub API docs: https://docs.github.com/en/rest/reference/users/#update-the-authenticated-user func (s *UsersService) Edit(ctx context.Context, user *User) (*User, *Response, error) { u := "user" req, err := s.client.NewRequest("PATCH", u, user) @@ -164,7 +164,7 @@ type UserContext struct { // GetHovercard fetches contextual information about user. It requires authentication // via Basic Auth or via OAuth with the repo scope. // -// GitHub API docs: https://developer.github.com/v3/users/#get-contextual-information-for-a-user +// GitHub API docs: https://docs.github.com/en/rest/reference/users/#get-contextual-information-for-a-user func (s *UsersService) GetHovercard(ctx context.Context, user string, opts *HovercardOptions) (*Hovercard, *Response, error) { u := fmt.Sprintf("users/%v/hovercard", user) u, err := addOptions(u, opts) @@ -202,7 +202,7 @@ type UserListOptions struct { // // To paginate through all users, populate 'Since' with the ID of the last user. // -// GitHub API docs: https://developer.github.com/v3/users/#list-users +// GitHub API docs: https://docs.github.com/en/rest/reference/users/#list-users func (s *UsersService) ListAll(ctx context.Context, opts *UserListOptions) ([]*User, *Response, error) { u, err := addOptions("users", opts) if err != nil { @@ -226,7 +226,7 @@ func (s *UsersService) ListAll(ctx context.Context, opts *UserListOptions) ([]*U // ListInvitations lists all currently-open repository invitations for the // authenticated user. // -// GitHub API docs: https://developer.github.com/v3/repos/invitations/#list-repository-invitations-for-the-authenticated-user +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#list-repository-invitations-for-the-authenticated-user func (s *UsersService) ListInvitations(ctx context.Context, opts *ListOptions) ([]*RepositoryInvitation, *Response, error) { u, err := addOptions("user/repository_invitations", opts) if err != nil { @@ -250,7 +250,7 @@ func (s *UsersService) ListInvitations(ctx context.Context, opts *ListOptions) ( // AcceptInvitation accepts the currently-open repository invitation for the // authenticated user. // -// GitHub API docs: https://developer.github.com/v3/repos/invitations/#accept-a-repository-invitation +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#accept-a-repository-invitation func (s *UsersService) AcceptInvitation(ctx context.Context, invitationID int64) (*Response, error) { u := fmt.Sprintf("user/repository_invitations/%v", invitationID) req, err := s.client.NewRequest("PATCH", u, nil) @@ -264,7 +264,7 @@ func (s *UsersService) AcceptInvitation(ctx context.Context, invitationID int64) // DeclineInvitation declines the currently-open repository invitation for the // authenticated user. // -// GitHub API docs: https://developer.github.com/v3/repos/invitations/#decline-a-repository-invitation +// GitHub API docs: https://docs.github.com/en/rest/reference/repos/#decline-a-repository-invitation func (s *UsersService) DeclineInvitation(ctx context.Context, invitationID int64) (*Response, error) { u := fmt.Sprintf("user/repository_invitations/%v", invitationID) req, err := s.client.NewRequest("DELETE", u, nil) diff --git a/github/users_blocking.go b/github/users_blocking.go index 1c292e50d43..a9ef4c58f10 100644 --- a/github/users_blocking.go +++ b/github/users_blocking.go @@ -12,7 +12,7 @@ import ( // ListBlockedUsers lists all the blocked users by the authenticated user. // -// GitHub API docs: https://developer.github.com/v3/users/blocking/#list-users-blocked-by-the-authenticated-user +// GitHub API docs: https://docs.github.com/en/rest/reference/users/#list-users-blocked-by-the-authenticated-user func (s *UsersService) ListBlockedUsers(ctx context.Context, opts *ListOptions) ([]*User, *Response, error) { u := "user/blocks" u, err := addOptions(u, opts) @@ -39,7 +39,7 @@ func (s *UsersService) ListBlockedUsers(ctx context.Context, opts *ListOptions) // IsBlocked reports whether specified user is blocked by the authenticated user. // -// GitHub API docs: https://developer.github.com/v3/users/blocking/#check-if-a-user-is-blocked-by-the-authenticated-user +// GitHub API docs: https://docs.github.com/en/rest/reference/users/#check-if-a-user-is-blocked-by-the-authenticated-user func (s *UsersService) IsBlocked(ctx context.Context, user string) (bool, *Response, error) { u := fmt.Sprintf("user/blocks/%v", user) @@ -58,7 +58,7 @@ func (s *UsersService) IsBlocked(ctx context.Context, user string) (bool, *Respo // BlockUser blocks specified user for the authenticated user. // -// GitHub API docs: https://developer.github.com/v3/users/blocking/#block-a-user +// GitHub API docs: https://docs.github.com/en/rest/reference/users/#block-a-user func (s *UsersService) BlockUser(ctx context.Context, user string) (*Response, error) { u := fmt.Sprintf("user/blocks/%v", user) @@ -75,7 +75,7 @@ func (s *UsersService) BlockUser(ctx context.Context, user string) (*Response, e // UnblockUser unblocks specified user for the authenticated user. // -// GitHub API docs: https://developer.github.com/v3/users/blocking/#unblock-a-user +// GitHub API docs: https://docs.github.com/en/rest/reference/users/#unblock-a-user func (s *UsersService) UnblockUser(ctx context.Context, user string) (*Response, error) { u := fmt.Sprintf("user/blocks/%v", user) diff --git a/github/users_emails.go b/github/users_emails.go index 05870c02270..64ed5eb573d 100644 --- a/github/users_emails.go +++ b/github/users_emails.go @@ -17,7 +17,7 @@ type UserEmail struct { // ListEmails lists all email addresses for the authenticated user. // -// GitHub API docs: https://developer.github.com/v3/users/emails/#list-email-addresses-for-the-authenticated-user +// GitHub API docs: https://docs.github.com/en/rest/reference/users/#list-email-addresses-for-the-authenticated-user func (s *UsersService) ListEmails(ctx context.Context, opts *ListOptions) ([]*UserEmail, *Response, error) { u := "user/emails" u, err := addOptions(u, opts) @@ -41,7 +41,7 @@ func (s *UsersService) ListEmails(ctx context.Context, opts *ListOptions) ([]*Us // AddEmails adds email addresses of the authenticated user. // -// GitHub API docs: https://developer.github.com/v3/users/emails/#add-an-email-address-for-the-authenticated-user +// GitHub API docs: https://docs.github.com/en/rest/reference/users/#add-an-email-address-for-the-authenticated-user func (s *UsersService) AddEmails(ctx context.Context, emails []string) ([]*UserEmail, *Response, error) { u := "user/emails" req, err := s.client.NewRequest("POST", u, emails) @@ -60,7 +60,7 @@ func (s *UsersService) AddEmails(ctx context.Context, emails []string) ([]*UserE // DeleteEmails deletes email addresses from authenticated user. // -// GitHub API docs: https://developer.github.com/v3/users/emails/#delete-an-email-address-for-the-authenticated-user +// GitHub API docs: https://docs.github.com/en/rest/reference/users/#delete-an-email-address-for-the-authenticated-user func (s *UsersService) DeleteEmails(ctx context.Context, emails []string) (*Response, error) { u := "user/emails" req, err := s.client.NewRequest("DELETE", u, emails) diff --git a/github/users_followers.go b/github/users_followers.go index bd0a3735c08..bf5dedb07b1 100644 --- a/github/users_followers.go +++ b/github/users_followers.go @@ -13,8 +13,8 @@ import ( // ListFollowers lists the followers for a user. Passing the empty string will // fetch followers for the authenticated user. // -// GitHub API docs: https://developer.github.com/v3/users/followers/#list-followers-of-a-user -// GitHub API docs: https://developer.github.com/v3/users/followers/#list-followers-of-the-authenticated-user +// GitHub API docs: https://docs.github.com/en/rest/reference/users/#list-followers-of-the-authenticated-user +// GitHub API docs: https://docs.github.com/en/rest/reference/users/#list-followers-of-a-user func (s *UsersService) ListFollowers(ctx context.Context, user string, opts *ListOptions) ([]*User, *Response, error) { var u string if user != "" { @@ -44,8 +44,8 @@ func (s *UsersService) ListFollowers(ctx context.Context, user string, opts *Lis // ListFollowing lists the people that a user is following. Passing the empty // string will list people the authenticated user is following. // -// GitHub API docs: https://developer.github.com/v3/users/followers/#list-the-people-the-authenticated-user-follows -// GitHub API docs: https://developer.github.com/v3/users/followers/#list-the-people-a-user-follows +// GitHub API docs: https://docs.github.com/en/rest/reference/users/#list-the-people-the-authenticated-user-follows +// GitHub API docs: https://docs.github.com/en/rest/reference/users/#list-the-people-a-user-follows func (s *UsersService) ListFollowing(ctx context.Context, user string, opts *ListOptions) ([]*User, *Response, error) { var u string if user != "" { @@ -75,8 +75,8 @@ func (s *UsersService) ListFollowing(ctx context.Context, user string, opts *Lis // IsFollowing checks if "user" is following "target". Passing the empty // string for "user" will check if the authenticated user is following "target". // -// GitHub API docs: https://developer.github.com/v3/users/followers/#check-if-a-person-is-followed-by-the-authenticated-user -// GitHub API docs: https://developer.github.com/v3/users/followers/#check-if-a-user-follows-another-user +// GitHub API docs: https://docs.github.com/en/rest/reference/users/#check-if-a-person-is-followed-by-the-authenticated-user +// GitHub API docs: https://docs.github.com/en/rest/reference/users/#check-if-a-user-follows-another-user func (s *UsersService) IsFollowing(ctx context.Context, user, target string) (bool, *Response, error) { var u string if user != "" { @@ -97,7 +97,7 @@ func (s *UsersService) IsFollowing(ctx context.Context, user, target string) (bo // Follow will cause the authenticated user to follow the specified user. // -// GitHub API docs: https://developer.github.com/v3/users/followers/#follow-a-user +// GitHub API docs: https://docs.github.com/en/rest/reference/users/#follow-a-user func (s *UsersService) Follow(ctx context.Context, user string) (*Response, error) { u := fmt.Sprintf("user/following/%v", user) req, err := s.client.NewRequest("PUT", u, nil) @@ -110,7 +110,7 @@ func (s *UsersService) Follow(ctx context.Context, user string) (*Response, erro // Unfollow will cause the authenticated user to unfollow the specified user. // -// GitHub API docs: https://developer.github.com/v3/users/followers/#unfollow-a-user +// GitHub API docs: https://docs.github.com/en/rest/reference/users/#unfollow-a-user func (s *UsersService) Unfollow(ctx context.Context, user string) (*Response, error) { u := fmt.Sprintf("user/following/%v", user) req, err := s.client.NewRequest("DELETE", u, nil) diff --git a/github/users_gpg_keys.go b/github/users_gpg_keys.go index 077a6c2eb37..08c594b8073 100644 --- a/github/users_gpg_keys.go +++ b/github/users_gpg_keys.go @@ -44,8 +44,8 @@ type GPGEmail struct { // string will fetch keys for the authenticated user. It requires authentication // via Basic Auth or via OAuth with at least read:gpg_key scope. // -// GitHub API docs: https://developer.github.com/v3/users/gpg_keys/#list-gpg-keys-for-a-user -// GitHub API docs: https://developer.github.com/v3/users/gpg_keys/#list-gpg-keys-for-the-authenticated-user +// GitHub API docs: https://docs.github.com/en/rest/reference/users/#list-gpg-keys-for-the-authenticated-user +// GitHub API docs: https://docs.github.com/en/rest/reference/users/#list-gpg-keys-for-a-user func (s *UsersService) ListGPGKeys(ctx context.Context, user string, opts *ListOptions) ([]*GPGKey, *Response, error) { var u string if user != "" { @@ -75,7 +75,7 @@ func (s *UsersService) ListGPGKeys(ctx context.Context, user string, opts *ListO // GetGPGKey gets extended details for a single GPG key. It requires authentication // via Basic Auth or via OAuth with at least read:gpg_key scope. // -// GitHub API docs: https://developer.github.com/v3/users/gpg_keys/#get-a-gpg-key-for-the-authenticated-user +// GitHub API docs: https://docs.github.com/en/rest/reference/users/#get-a-gpg-key-for-the-authenticated-user func (s *UsersService) GetGPGKey(ctx context.Context, id int64) (*GPGKey, *Response, error) { u := fmt.Sprintf("user/gpg_keys/%v", id) req, err := s.client.NewRequest("GET", u, nil) @@ -95,7 +95,7 @@ func (s *UsersService) GetGPGKey(ctx context.Context, id int64) (*GPGKey, *Respo // CreateGPGKey creates a GPG key. It requires authenticatation via Basic Auth // or OAuth with at least write:gpg_key scope. // -// GitHub API docs: https://developer.github.com/v3/users/gpg_keys/#create-a-gpg-key +// GitHub API docs: https://docs.github.com/en/rest/reference/users/gpg_keys/#create-a-gpg-key func (s *UsersService) CreateGPGKey(ctx context.Context, armoredPublicKey string) (*GPGKey, *Response, error) { gpgKey := &struct { ArmoredPublicKey string `json:"armored_public_key"` @@ -117,7 +117,7 @@ func (s *UsersService) CreateGPGKey(ctx context.Context, armoredPublicKey string // DeleteGPGKey deletes a GPG key. It requires authentication via Basic Auth or // via OAuth with at least admin:gpg_key scope. // -// GitHub API docs: https://developer.github.com/v3/users/gpg_keys/#delete-a-gpg-key-for-the-authenticated-user +// GitHub API docs: https://docs.github.com/en/rest/reference/users/#delete-a-gpg-key-for-the-authenticated-user func (s *UsersService) DeleteGPGKey(ctx context.Context, id int64) (*Response, error) { u := fmt.Sprintf("user/gpg_keys/%v", id) req, err := s.client.NewRequest("DELETE", u, nil) diff --git a/github/users_keys.go b/github/users_keys.go index e6b6380864e..5955cf0cf24 100644 --- a/github/users_keys.go +++ b/github/users_keys.go @@ -27,8 +27,8 @@ func (k Key) String() string { // ListKeys lists the verified public keys for a user. Passing the empty // string will fetch keys for the authenticated user. // -// GitHub API docs: https://developer.github.com/v3/users/keys/#list-public-keys-for-a-user -// GitHub API docs: https://developer.github.com/v3/users/keys/#list-public-ssh-keys-for-the-authenticated-user +// GitHub API docs: https://docs.github.com/en/rest/reference/users/#list-public-ssh-keys-for-the-authenticated-user +// GitHub API docs: https://docs.github.com/en/rest/reference/users/#list-public-keys-for-a-user func (s *UsersService) ListKeys(ctx context.Context, user string, opts *ListOptions) ([]*Key, *Response, error) { var u string if user != "" { @@ -57,7 +57,7 @@ func (s *UsersService) ListKeys(ctx context.Context, user string, opts *ListOpti // GetKey fetches a single public key. // -// GitHub API docs: https://developer.github.com/v3/users/keys/#get-a-public-ssh-key-for-the-authenticated-user +// GitHub API docs: https://docs.github.com/en/rest/reference/users/#get-a-public-ssh-key-for-the-authenticated-user func (s *UsersService) GetKey(ctx context.Context, id int64) (*Key, *Response, error) { u := fmt.Sprintf("user/keys/%v", id) @@ -77,7 +77,7 @@ func (s *UsersService) GetKey(ctx context.Context, id int64) (*Key, *Response, e // CreateKey adds a public key for the authenticated user. // -// GitHub API docs: https://developer.github.com/v3/users/keys/#create-a-public-ssh-key-for-the-authenticated-user +// GitHub API docs: https://docs.github.com/en/rest/reference/users/#create-a-public-ssh-key-for-the-authenticated-user func (s *UsersService) CreateKey(ctx context.Context, key *Key) (*Key, *Response, error) { u := "user/keys" @@ -97,7 +97,7 @@ func (s *UsersService) CreateKey(ctx context.Context, key *Key) (*Key, *Response // DeleteKey deletes a public key. // -// GitHub API docs: https://developer.github.com/v3/users/keys/#delete-a-public-ssh-key-for-the-authenticated-user +// GitHub API docs: https://docs.github.com/en/rest/reference/users/#delete-a-public-ssh-key-for-the-authenticated-user func (s *UsersService) DeleteKey(ctx context.Context, id int64) (*Response, error) { u := fmt.Sprintf("user/keys/%v", id) diff --git a/github/users_projects.go b/github/users_projects.go index 1357055040c..eabbe54af92 100644 --- a/github/users_projects.go +++ b/github/users_projects.go @@ -12,7 +12,7 @@ import ( // ListProjects lists the projects for the specified user. // -// GitHub API docs: https://developer.github.com/v3/projects/#list-user-projects +// GitHub API docs: https://docs.github.com/en/rest/reference/projects/#list-user-projects func (s *UsersService) ListProjects(ctx context.Context, user string, opts *ProjectListOptions) ([]*Project, *Response, error) { u := fmt.Sprintf("users/%v/projects", user) u, err := addOptions(u, opts) @@ -47,7 +47,7 @@ type CreateUserProjectOptions struct { // CreateProject creates a GitHub Project for the current user. // -// GitHub API docs: https://developer.github.com/v3/projects/#create-a-user-project +// GitHub API docs: https://docs.github.com/en/rest/reference/projects/#create-a-user-project func (s *UsersService) CreateProject(ctx context.Context, opts *CreateUserProjectOptions) (*Project, *Response, error) { u := "user/projects" req, err := s.client.NewRequest("POST", u, opts) diff --git a/update-urls/activity-events_test.go b/update-urls/activity-events_test.go index 6f4dbeb4b13..1be30d7a074 100644 --- a/update-urls/activity-events_test.go +++ b/update-urls/activity-events_test.go @@ -11,7 +11,7 @@ import ( func newActivitiesEventsPipeline() *pipelineSetup { return &pipelineSetup{ - baseURL: "https://developer.github.com/v3/activity/events/", + baseURL: "https://docs.github.com/en/rest/reference/activity/events/", endpointsFromWebsite: activityEventsWant, filename: "activity_events.go", serviceName: "ActivityService", @@ -86,961 +86,5784 @@ var activityEventsWant = endpointsByFragmentID{ "list-public-events-received-by-a-user": []*Endpoint{ {urlFormats: []string{"users/%v/received_events/public"}, httpMethod: "GET"}, }, -} - -var activityEventsTestWebPage = ` - - - - - - - - Events | GitHub Developer Guide - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - + "star-a-repository-for-the-authenticated-user": []*Endpoint{ + {urlFormats: []string{"user/starred/%v/%v"}, httpMethod: "PUT"}, + }, -
-
-

-Events

- -

This is a read-only API to the GitHub events. These events power the various activity streams on the site. An events API for repository issues is also available. For more information, see the "Issue Events API."

- - + "list-repositories-starred-by-the-authenticated-user": []*Endpoint{ + {urlFormats: []string{"user/starred"}, httpMethod: "GET"}, + }, -

Events are optimized for polling with the "ETag" header. If no new events have been triggered, you will see a "304 Not Modified" response, and your current rate limit will be untouched. There is also an "X-Poll-Interval" header that specifies how often (in seconds) you are allowed to poll. In times of high -server load, the time may increase. Please obey the header.

+ "list-watchers": []*Endpoint{ + {urlFormats: []string{"repos/%v/%v/subscribers"}, httpMethod: "GET"}, + }, -
-curl -I https://api.github.com/users/tater/events
-HTTP/1.1 200 OK
-X-Poll-Interval: 60
-ETag: "a18c3bded88eb5dbb5c849a489412bf3"
-# The quotes around the ETag value are important
-curl -I https://api.github.com/users/tater/events \
-   -H 'If-None-Match: "a18c3bded88eb5dbb5c849a489412bf3"'
-HTTP/1.1 304 Not Modified
-X-Poll-Interval: 60
-
+ "get-feeds": []*Endpoint{ + {urlFormats: []string{"feeds"}, httpMethod: "GET"}, + }, -

Events support pagination, however the per_page option is unsupported. The fixed page size is 30 items. Fetching up to ten pages is supported, for a total of 300 events.

+ "get-a-thread": []*Endpoint{ + {urlFormats: []string{"notifications/threads/%v"}, httpMethod: "GET"}, + }, -

Only events created within the past 90 days will be included in timelines. Events older than 90 days will not be included (even if the total number of events in the timeline is less than 300).

+ "mark-a-thread-as-read": []*Endpoint{ + {urlFormats: []string{"notifications/threads/%v"}, httpMethod: "PATCH"}, + }, -

All Events have the same response format:

+ "list-stargazers": []*Endpoint{ + {urlFormats: []string{"repos/%v/%v/stargazers"}, httpMethod: "GET"}, + }, -
Status: 200 OK
-Link: <https://api.github.com/resource?page=2>; rel="next",
-      <https://api.github.com/resource?page=5>; rel="last"
-
+ "list-repositories-watched-by-a-user": []*Endpoint{ + {urlFormats: []string{"users/%v/subscriptions"}, httpMethod: "GET"}, + }, + "list-repository-notifications-for-the-authenticated-user": []*Endpoint{ + {urlFormats: []string{"repos/%v/%v/notifications"}, httpMethod: "GET"}, + }, -
[
-  {
-    "type": "Event",
-    "public": true,
-    "payload": {
-    },
-    "repo": {
-      "id": 3,
-      "name": "octocat/Hello-World",
-      "url": "https://api.github.com/repos/octocat/Hello-World"
-    },
-    "actor": {
-      "id": 1,
-      "login": "octocat",
-      "gravatar_id": "",
-      "avatar_url": "https://github.com/images/error/octocat_happy.gif",
-      "url": "https://api.github.com/users/octocat"
-    },
-    "org": {
-      "id": 1,
-      "login": "github",
-      "gravatar_id": "",
-      "url": "https://api.github.com/orgs/github",
-      "avatar_url": "https://github.com/images/error/octocat_happy.gif"
-    },
-    "created_at": "2011-09-06T17:26:27Z",
-    "id": "12345"
-  }
-]
-
+ "mark-repository-notifications-as-read": []*Endpoint{ + {urlFormats: []string{"repos/%v/%v/notifications"}, httpMethod: "PUT"}, + }, + "check-if-a-repository-is-starred-by-the-authenticated-user": []*Endpoint{ + {urlFormats: []string{"user/starred/%v/%v"}, httpMethod: "GET"}, + }, -

-List public events -

+ "list-notifications-for-the-authenticated-user": []*Endpoint{ + {urlFormats: []string{"notifications"}, httpMethod: "GET"}, + }, -

We delay the public events feed by five minutes, which means the most recent event returned by the public events API actually occurred at least five minutes ago.

+ "get-a-thread-subscription-for-the-authenticated-user": []*Endpoint{ + {urlFormats: []string{"notifications/threads/%v/subscription"}, httpMethod: "GET"}, + }, -
GET /events
-
+ "unstar-a-repository-for-the-authenticated-user": []*Endpoint{ + {urlFormats: []string{"user/starred/%v/%v"}, httpMethod: "DELETE"}, + }, -

-List repository events -

+ "list-repositories-watched-by-the-authenticated-user": []*Endpoint{ + {urlFormats: []string{"user/subscriptions"}, httpMethod: "GET"}, + }, -
GET /repos/:owner/:repo/events
-
+ "get-a-repository-subscription": []*Endpoint{ + {urlFormats: []string{"repos/%v/%v/subscription"}, httpMethod: "GET"}, + }, -

-List public events for a network of repositories -

+ "set-a-repository-subscription": []*Endpoint{ + {urlFormats: []string{"repos/%v/%v/subscription"}, httpMethod: "PUT"}, + }, -
GET /networks/:owner/:repo/events
-
+ "list-repositories-starred-by-a-user": []*Endpoint{ + {urlFormats: []string{"users/%v/starred"}, httpMethod: "GET"}, + }, +} -

-List public organization events -

+var activityEventsTestWebPage = ` + + + Activity - GitHub Docs + + + -
GET /orgs/:org/events
-
+ + + -

-List events received by the authenticated user -

+ -

These are events that you've received by watching repos and following users. If you are authenticated as the given user, you will see private events. Otherwise, you'll only see public events.

+ + + + + + + + + + + + + + -
GET /users/:username/received_events
-
+ + + + -

-List public events received by a user -

-
GET /users/:username/received_events/public
-
+ + + -

This is the user's organization dashboard. You must be authenticated as the user to view this.

-
GET /users/:username/events/orgs/:org
-
-
+
+
- +
+
+ +
+
+

Activity

+
+ +
-
+ ` @@ -1058,7 +5881,7 @@ import ( // ListEvents drinks from the firehose of all public events across GitHub. // -// GitHub API docs: https://developer.github.com/v3/activity/events/#list-public-events +// GitHub API docs: https://docs.github.com/en/rest/reference/activity/events/#list-public-events func (s *ActivityService) ListEvents(ctx context.Context, opts *ListOptions) ([]*Event, *Response, error) { u, err := addOptions("events", opts) if err != nil { @@ -1081,7 +5904,7 @@ func (s *ActivityService) ListEvents(ctx context.Context, opts *ListOptions) ([] // ListRepositoryEvents lists events for a repository. // -// GitHub API docs: https://developer.github.com/v3/activity/events/#list-repository-events +// GitHub API docs: https://docs.github.com/en/rest/reference/activity/events/#list-repository-events func (s *ActivityService) ListRepositoryEvents(ctx context.Context, owner, repo string, opts *ListOptions) ([]*Event, *Response, error) { u := fmt.Sprintf("repos/%v/%v/events", owner, repo) u, err := addOptions(u, opts) @@ -1108,7 +5931,7 @@ func (s *ActivityService) ListRepositoryEvents(ctx context.Context, owner, repo // ListEventsForRepoNetwork lists public events for a network of repositories. // -// GitHub API docs: https://developer.github.com/v3/activity/events/#list-public-events-for-a-network-of-repositories +// GitHub API docs: https://docs.github.com/en/rest/reference/activity/events/#list-public-events-for-a-network-of-repositories func (s *ActivityService) ListEventsForRepoNetwork(ctx context.Context, owner, repo string, opts *ListOptions) ([]*Event, *Response, error) { u := fmt.Sprintf("networks/%v/%v/events", owner, repo) u, err := addOptions(u, opts) @@ -1132,7 +5955,7 @@ func (s *ActivityService) ListEventsForRepoNetwork(ctx context.Context, owner, r // ListEventsForOrganization lists public events for an organization. // -// GitHub API docs: https://developer.github.com/v3/activity/events/#list-public-events-for-an-organization +// GitHub API docs: https://docs.github.com/en/rest/reference/activity/events/#list-public-events-for-an-organization func (s *ActivityService) ListEventsForOrganization(ctx context.Context, org string, opts *ListOptions) ([]*Event, *Response, error) { u := fmt.Sprintf("orgs/%v/events", org) u, err := addOptions(u, opts) @@ -1157,8 +5980,8 @@ func (s *ActivityService) ListEventsForOrganization(ctx context.Context, org str // ListEventsPerformedByUser lists the events performed by a user. If publicOnly is // true, only public events will be returned. // -// GitHub API docs: https://developer.github.com/v3/activity/events/#list-events-for-the-authenticated-user -// GitHub API docs: https://developer.github.com/v3/activity/events/#list-public-events-for-a-user +// GitHub API docs: https://docs.github.com/en/rest/reference/activity/events/#list-events-for-the-authenticated-user +// GitHub API docs: https://docs.github.com/en/rest/reference/activity/events/#list-public-events-for-a-user func (s *ActivityService) ListEventsPerformedByUser(ctx context.Context, user string, publicOnly bool, opts *ListOptions) ([]*Event, *Response, error) { var u string if publicOnly { @@ -1188,8 +6011,8 @@ func (s *ActivityService) ListEventsPerformedByUser(ctx context.Context, user st // ListEventsReceivedByUser lists the events received by a user. If publicOnly is // true, only public events will be returned. // -// GitHub API docs: https://developer.github.com/v3/activity/events/#list-events-received-by-the-authenticated-user -// GitHub API docs: https://developer.github.com/v3/activity/events/#list-public-events-received-by-a-user +// GitHub API docs: https://docs.github.com/en/rest/reference/activity/events/#list-events-received-by-the-authenticated-user +// GitHub API docs: https://docs.github.com/en/rest/reference/activity/events/#list-public-events-received-by-a-user func (s *ActivityService) ListEventsReceivedByUser(ctx context.Context, user string, publicOnly bool, opts *ListOptions) ([]*Event, *Response, error) { var u string if publicOnly { @@ -1219,7 +6042,7 @@ func (s *ActivityService) ListEventsReceivedByUser(ctx context.Context, user str // ListUserEventsForOrganization provides the user’s organization dashboard. You // must be authenticated as the user to view this. // -// GitHub API docs: https://developer.github.com/v3/activity/events/#list-events-for-an-organization +// GitHub API docs: https://docs.github.com/en/rest/reference/activity/events/#list-events-for-an-organization func (s *ActivityService) ListUserEventsForOrganization(ctx context.Context, org, user string, opts *ListOptions) ([]*Event, *Response, error) { u := fmt.Sprintf("users/%v/events/orgs/%v", user, org) u, err := addOptions(u, opts) @@ -1256,7 +6079,7 @@ import ( // ListEvents drinks from the firehose of all public events across GitHub. // -// GitHub API docs: https://developer.github.com/v3/activity/events/#list-public-events +// GitHub API docs: https://docs.github.com/en/rest/reference/activity/events/#list-public-events func (s *ActivityService) ListEvents(ctx context.Context, opts *ListOptions) ([]*Event, *Response, error) { u, err := addOptions("events", opts) if err != nil { @@ -1279,7 +6102,7 @@ func (s *ActivityService) ListEvents(ctx context.Context, opts *ListOptions) ([] // ListRepositoryEvents lists events for a repository. // -// GitHub API docs: https://developer.github.com/v3/activity/events/#list-repository-events +// GitHub API docs: https://docs.github.com/en/rest/reference/activity/events/#list-repository-events func (s *ActivityService) ListRepositoryEvents(ctx context.Context, owner, repo string, opts *ListOptions) ([]*Event, *Response, error) { u := fmt.Sprintf("repos/%v/%v/events", owner, repo) u, err := addOptions(u, opts) @@ -1306,7 +6129,7 @@ func (s *ActivityService) ListRepositoryEvents(ctx context.Context, owner, repo // ListEventsForRepoNetwork lists public events for a network of repositories. // -// GitHub API docs: https://developer.github.com/v3/activity/events/#list-public-events-for-a-network-of-repositories +// GitHub API docs: https://docs.github.com/en/rest/reference/activity/events/#list-public-events-for-a-network-of-repositories func (s *ActivityService) ListEventsForRepoNetwork(ctx context.Context, owner, repo string, opts *ListOptions) ([]*Event, *Response, error) { u := fmt.Sprintf("networks/%v/%v/events", owner, repo) u, err := addOptions(u, opts) @@ -1330,7 +6153,7 @@ func (s *ActivityService) ListEventsForRepoNetwork(ctx context.Context, owner, r // ListEventsForOrganization lists public events for an organization. // -// GitHub API docs: https://developer.github.com/v3/activity/events/#list-public-organization-events +// GitHub API docs: https://docs.github.com/en/rest/reference/activity/events/#list-public-organization-events func (s *ActivityService) ListEventsForOrganization(ctx context.Context, org string, opts *ListOptions) ([]*Event, *Response, error) { u := fmt.Sprintf("orgs/%v/events", org) u, err := addOptions(u, opts) @@ -1355,8 +6178,8 @@ func (s *ActivityService) ListEventsForOrganization(ctx context.Context, org str // ListEventsPerformedByUser lists the events performed by a user. If publicOnly is // true, only public events will be returned. // -// GitHub API docs: https://developer.github.com/v3/activity/events/#list-events-for-the-authenticated-user -// GitHub API docs: https://developer.github.com/v3/activity/events/#list-public-events-for-a-user +// GitHub API docs: https://docs.github.com/en/rest/reference/activity/events/#list-events-for-the-authenticated-user +// GitHub API docs: https://docs.github.com/en/rest/reference/activity/events/#list-public-events-for-a-user func (s *ActivityService) ListEventsPerformedByUser(ctx context.Context, user string, publicOnly bool, opts *ListOptions) ([]*Event, *Response, error) { var u string if publicOnly { @@ -1386,8 +6209,8 @@ func (s *ActivityService) ListEventsPerformedByUser(ctx context.Context, user st // ListEventsReceivedByUser lists the events received by a user. If publicOnly is // true, only public events will be returned. // -// GitHub API docs: https://developer.github.com/v3/activity/events/#list-events-received-by-the-authenticated-user -// GitHub API docs: https://developer.github.com/v3/activity/events/#list-public-events-received-by-a-user +// GitHub API docs: https://docs.github.com/en/rest/reference/activity/events/#list-events-received-by-the-authenticated-user +// GitHub API docs: https://docs.github.com/en/rest/reference/activity/events/#list-public-events-received-by-a-user func (s *ActivityService) ListEventsReceivedByUser(ctx context.Context, user string, publicOnly bool, opts *ListOptions) ([]*Event, *Response, error) { var u string if publicOnly { @@ -1417,7 +6240,7 @@ func (s *ActivityService) ListEventsReceivedByUser(ctx context.Context, user str // ListUserEventsForOrganization provides the user’s organization dashboard. You // must be authenticated as the user to view this. // -// GitHub API docs: https://developer.github.com/v3/activity/events/#list-organization-events-for-the-authenticated-user +// GitHub API docs: https://docs.github.com/en/rest/reference/activity/events/#list-organization-events-for-the-authenticated-user func (s *ActivityService) ListUserEventsForOrganization(ctx context.Context, org, user string, opts *ListOptions) ([]*Event, *Response, error) { u := fmt.Sprintf("users/%v/events/orgs/%v", user, org) u, err := addOptions(u, opts) diff --git a/update-urls/main.go b/update-urls/main.go index 3d8ca216357..5ee660959fa 100644 --- a/update-urls/main.go +++ b/update-urls/main.go @@ -32,10 +32,13 @@ import ( ) const ( - skipPrefix = "gen-" + codeLegacySplitString = `` + codeSplitString = `await octokit.request('` + fragmentIDString = `

1: - log.Printf("WARNING: multiple Enterprise GitHub URLs found - skipping: %#v", endpoint.enterpriseRefLines) + log.Printf("WARNING: multiple Enterprise GitHub URLs found - skipping:") + for i, refLine := range endpoint.enterpriseRefLines { + log.Printf("line %v: %#v", i, refLine) + } case len(endpoint.enterpriseRefLines) > 0: line := fmt.Sprintf(enterpriseRefFmt, url) cmt := endpoint.enterpriseRefLines[0] @@ -541,7 +552,7 @@ func (dc *documentCache) CacheDocFromInternet(urlWithID string) { } // TODO: Enterprise URLs are currently causing problems - for example: - // GET https://developer.github.com/enterprise/v3/enterprise-admin/users/ + // GET https://docs.github.com/enterprise/v3/enterprise-admin/users/ // returns StatusCode=404 if strings.Contains(url, "enterprise") { logf("Skipping troublesome Enterprise URL: %v", url) @@ -555,14 +566,24 @@ func (dc *documentCache) CacheDocFromInternet(urlWithID string) { log.Fatalf("url %v - StatusCode=%v", url, resp.StatusCode) } + finalURL := resp.Request.URL.String() + url = getURL(finalURL) + logf("The final URL is: %v; url=%v\n", finalURL, url) + b, err := ioutil.ReadAll(resp.Body) check("Unable to read body of URL: %v, %v", url, err) check("Unable to close body of URL: %v, %v", url, resp.Body.Close()) dc.apiDocs[url] = parseWebPageEndpoints(string(b)) + logf("Found %v web page fragment identifiers.", len(dc.apiDocs[url])) + if len(dc.apiDocs[url]) == 0 { + logf("webage text: %s", b) + } // Now reverse-map the methods+paths to URLs. for fragID, v := range dc.apiDocs[url] { + logf("For fragID=%q, found %v endpoints.", fragID, len(v)) for _, endpoint := range v { + logf("For fragID=%q, endpoint=%q, found %v paths.", fragID, endpoint, len(endpoint.urlFormats)) for _, path := range endpoint.urlFormats { methodAndPath := fmt.Sprintf("%v %v", endpoint.httpMethod, path) dc.urlByMethodAndPath[methodAndPath] = fmt.Sprintf("%v#%v", url, fragID) @@ -701,9 +722,10 @@ func processAST(filename string, f *ast.File, services servicesMap, endpoints en endpointComments = decl.Doc.List for i, comment := range decl.Doc.List { logf("doc.comment[%v] = %#v", i, *comment) - if strings.Contains(comment.Text, enterpriseURL) { - enterpriseRefLines = append(enterpriseRefLines, comment) - } else if strings.Contains(comment.Text, stdURL) { + // if strings.Contains(comment.Text, enterpriseURL) { + // enterpriseRefLines = append(enterpriseRefLines, comment) + // } else + if strings.Contains(comment.Text, stdURL) { stdRefLines = append(stdRefLines, comment) } } @@ -943,6 +965,10 @@ func processAssignStmt(receiverName string, stmt *ast.AssignStmt) (httpMethod, u logf("processAssignStmt: *ast.SelectorExpr: %#v", *expr) case *ast.UnaryExpr: // OpPos, Op, X logf("processAssignStmt: *ast.UnaryExpr: %#v", *expr) + case *ast.TypeAssertExpr: // X, Lparen, Type, Rparen + logf("processAssignStmt: *ast.TypeAssertExpr: %#v", *expr) + case *ast.Ident: // NamePos, Name, Obj + logf("processAssignStmt: *ast.Ident: %#v", *expr) default: log.Fatalf("unhandled AssignStmt Rhs type: %T", expr) } @@ -1105,41 +1131,21 @@ func parseWebPageEndpoints(buf string) map[string][]*Endpoint { // ... // - parts := strings.Split(buf, "") + parts := splitHTML(buf) var lastFragmentID string for _, part := range parts { for _, method := range httpMethods { if strings.HasPrefix(part, method) { - eol := strings.Index(part, "\n") - if eol < 0 { - eol = len(part) - } - if v := strings.Index(part, "<"); v > len(method) && v < eol { - eol = v - } - if v := strings.Index(part, "{"); v > len(method) && v < eol { - eol = v + endpoint := parseEndpoint(part, method) + if lastFragmentID == "" { + log.Fatalf("parseWebPageEndpoints: empty lastFragmentID") } - path := strings.TrimSpace(part[len(method):eol]) - if strings.HasPrefix(path, ":server") { // Hack to remove :server - path = strings.TrimPrefix(path, ":server") - } - path = paramRE.ReplaceAllString(path, "%v") - // strip leading garbage - if i := strings.Index(path, "/"); i >= 0 { - path = path[i+1:] - } - path = strings.TrimSuffix(path, ".") - logf("Found %v %v", method, path) - result[lastFragmentID] = append(result[lastFragmentID], &Endpoint{ - urlFormats: []string{path}, - httpMethod: method, - }) + result[lastFragmentID] = append(result[lastFragmentID], endpoint) } } - if i := strings.LastIndex(part, "= 0 { lastFragmentID = b[:i] @@ -1151,6 +1157,60 @@ func parseWebPageEndpoints(buf string) map[string][]*Endpoint { return result } +func splitHTML(buf string) []string { + var result []string + for buf != "" { + i := strings.Index(buf, codeLegacySplitString) + j := strings.Index(buf, codeSplitString) + switch { + case i < 0 && j < 0: + result = append(result, buf) + buf = "" + case j < 0, i >= 0 && j >= 0 && i < j: + result = append(result, buf[:i]) + buf = buf[i+len(codeLegacySplitString):] + case i < 0, i >= 0 && j >= 0 && j < i: + result = append(result, buf[:j]) + buf = buf[j+len(codeSplitString):] + default: + log.Fatalf("splitHTML: i=%v, j=%v", i, j) + } + } + return result +} + +func parseEndpoint(s, method string) *Endpoint { + eol := strings.Index(s, "\n") + if eol < 0 { + eol = len(s) + } + if v := strings.Index(s, "'"); v > len(method) && v < eol { + eol = v + } + if v := strings.Index(s, "<"); v > len(method) && v < eol { + eol = v + } + // if v := strings.Index(s, "{"); v > len(method) && v < eol { + // eol = v + // } + path := strings.TrimSpace(s[len(method):eol]) + if strings.HasPrefix(path, "{server}") { // Hack to remove {server} + path = strings.TrimPrefix(path, "{server}") + } + path = paramLegacyRE.ReplaceAllString(path, "%v") + path = paramRE.ReplaceAllString(path, "%v") + // strip leading garbage + if i := strings.Index(path, "/"); i >= 0 { + path = path[i+1:] + } + path = strings.TrimSuffix(path, ".") + logf("Found endpoint: %v %v", method, path) + return &Endpoint{ + urlFormats: []string{path}, + httpMethod: method, + } +} + var httpMethods = []string{ "GET", "HEAD", diff --git a/update-urls/main_test.go b/update-urls/main_test.go index e77411a022c..79620a95332 100644 --- a/update-urls/main_test.go +++ b/update-urls/main_test.go @@ -234,6 +234,7 @@ type fakeDocCache struct { } func (f *fakeDocCache) UrlByMethodAndPath(methodAndPath string) (string, bool) { + f.t.Helper() for fragmentID, endpoints := range f.endpoints { for _, endpoint := range endpoints { for _, urlFormat := range endpoint.urlFormats { @@ -512,18 +513,18 @@ func TestGitURL(t *testing.T) { {name: "non-http", s: "howdy"}, { name: "normal URL, no slash", - s: "https://developer.github.com/v3/activity/events", - want: "https://developer.github.com/v3/activity/events/", + s: "https://docs.github.com/en/rest/reference/activity/events", + want: "https://docs.github.com/en/rest/reference/activity/events/", }, { name: "normal URL, with slash", - s: "https://developer.github.com/v3/activity/events/", - want: "https://developer.github.com/v3/activity/events/", + s: "https://docs.github.com/en/rest/reference/activity/events/", + want: "https://docs.github.com/en/rest/reference/activity/events/", }, { name: "normal URL, with fragment identifier", - s: "https://developer.github.com/v3/activity/events/#list-public-events", - want: "https://developer.github.com/v3/activity/events/", + s: "https://docs.github.com/en/rest/reference/activity/events/#list-public-events", + want: "https://docs.github.com/en/rest/reference/activity/events/", }, } @@ -561,3 +562,37 @@ func testWebPageHelper(t *testing.T, got, want map[string][]*Endpoint) { } } } + +func TestParseEndpoint(t *testing.T) { + tests := []struct { + name string + s string + method string + want *Endpoint + }{ + { + name: "orgs_projects: list-repository-projects", + s: `GET /repos/{owner}/{repo}/projects', { +`, + method: "GET", + want: &Endpoint{urlFormats: []string{"repos/%v/%v/projects"}, httpMethod: "GET"}, + }, + { + name: "orgs_projects: ListProjects", + s: `GET /orgs/{org}/projects', { +`, + method: "GET", + want: &Endpoint{urlFormats: []string{"orgs/%v/projects"}, httpMethod: "GET"}, + }, + } + + for i, tt := range tests { + t.Run(fmt.Sprintf("test #%v: %v", i, tt.name), func(t *testing.T) { + got := parseEndpoint(tt.s, tt.method) + + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("parseEndpoint = %#v, want %#v", got, tt.want) + } + }) + } +} diff --git a/update-urls/reactions_test.go b/update-urls/reactions_test.go index 1ef696f7799..8b9a0eff445 100644 --- a/update-urls/reactions_test.go +++ b/update-urls/reactions_test.go @@ -11,7 +11,7 @@ import ( func newReactionsPipeline() *pipelineSetup { return &pipelineSetup{ - baseURL: "https://developer.github.com/v3/reactions/", + baseURL: "https://docs.github.com/en/rest/reference/reactions/", endpointsFromWebsite: reactionsWant, filename: "reactions.go", serviceName: "ReactionsService", @@ -128,3033 +128,5696 @@ var reactionsWant = endpointsByFragmentID{ "list-reactions-for-a-team-discussion-legacy": []*Endpoint{{urlFormats: []string{"teams/%v/discussions/%v/reactions"}, httpMethod: "GET"}}, } -var reactionsTestWebPage = ` - - - - - - - - - Reactions | GitHub Developer Guide - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +var reactionsTestWebPage = ` + + + Reactions - GitHub Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + +