From 7aee2d9c0b421e94d4e0afad69a04c29aabb8e2c Mon Sep 17 00:00:00 2001 From: Jake Champlin Date: Wed, 28 Jun 2017 15:27:48 -0400 Subject: [PATCH 1/2] r/github_repository: Allow updating default_branch Allows a user to update the default branch for a repository. This cannot be set during initial creation of the repository, and can only be configured during Updates to an existing repository. The GitHub API will also omit an error during Update if a corresponding ref is not found for the target branch. ``` $ make testacc TEST=./github TESTARGS="-run=TestAccGithubRepository_defaultBranch" ==> Checking that code complies with gofmt requirements... TF_ACC=1 go test ./github -v -run=TestAccGithubRepository_defaultBranch -timeout 120m === RUN TestAccGithubRepository_defaultBranch --- PASS: TestAccGithubRepository_defaultBranch (5.82s) PASS ok github.com/terraform-providers/terraform-provider-github/github 5.826s ``` --- github/resource_github_repository.go | 19 ++- github/resource_github_repository_test.go | 145 ++++++++++++++++++++++ website/docs/r/repository.html.markdown | 6 +- 3 files changed, 164 insertions(+), 6 deletions(-) diff --git a/github/resource_github_repository.go b/github/resource_github_repository.go index 144237ee72..fa6e340abc 100644 --- a/github/resource_github_repository.go +++ b/github/resource_github_repository.go @@ -2,6 +2,7 @@ package github import ( "context" + "fmt" "log" "github.com/google/go-github/github" @@ -68,15 +69,17 @@ func resourceGithubRepository() *schema.Resource { Type: schema.TypeBool, Optional: true, }, + "default_branch": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "Can only be set after initial repository creation, and only if the target branch exists", + }, "full_name": { Type: schema.TypeString, Computed: true, }, - "default_branch": { - Type: schema.TypeString, - Computed: true, - }, "ssh_clone_url": { Type: schema.TypeString, Computed: true, @@ -130,6 +133,10 @@ func resourceGithubRepositoryObject(d *schema.ResourceData) *github.Repository { func resourceGithubRepositoryCreate(d *schema.ResourceData, meta interface{}) error { client := meta.(*Organization).client + if _, ok := d.GetOk("default_branch"); ok { + return fmt.Errorf("Cannot set the default branch on a new repository.") + } + repoReq := resourceGithubRepositoryObject(d) log.Printf("[DEBUG] create github repository %s/%s", meta.(*Organization).name, *repoReq.Name) repo, _, err := client.Repositories.Create(context.TODO(), meta.(*Organization).name, repoReq) @@ -181,6 +188,10 @@ func resourceGithubRepositoryRead(d *schema.ResourceData, meta interface{}) erro func resourceGithubRepositoryUpdate(d *schema.ResourceData, meta interface{}) error { client := meta.(*Organization).client repoReq := resourceGithubRepositoryObject(d) + // Can only set `default_branch` on an already created repository with the target branches ref already in-place + defaultBranch := d.Get("default_branch").(string) + repoReq.DefaultBranch = &defaultBranch + repoName := d.Id() log.Printf("[DEBUG] update github repository %s/%s", meta.(*Organization).name, repoName) repo, _, err := client.Repositories.Edit(context.TODO(), meta.(*Organization).name, repoName, repoReq) diff --git a/github/resource_github_repository_test.go b/github/resource_github_repository_test.go index 0395a1cd1a..8e8e77743c 100644 --- a/github/resource_github_repository_test.go +++ b/github/resource_github_repository_test.go @@ -3,6 +3,7 @@ package github import ( "context" "fmt" + "os" "strings" "testing" @@ -80,6 +81,62 @@ func TestAccGithubRepository_importBasic(t *testing.T) { }) } +func TestAccGithubRepository_defaultBranch(t *testing.T) { + var repo github.Repository + randString := acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum) + name := fmt.Sprintf("tf-acc-test-%s", randString) + description := fmt.Sprintf("Terraform acceptance tests %s", randString) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckGithubRepositoryDestroy, + Steps: []resource.TestStep{ + { + Config: testAccGithubRepositoryConfigDefaultBranch(randString), + Check: resource.ComposeTestCheckFunc( + testAccCheckGithubRepositoryExists("github_repository.foo", &repo), + testAccCheckGithubRepositoryAttributes(&repo, &testAccGithubRepositoryExpectedAttributes{ + Name: name, + Description: description, + Homepage: "http://example.com/", + HasIssues: true, + HasWiki: true, + AllowMergeCommit: true, + AutoInit: true, + AllowSquashMerge: false, + AllowRebaseMerge: false, + HasDownloads: true, + DefaultBranch: "master", + }), + ), + }, + { + PreConfig: func() { + testAccCreateRepositoryBranch("foo", *repo.Name) + }, + Config: testAccGithubRepositoryUpdateConfigDefaultBranch(randString), + Check: resource.ComposeTestCheckFunc( + testAccCheckGithubRepositoryExists("github_repository.foo", &repo), + testAccCheckGithubRepositoryAttributes(&repo, &testAccGithubRepositoryExpectedAttributes{ + Name: name, + Description: "Updated " + description, + Homepage: "http://example.com/", + AutoInit: true, + HasIssues: true, + HasWiki: true, + AllowMergeCommit: true, + AllowSquashMerge: false, + AllowRebaseMerge: false, + HasDownloads: true, + DefaultBranch: "foo", + }), + ), + }, + }, + }) +} + func testAccCheckGithubRepositoryExists(n string, repo *github.Repository) resource.TestCheckFunc { return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[n] @@ -114,6 +171,7 @@ type testAccGithubRepositoryExpectedAttributes struct { AllowSquashMerge bool AllowRebaseMerge bool HasDownloads bool + AutoInit bool DefaultBranch string } @@ -156,6 +214,12 @@ func testAccCheckGithubRepositoryAttributes(repo *github.Repository, want *testA return fmt.Errorf("got default branch %q; want %q", *repo.DefaultBranch, want.DefaultBranch) } + if repo.AutoInit != nil { + if *repo.AutoInit != want.AutoInit { + return fmt.Errorf("got auto init %q; want %q", *repo.AutoInit, want.AutoInit) + } + } + // For the rest of these, we just want to make sure they've been // populated with something that seems somewhat reasonable. if !strings.HasSuffix(*repo.FullName, "/"+want.Name) { @@ -213,6 +277,42 @@ func testAccCheckGithubRepositoryDestroy(s *terraform.State) error { return nil } +func testAccCreateRepositoryBranch(branch, repository string) error { + org := os.Getenv("GITHUB_ORGANIZATION") + token := os.Getenv("GITHUB_TOKEN") + + config := Config{ + Token: token, + Organization: org, + } + + c, err := config.Client() + if err != nil { + panic(fmt.Sprintf("Error creating github client: %s", err)) + } + client := c.(*Organization).client + + refs, _, err := client.Git.GetRefs(context.TODO(), org, repository, "heads") + if err != nil { + panic(fmt.Sprintf("Error getting reference commit: %s", err)) + } + ref := refs[0] + + newRef := &github.Reference{ + Ref: github.String(fmt.Sprintf("refs/heads/%s", branch)), + Object: &github.GitObject{ + SHA: ref.Object.SHA, + }, + } + + _, _, err = client.Git.CreateRef(context.TODO(), org, repository, newRef) + if err != nil { + panic(fmt.Sprintf("Error creating git reference: %s", err)) + } + + return nil +} + func testAccGithubRepositoryConfig(randString string) string { return fmt.Sprintf(` resource "github_repository" "foo" { @@ -254,3 +354,48 @@ resource "github_repository" "foo" { } `, randString, randString) } + +func testAccGithubRepositoryConfigDefaultBranch(randString string) string { + return fmt.Sprintf(` +resource "github_repository" "foo" { + name = "tf-acc-test-%s" + description = "Terraform acceptance tests %s" + homepage_url = "http://example.com/" + + # So that acceptance tests can be run in a github organization + # with no billing + private = false + + has_issues = true + has_wiki = true + allow_merge_commit = true + allow_squash_merge = false + allow_rebase_merge = false + has_downloads = true + auto_init = true +} +`, randString, randString) +} + +func testAccGithubRepositoryUpdateConfigDefaultBranch(randString string) string { + return fmt.Sprintf(` +resource "github_repository" "foo" { + name = "tf-acc-test-%s" + description = "Updated Terraform acceptance tests %s" + homepage_url = "http://example.com/" + + # So that acceptance tests can be run in a github organization + # with no billing + private = false + + has_issues = true + has_wiki = true + allow_merge_commit = true + allow_squash_merge = false + allow_rebase_merge = false + has_downloads = true + auto_init = true + default_branch = "foo" +} +`, randString, randString) +} diff --git a/website/docs/r/repository.html.markdown b/website/docs/r/repository.html.markdown index 67a2c01ac6..fc7850d6b2 100644 --- a/website/docs/r/repository.html.markdown +++ b/website/docs/r/repository.html.markdown @@ -56,14 +56,16 @@ The following arguments are supported: * `auto_init` - (Optional) Meaningful only during create; set to `true` to produce an initial commit in the repository. +* `default_branch` - (Optional) The name of the default branch of the repository. **NOTE:** This can only be set after a repository has already been created, +and after a correct reference has been created for the target branch inside the repository. This means a user will have to omit this parameter from the +initial repository creation and create the target branch inside of the repository prior to setting this attribute. + ## Attributes Reference The following additional attributes are exported: * `full_name` - A string of the form "orgname/reponame". -* `default_branch` - The name of the repository's default branch. - * `ssh_clone_url` - URL that can be provided to `git clone` to clone the repository via SSH. From b977d398ae40e8ccc8c4b562517f7608219d4a21 Mon Sep 17 00:00:00 2001 From: Jake Champlin Date: Wed, 28 Jun 2017 15:31:49 -0400 Subject: [PATCH 2/2] fix vet issue --- github/resource_github_repository_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/github/resource_github_repository_test.go b/github/resource_github_repository_test.go index 8e8e77743c..500aaea8f6 100644 --- a/github/resource_github_repository_test.go +++ b/github/resource_github_repository_test.go @@ -216,7 +216,7 @@ func testAccCheckGithubRepositoryAttributes(repo *github.Repository, want *testA if repo.AutoInit != nil { if *repo.AutoInit != want.AutoInit { - return fmt.Errorf("got auto init %q; want %q", *repo.AutoInit, want.AutoInit) + return fmt.Errorf("got auto init %t; want %t", *repo.AutoInit, want.AutoInit) } }