Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

r/github_repository: Allow updating default_branch #23

Merged
merged 2 commits into from
Jun 28, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 15 additions & 4 deletions github/resource_github_repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package github

import (
"context"
"fmt"
"log"

"github.com/google/go-github/github"
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down
145 changes: 145 additions & 0 deletions github/resource_github_repository_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package github
import (
"context"
"fmt"
"os"
"strings"
"testing"

Expand Down Expand Up @@ -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]
Expand Down Expand Up @@ -114,6 +171,7 @@ type testAccGithubRepositoryExpectedAttributes struct {
AllowSquashMerge bool
AllowRebaseMerge bool
HasDownloads bool
AutoInit bool

DefaultBranch string
}
Expand Down Expand Up @@ -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 %t; want %t", *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) {
Expand Down Expand Up @@ -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" {
Expand Down Expand Up @@ -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)
}
6 changes: 4 additions & 2 deletions website/docs/r/repository.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down