forked from integrations/terraform-provider-github
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[FEAT]: Add github_repository_topics resource (integrations#1846)
* only set topics if explicitly set in github_repository resource * Revert "only set topics if explicitly set in github_repository resource" This reverts commit 70977ca. * add repository_topics resource * change repository resource to compute topics if not set * add validation function to the repo name * import needs to set the repository argument * add tests * add docs for repository_topics resource * formatting * make the usage of github_repository_topics clearer * add github_repository_topic to gtihub.erb * add link to issue showing intended usage of repository_topics resource2 * Update website/docs/r/repository.html.markdown --------- Co-authored-by: Keegan Campbell <[email protected]>
- Loading branch information
1 parent
a7237af
commit 5396104
Showing
7 changed files
with
269 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
package github | ||
|
||
import ( | ||
"context" | ||
"regexp" | ||
|
||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema" | ||
"github.com/hashicorp/terraform-plugin-sdk/helper/validation" | ||
) | ||
|
||
func resourceGithubRepositoryTopics() *schema.Resource { | ||
return &schema.Resource{ | ||
Create: resourceGithubRepositoryTopicsCreateOrUpdate, | ||
Read: resourceGithubRepositoryTopicsRead, | ||
Update: resourceGithubRepositoryTopicsCreateOrUpdate, | ||
Delete: resourceGithubRepositoryTopicsDelete, | ||
Importer: &schema.ResourceImporter{ | ||
State: func(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { | ||
d.Set("repository", d.Id()) | ||
return []*schema.ResourceData{d}, nil | ||
}, | ||
}, | ||
Schema: map[string]*schema.Schema{ | ||
"repository": { | ||
Type: schema.TypeString, | ||
Required: true, | ||
ValidateFunc: validation.StringMatch(regexp.MustCompile(`^[-a-zA-Z0-9_.]{1,100}$`), "must include only alphanumeric characters, underscores or hyphens and consist of 100 characters or less"), | ||
Description: "The name of the repository. The name is not case sensitive.", | ||
}, | ||
"topics": { | ||
Type: schema.TypeSet, | ||
Required: true, | ||
Description: "An array of topics to add to the repository. Pass one or more topics to replace the set of existing topics. Send an empty array ([]) to clear all topics from the repository. Note: Topic names cannot contain uppercase letters.", | ||
Elem: &schema.Schema{ | ||
Type: schema.TypeString, | ||
ValidateFunc: validation.StringMatch(regexp.MustCompile(`^[a-z0-9][a-z0-9-]{0,49}$`), "must include only lowercase alphanumeric characters or hyphens and cannot start with a hyphen and consist of 50 characters or less"), | ||
}, | ||
}}, | ||
} | ||
|
||
} | ||
|
||
func resourceGithubRepositoryTopicsCreateOrUpdate(d *schema.ResourceData, meta interface{}) error { | ||
client := meta.(*Owner).v3client | ||
ctx := context.Background() | ||
|
||
owner := meta.(*Owner).name | ||
repoName := d.Get("repository").(string) | ||
topics := expandStringList(d.Get("topics").(*schema.Set).List()) | ||
|
||
if len(topics) > 0 { | ||
_, _, err := client.Repositories.ReplaceAllTopics(ctx, owner, repoName, topics) | ||
if err != nil { | ||
return err | ||
} | ||
} | ||
|
||
d.SetId(repoName) | ||
return resourceGithubRepositoryTopicsRead(d, meta) | ||
} | ||
|
||
func resourceGithubRepositoryTopicsRead(d *schema.ResourceData, meta interface{}) error { | ||
client := meta.(*Owner).v3client | ||
ctx := context.WithValue(context.Background(), ctxId, d.Id()) | ||
|
||
owner := meta.(*Owner).name | ||
repoName := d.Get("repository").(string) | ||
|
||
topics, _, err := client.Repositories.ListAllTopics(ctx, owner, repoName) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
d.Set("topics", flattenStringList(topics)) | ||
return nil | ||
} | ||
|
||
func resourceGithubRepositoryTopicsDelete(d *schema.ResourceData, meta interface{}) error { | ||
client := meta.(*Owner).v3client | ||
ctx := context.WithValue(context.Background(), ctxId, d.Id()) | ||
|
||
owner := meta.(*Owner).name | ||
repoName := d.Get("repository").(string) | ||
|
||
_, _, err := client.Repositories.ReplaceAllTopics(ctx, owner, repoName, []string{}) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
package github | ||
|
||
import ( | ||
"fmt" | ||
"testing" | ||
|
||
"github.com/hashicorp/terraform-plugin-sdk/helper/acctest" | ||
"github.com/hashicorp/terraform-plugin-sdk/helper/resource" | ||
) | ||
|
||
func TestAccGithubRepositoryTopics(t *testing.T) { | ||
t.Run("create repository topics and import them", func(t *testing.T) { | ||
randomID := acctest.RandStringFromCharSet(5, acctest.CharSetAlphaNum) | ||
|
||
config := fmt.Sprintf(` | ||
resource "github_repository" "test" { | ||
name = "tf-acc-test-%s" | ||
auto_init = true | ||
} | ||
resource "github_repository_topics" "test" { | ||
repository = github_repository.test.name | ||
topics = ["test", "test-2"] | ||
} | ||
`, randomID) | ||
|
||
const resourceName = "github_repository_topics.test" | ||
|
||
check := resource.ComposeTestCheckFunc( | ||
resource.TestCheckResourceAttr(resourceName, "topics.#", "2"), | ||
) | ||
|
||
testCase := func(t *testing.T, mode string) { | ||
resource.Test(t, resource.TestCase{ | ||
PreCheck: func() { skipUnlessMode(t, mode) }, | ||
Providers: testAccProviders, | ||
Steps: []resource.TestStep{ | ||
{ | ||
Config: config, | ||
Check: check, | ||
}, | ||
{ | ||
ResourceName: resourceName, | ||
ImportState: true, | ||
ImportStateVerify: true, | ||
}, | ||
}, | ||
}) | ||
} | ||
|
||
t.Run("with an anonymous account", func(t *testing.T) { | ||
t.Skip("anonymous account not supported for this operation") | ||
}) | ||
|
||
t.Run("with an individual account", func(t *testing.T) { | ||
testCase(t, individual) | ||
}) | ||
|
||
t.Run("with an organization account", func(t *testing.T) { | ||
testCase(t, organization) | ||
}) | ||
}) | ||
|
||
t.Run("create repository topics and update them", func(t *testing.T) { | ||
randomID := acctest.RandStringFromCharSet(5, acctest.CharSetAlphaNum) | ||
|
||
configBefore := fmt.Sprintf(` | ||
resource "github_repository" "test" { | ||
name = "tf-acc-test-%s" | ||
auto_init = true | ||
} | ||
resource "github_repository_topics" "test" { | ||
repository = github_repository.test.name | ||
topics = ["test", "test-2"] | ||
} | ||
`, randomID) | ||
|
||
configAfter := fmt.Sprintf(` | ||
resource "github_repository" "test" { | ||
name = "tf-acc-test-%s" | ||
auto_init = true | ||
} | ||
resource "github_repository_topics" "test" { | ||
repository = github_repository.test.name | ||
topics = ["test", "test-2", "extra-topic"] | ||
} | ||
`, randomID) | ||
|
||
const resourceName = "github_repository_topics.test" | ||
|
||
checkBefore := resource.ComposeTestCheckFunc( | ||
resource.TestCheckResourceAttr(resourceName, "topics.#", "2"), | ||
) | ||
checkAfter := resource.ComposeTestCheckFunc( | ||
resource.TestCheckResourceAttr(resourceName, "topics.#", "3"), | ||
) | ||
|
||
testCase := func(t *testing.T, mode string) { | ||
resource.Test(t, resource.TestCase{ | ||
PreCheck: func() { skipUnlessMode(t, mode) }, | ||
Providers: testAccProviders, | ||
Steps: []resource.TestStep{ | ||
{ | ||
Config: configBefore, | ||
Check: checkBefore, | ||
}, | ||
{ | ||
Config: configAfter, | ||
Check: checkAfter, | ||
}, | ||
}, | ||
}) | ||
} | ||
|
||
t.Run("with an anonymous account", func(t *testing.T) { | ||
t.Skip("anonymous account not supported for this operation") | ||
}) | ||
|
||
t.Run("with an individual account", func(t *testing.T) { | ||
testCase(t, individual) | ||
}) | ||
|
||
t.Run("with an organization account", func(t *testing.T) { | ||
testCase(t, organization) | ||
}) | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
--- | ||
layout: "github" | ||
page_title: "GitHub: github_repository_topics" | ||
description: |- | ||
Creates and manages the topics on a repository | ||
--- | ||
|
||
# github_repository_topics | ||
|
||
This resource allows you to create and manage topics for repositories within your GitHub organization or personal account. | ||
|
||
~> Note: This resource is not compatible with the `topic` attribute of the `github_repository` Use either ``github_repository_topics`` | ||
or ``topic`` in ``github_repository``. `github_repository_topics` is only meant to be used if the repository itself is not handled via terraform, for example if it's only read as a datasource (see [issue #1845](https://github.com/integrations/terraform-provider-github/issues/1845)). | ||
|
||
## Example Usage | ||
|
||
```hcl | ||
data "github_repository" "test" { | ||
name = "test" | ||
} | ||
resource "github_repository_topics" "test" { | ||
repository = github_repository.test.name | ||
topics = ["topic-1", "topic-2"] | ||
} | ||
``` | ||
|
||
## Argument Reference | ||
|
||
The following arguments are supported: | ||
|
||
* `repository` - (Required) The repository name. | ||
|
||
* `topics` - (Required) A list of topics to add to the repository. | ||
|
||
## Import | ||
|
||
Repository topics can be imported using the `name` of the repository. | ||
|
||
``` | ||
$ terraform import github_repository_topics.terraform terraform | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters