Skip to content

Commit

Permalink
Merge pull request integrations#97 from endorama/add-repository-topics
Browse files Browse the repository at this point in the history
Add repository topics
  • Loading branch information
paultyng authored Jun 1, 2018
2 parents 90e5435 + 0bd458d commit d957f88
Show file tree
Hide file tree
Showing 3 changed files with 141 additions and 3 deletions.
30 changes: 28 additions & 2 deletions github/resource_github_repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,11 @@ func resourceGithubRepository() *schema.Resource {
Optional: true,
Default: false,
},
"topics": {
Type: schema.TypeList,
Elem: &schema.Schema{Type: schema.TypeString},
Optional: true,
},

"full_name": {
Type: schema.TypeString,
Expand Down Expand Up @@ -137,6 +142,7 @@ func resourceGithubRepositoryObject(d *schema.ResourceData) *github.Repository {
licenseTemplate := d.Get("license_template").(string)
gitIgnoreTemplate := d.Get("gitignore_template").(string)
archived := d.Get("archived").(bool)
topics := expandStringList(d.Get("topics").([]interface{}))

repo := &github.Repository{
Name: &name,
Expand All @@ -154,26 +160,36 @@ func resourceGithubRepositoryObject(d *schema.ResourceData) *github.Repository {
LicenseTemplate: &licenseTemplate,
GitignoreTemplate: &gitIgnoreTemplate,
Archived: &archived,
Topics: topics,
}

return repo
}

func resourceGithubRepositoryCreate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*Organization).client
ctx := context.TODO()

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)
repo, _, err := client.Repositories.Create(ctx, meta.(*Organization).name, repoReq)
if err != nil {
return err
}
d.SetId(*repo.Name)

topics := repoReq.Topics
if len(topics) > 0 {
_, _, err = client.Repositories.ReplaceAllTopics(ctx, meta.(*Organization).name, *repoReq.Name, topics)
if err != nil {
return err
}
}

return resourceGithubRepositoryUpdate(d, meta)
}

Expand Down Expand Up @@ -214,11 +230,13 @@ func resourceGithubRepositoryRead(d *schema.ResourceData, meta interface{}) erro
d.Set("git_clone_url", repo.GitURL)
d.Set("http_clone_url", repo.CloneURL)
d.Set("archived", repo.Archived)
d.Set("topics", flattenStringList(repo.Topics))
return nil
}

func resourceGithubRepositoryUpdate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*Organization).client
ctx := context.TODO()
repoReq := resourceGithubRepositoryObject(d)
// Can only set `default_branch` on an already created repository with the target branches ref already in-place
if v, ok := d.GetOk("default_branch"); ok {
Expand All @@ -231,12 +249,20 @@ func resourceGithubRepositoryUpdate(d *schema.ResourceData, meta interface{}) er

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)
repo, _, err := client.Repositories.Edit(ctx, meta.(*Organization).name, repoName, repoReq)
if err != nil {
return err
}
d.SetId(*repo.Name)

if d.HasChange("topics") {
topics := repoReq.Topics
_, _, err = client.Repositories.ReplaceAllTopics(ctx, meta.(*Organization).name, *repo.Name, topics)
if err != nil {
return err
}
}

return resourceGithubRepositoryRead(d, meta)
}

Expand Down
95 changes: 94 additions & 1 deletion github/resource_github_repository_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,75 @@ func TestAccGithubRepository_templates(t *testing.T) {
})
}

func TestAccGithubRepository_topics(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: testAccGithubRepositoryConfigTopics(randString, `"topic1", "topic2"`),
Check: resource.ComposeTestCheckFunc(
testAccCheckGithubRepositoryExists("github_repository.foo", &repo),
testAccCheckGithubRepositoryAttributes(&repo, &testAccGithubRepositoryExpectedAttributes{
Name: name,
Description: description,
Homepage: "http://example.com/",
Topics: []string{"topic1", "topic2"},

// non-zero defaults
DefaultBranch: "master",
AllowMergeCommit: true,
AllowSquashMerge: true,
AllowRebaseMerge: true,
}),
),
},
{
Config: testAccGithubRepositoryConfigTopics(randString, `"topic1", "topic2", "topic3"`),
Check: resource.ComposeTestCheckFunc(
testAccCheckGithubRepositoryExists("github_repository.foo", &repo),
testAccCheckGithubRepositoryAttributes(&repo, &testAccGithubRepositoryExpectedAttributes{
Name: name,
Description: description,
Homepage: "http://example.com/",
Topics: []string{"topic1", "topic2", "topic3"},

// non-zero defaults
DefaultBranch: "master",
AllowMergeCommit: true,
AllowSquashMerge: true,
AllowRebaseMerge: true,
}),
),
},
{
Config: testAccGithubRepositoryConfigTopics(randString, ``),
Check: resource.ComposeTestCheckFunc(
testAccCheckGithubRepositoryExists("github_repository.foo", &repo),
testAccCheckGithubRepositoryAttributes(&repo, &testAccGithubRepositoryExpectedAttributes{
Name: name,
Description: description,
Homepage: "http://example.com/",
Topics: []string{},

// non-zero defaults
DefaultBranch: "master",
AllowMergeCommit: true,
AllowSquashMerge: true,
AllowRebaseMerge: true,
}),
),
},
},
})
}

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 @@ -342,6 +411,7 @@ type testAccGithubRepositoryExpectedAttributes struct {
LicenseTemplate string
GitignoreTemplate string
Archived bool
Topics []string
}

func testAccCheckGithubRepositoryAttributes(repo *github.Repository, want *testAccGithubRepositoryExpectedAttributes) resource.TestCheckFunc {
Expand Down Expand Up @@ -377,7 +447,14 @@ func testAccCheckGithubRepositoryAttributes(repo *github.Repository, want *testA
if *repo.HasDownloads != want.HasDownloads {
return fmt.Errorf("got has downloads %#v; want %#v", *repo.HasDownloads, want.HasDownloads)
}

if len(want.Topics) != len(repo.Topics) {
return fmt.Errorf("got topics %#v; want %#v", repo.Topics, want.Topics)
}
for i := range want.Topics {
if repo.Topics[i] != want.Topics[i] {
return fmt.Errorf("got topics %#v; want %#v", repo.Topics, want.Topics)
}
}
if *repo.DefaultBranch != want.DefaultBranch {
return fmt.Errorf("got default branch %q; want %q", *repo.DefaultBranch, want.DefaultBranch)
}
Expand Down Expand Up @@ -628,3 +705,19 @@ resource "github_repository" "foo" {
}
`, randString, randString)
}

func testAccGithubRepositoryConfigTopics(randString string, topicList 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
topics = [%s]
}
`, randString, randString, topicList)
}
19 changes: 19 additions & 0 deletions github/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,22 @@ func validateTwoPartID(id string) error {
func buildTwoPartID(a, b *string) string {
return fmt.Sprintf("%s:%s", *a, *b)
}

func expandStringList(configured []interface{}) []string {
vs := make([]string, 0, len(configured))
for _, v := range configured {
val, ok := v.(string)
if ok && val != "" {
vs = append(vs, val)
}
}
return vs
}

func flattenStringList(v []string) []interface{} {
c := make([]interface{}, 0, len(v))
for _, s := range v {
c = append(c, s)
}
return c
}

0 comments on commit d957f88

Please sign in to comment.