diff --git a/README.md b/README.md index b9ae82f..6cc4838 100644 --- a/README.md +++ b/README.md @@ -88,6 +88,22 @@ For complete usage of go-github, see the full [package docs][]. [personal API token]: https://github.com/blog/1509-personal-api-tokens [package docs]: https://godoc.org/github.com/google/go-github/github +### Integration Tests ### + +You can run the integration tests from from the `tests` directory with: + +```bash +GITHUB_AUTH_TOKEN= go test ./... +``` + +You can create a token here: https://github.com/settings/tokens + +These scopes are needed: + +* repo +* delete_repo +* user +* admin:public_key ## Roadmap ## diff --git a/github/git_blobs.go b/github/git_blobs.go index 133780b..55148fd 100644 --- a/github/git_blobs.go +++ b/github/git_blobs.go @@ -33,7 +33,7 @@ func (s *GitService) GetBlob(owner string, repo string, sha string) (*Blob, *Res // CreateBlob creates a blob object. // -// GitHub API docs: http://developer.github.com/v3/git/blobs/#create-a-blob +// GitHub API docs: https://developer.github.com/v3/git/blobs/#create-a-blob func (s *GitService) CreateBlob(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/repos.go b/github/repos.go index c9eb37a..0f8353f 100644 --- a/github/repos.go +++ b/github/repos.go @@ -515,3 +515,24 @@ func (s *RepositoriesService) GetBranch(owner, repo, branch string) (*Branch, *R return b, resp, err } + +// EditBranch edits the branch (currently only Branch Protection) +// +// GitHub API docs: https://developer.github.com/v3/repos/#enabling-and-disabling-branch-protection +func (s *RepositoriesService) EditBranch(owner, repo, branchName string, branch *Branch) (*Branch, *Response, error) { + u := fmt.Sprintf("repos/%v/%v/branches/%v", owner, repo, branchName) + req, err := s.client.NewRequest("PATCH", u, branch) + if err != nil { + return nil, nil, err + } + + req.Header.Set("Accept", mediaTypeProtectedBranchesPreview) + + b := new(Branch) + resp, err := s.client.Do(req, b) + if err != nil { + return nil, resp, err + } + + return b, resp, err +} diff --git a/github/repos_test.go b/github/repos_test.go index b882156..c4dcb0d 100644 --- a/github/repos_test.go +++ b/github/repos_test.go @@ -415,6 +415,42 @@ func TestRepositoriesService_GetBranch(t *testing.T) { } } +func TestRepositoriesService_EditBranch(t *testing.T) { + setup() + defer teardown() + + input := &Branch{ + Protection: &Protection{ + Enabled: Bool(true), + RequiredStatusChecks: &RequiredStatusChecks{ + EnforcementLevel: String("everyone"), + Contexts: &[]string{"continous-integration"}, + }, + }, + } + + mux.HandleFunc("/repos/o/r/branches/b", func(w http.ResponseWriter, r *http.Request) { + v := new(Branch) + json.NewDecoder(r.Body).Decode(v) + + testMethod(t, r, "PATCH") + if !reflect.DeepEqual(v, input) { + t.Errorf("Request body = %+v, want %+v", v, input) + } + testHeader(t, r, "Accept", mediaTypeProtectedBranchesPreview) + fmt.Fprint(w, `{"protection": {"enabled": true, "required_status_checks": {"enforcement_level": "everyone", "contexts": ["continous-integration"]}}}`) + }) + + branch, _, err := client.Repositories.EditBranch("o", "r", "b", input) + if err != nil { + t.Errorf("Repositories.EditBranch returned error: %v", err) + } + + if !reflect.DeepEqual(branch, input) { + t.Errorf("Repositories.EditBranch returned %+v, want %+v", branch, input) + } +} + func TestRepositoriesService_ListLanguages_invalidOwner(t *testing.T) { _, _, err := client.Repositories.ListLanguages("%", "%") testURLParseError(t, err) diff --git a/tests/integration/github_test.go b/tests/integration/github_test.go index 328f1e5..6d2306c 100644 --- a/tests/integration/github_test.go +++ b/tests/integration/github_test.go @@ -15,6 +15,8 @@ import ( "github.com/google/go-github/github" "golang.org/x/oauth2" + "net/http" + "math/rand" ) var ( @@ -45,3 +47,28 @@ func checkAuth(name string) bool { } return auth } + +func createRandomTestRepository(owner string, autoinit bool) (*github.Repository, error) { + // create random repo name that does not currently exist + var repoName string + for { + repoName = fmt.Sprintf("test-%d", rand.Int()) + _, resp, err := client.Repositories.Get(owner, repoName) + if err != nil { + if resp.StatusCode == http.StatusNotFound { + // found a non-existant repo, perfect + break + } + + return nil, err + } + } + + // create the repository + repo, _, err := client.Repositories.Create("", &github.Repository{Name: github.String(repoName), AutoInit:github.Bool(autoinit)}) + if err != nil { + return nil, err + } + + return repo, nil +} diff --git a/tests/integration/repos_test.go b/tests/integration/repos_test.go index 624d60b..13a34c4 100644 --- a/tests/integration/repos_test.go +++ b/tests/integration/repos_test.go @@ -6,12 +6,11 @@ package tests import ( - "fmt" - "math/rand" "net/http" "testing" "github.com/google/go-github/github" + "reflect" ) func TestRepositories_CRUD(t *testing.T) { @@ -25,24 +24,9 @@ func TestRepositories_CRUD(t *testing.T) { t.Fatalf("Users.Get('') returned error: %v", err) } - // create random repo name that does not currently exist - var repoName string - for { - repoName = fmt.Sprintf("test-%d", rand.Int()) - _, resp, err := client.Repositories.Get(*me.Login, repoName) - if err != nil { - if resp.StatusCode == http.StatusNotFound { - // found a non-existant repo, perfect - break - } - t.Fatalf("Repositories.Get() returned error: %v", err) - } - } - - // create the repository - repo, _, err := client.Repositories.Create("", &github.Repository{Name: github.String(repoName)}) + repo, err := createRandomTestRepository(*me.Login, false) if err != nil { - t.Fatalf("Repositories.Create() returned error: %v", err) + t.Fatalf("createRandomTestRepository returned error: %v", err) } // update the repository description @@ -106,3 +90,56 @@ func TestRepositories_ServiceHooks(t *testing.T) { t.Fatalf("Repositories.ListServiceHooks() returned no hooks") } } + +func TestRepositories_EditBranches(t *testing.T) { + if !checkAuth("TestRepositories_EditBranches") { + return + } + + // get authenticated user + me, _, err := client.Users.Get("") + if err != nil { + t.Fatalf("Users.Get('') returned error: %v", err) + } + + repo, err := createRandomTestRepository(*me.Login, true) + if err != nil { + t.Fatalf("createRandomTestRepository returned error: %v", err) + } + + branch, _, err := client.Repositories.GetBranch(*repo.Owner.Login, *repo.Name, "master") + if err != nil { + t.Fatalf("Repositories.GetBranch() returned error: %v", err) + } + + if *branch.Protection.Enabled { + t.Fatalf("Branch %v of repo %v is already protected", "master", *repo.Name) + } + + branch.Protection.Enabled = github.Bool(true) + branch.Protection.RequiredStatusChecks = &github.RequiredStatusChecks{ + EnforcementLevel:github.String("everyone"), + Contexts:&[]string{"continous-integration"}, + } + branch, _, err = client.Repositories.EditBranch(*repo.Owner.Login, *repo.Name, "master", branch) + if err != nil { + t.Fatalf("Repositories.EditBranch() returned error: %v", err) + } + + if !*branch.Protection.Enabled { + t.Fatalf("Branch %v of repo %v should be protected, but is not!", "master", *repo.Name) + } + if *branch.Protection.RequiredStatusChecks.EnforcementLevel != "everyone" { + t.Fatalf("RequiredStatusChecks should be enabled for everyone, set for: %v", *branch.Protection.RequiredStatusChecks.EnforcementLevel) + } + + wantedContexts := []string{"continous-integration"} + if !reflect.DeepEqual(*branch.Protection.RequiredStatusChecks.Contexts, wantedContexts) { + t.Fatalf("RequiredStatusChecks.Contexts should be: %v but is: %v", wantedContexts, *branch.Protection.RequiredStatusChecks.Contexts) + } + + _, err = client.Repositories.Delete(*repo.Owner.Login, *repo.Name) + if err != nil { + t.Fatalf("Repositories.Delete() returned error: %v", err) + } +}