diff --git a/github/data_source_github_repository.go b/github/data_source_github_repository.go index ed2a30143b..e6fd1a36e2 100644 --- a/github/data_source_github_repository.go +++ b/github/data_source_github_repository.go @@ -28,6 +28,11 @@ func dataSourceGithubRepository() *schema.Resource { Computed: true, ConflictsWith: []string{"full_name"}, }, + "owner": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, "description": { Type: schema.TypeString, Default: nil, @@ -373,6 +378,7 @@ func dataSourceGithubRepositoryRead(d *schema.ResourceData, meta interface{}) er d.SetId(repoName) d.Set("name", repo.GetName()) + d.Set("owner", owner) d.Set("description", repo.GetDescription()) d.Set("homepage_url", repo.GetHomepage()) d.Set("private", repo.GetPrivate()) diff --git a/github/resource_github_actions_secret.go b/github/resource_github_actions_secret.go index 79fea4f729..fcf4f749d6 100644 --- a/github/resource_github_actions_secret.go +++ b/github/resource_github_actions_secret.go @@ -23,6 +23,13 @@ func resourceGithubActionsSecret() *schema.Resource { }, Schema: map[string]*schema.Schema{ + "owner": { + Type: schema.TypeString, + Required: false, + Optional: true, + ForceNew: true, + Description: "The account owner of the repository.", + }, "repository": { Type: schema.TypeString, Required: true, @@ -68,9 +75,9 @@ func resourceGithubActionsSecret() *schema.Resource { func resourceGithubActionsSecretCreateOrUpdate(d *schema.ResourceData, meta interface{}) error { client := meta.(*Owner).v3client - owner := meta.(*Owner).name ctx := context.Background() + owner := getOwnerParam(d.Get("owner").(string), meta.(*Owner).name) repo := d.Get("repository").(string) secretName := d.Get("secret_name").(string) plaintextValue := d.Get("plaintext_value").(string) @@ -109,7 +116,7 @@ func resourceGithubActionsSecretCreateOrUpdate(d *schema.ResourceData, meta inte func resourceGithubActionsSecretRead(d *schema.ResourceData, meta interface{}) error { client := meta.(*Owner).v3client - owner := meta.(*Owner).name + owner := getOwnerParam(d.Get("owner").(string), meta.(*Owner).name) ctx := context.Background() repoName, secretName, err := parseTwoPartID(d.Id(), "repository", "secret_name") @@ -169,7 +176,7 @@ func resourceGithubActionsSecretRead(d *schema.ResourceData, meta interface{}) e func resourceGithubActionsSecretDelete(d *schema.ResourceData, meta interface{}) error { client := meta.(*Owner).v3client - orgName := meta.(*Owner).name + owner := getOwnerParam(d.Get("owner").(string), meta.(*Owner).name) ctx := context.WithValue(context.Background(), ctxId, d.Id()) repoName, secretName, err := parseTwoPartID(d.Id(), "repository", "secret_name") @@ -177,14 +184,14 @@ func resourceGithubActionsSecretDelete(d *schema.ResourceData, meta interface{}) return err } - _, err = client.Actions.DeleteRepoSecret(ctx, orgName, repoName, secretName) + _, err = client.Actions.DeleteRepoSecret(ctx, owner, repoName, secretName) return err } func resourceGithubActionsSecretImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { client := meta.(*Owner).v3client - owner := meta.(*Owner).name + owner := getOwnerParam(d.Get("owner").(string), meta.(*Owner).name) ctx := context.Background() parts := strings.Split(d.Id(), "/") @@ -257,3 +264,10 @@ func encryptPlaintext(plaintext, publicKeyB64 string) ([]byte, error) { return cipherText, nil } + +func getOwnerParam(param string, default_param string) string { + if len(param) > 0 { + return param + } + return default_param +} diff --git a/github/resource_github_actions_secret_test.go b/github/resource_github_actions_secret_test.go index 21bf90233a..b7a78baa1d 100644 --- a/github/resource_github_actions_secret_test.go +++ b/github/resource_github_actions_secret_test.go @@ -7,7 +7,6 @@ import ( "testing" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" ) @@ -295,4 +294,104 @@ func TestAccGithubActionsSecret(t *testing.T) { }) }) + + t.Run("creates and updates another owner repository name without error", func(t *testing.T) { + repoName := fmt.Sprintf("tf-acc-test-%s-with-owner", randomID) + updatedRepoName := fmt.Sprintf("tf-acc-test-%s-with-owner-updated", randomID) + secretValue := base64.StdEncoding.EncodeToString([]byte("super_secret_value")) + + config := fmt.Sprintf(` + resource "github_repository" "test" { + name = "%s" + vulnerability_alerts = true + } + + resource "github_actions_secret" "plaintext_secret" { + owner = github_repository.test.owner + repository = github_repository.test.name + secret_name = "test_plaintext_secret" + plaintext_value = "%s" + } + + resource "github_actions_secret" "encrypted_secret" { + repository = github_repository.test.name + secret_name = "test_encrypted_secret" + encrypted_value = "%s" + } + `, repoName, secretValue, secretValue) + + checks := map[string]resource.TestCheckFunc{ + "before": resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr( + "github_actions_secret.plaintext_secret", "repository", + repoName, + ), + resource.TestCheckResourceAttr( + "github_actions_secret.plaintext_secret", "plaintext_value", + secretValue, + ), + resource.TestCheckResourceAttr( + "github_actions_secret.encrypted_secret", "encrypted_value", + secretValue, + ), + resource.TestCheckResourceAttrSet( + "github_actions_secret.plaintext_secret", "created_at", + ), + resource.TestCheckResourceAttrSet( + "github_actions_secret.plaintext_secret", "updated_at", + ), + ), + "after": resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr( + "github_actions_secret.plaintext_secret", "repository", + updatedRepoName, + ), + resource.TestCheckResourceAttr( + "github_actions_secret.plaintext_secret", "plaintext_value", + secretValue, + ), + resource.TestCheckResourceAttr( + "github_actions_secret.encrypted_secret", "encrypted_value", + secretValue, + ), + resource.TestCheckResourceAttrSet( + "github_actions_secret.plaintext_secret", "created_at", + ), + resource.TestCheckResourceAttrSet( + "github_actions_secret.plaintext_secret", "updated_at", + ), + ), + } + + 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: checks["before"], + }, + { + Config: strings.Replace(config, + repoName, + updatedRepoName, 2), + Check: checks["after"], + }, + }, + }) + } + + 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) + }) + }) } diff --git a/github/resource_github_repository.go b/github/resource_github_repository.go index f28cc4c6e8..be54f85de3 100644 --- a/github/resource_github_repository.go +++ b/github/resource_github_repository.go @@ -39,6 +39,12 @@ func resourceGithubRepository() *schema.Resource { ValidateDiagFunc: toDiagFunc(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"), "name"), Description: "The name of the repository.", }, + "owner": { + Type: schema.TypeString, + Computed: true, + Optional: true, + Description: "The repository's owner.", + }, "description": { Type: schema.TypeString, Optional: true, diff --git a/website/docs/r/actions_secret.html.markdown b/website/docs/r/actions_secret.html.markdown index 53b70864a8..6f8f47d8d1 100644 --- a/website/docs/r/actions_secret.html.markdown +++ b/website/docs/r/actions_secret.html.markdown @@ -33,6 +33,7 @@ resource "github_actions_secret" "example_secret" { } resource "github_actions_secret" "example_secret" { + owner = "example_owner" repository = "example_repository" secret_name = "example_secret_name" encrypted_value = var.some_encrypted_secret_string @@ -45,6 +46,7 @@ The following arguments are supported: * `repository` - (Required) Name of the repository * `secret_name` - (Required) Name of the secret +* `owner` - (Optional) The account owner of the repository * `encrypted_value` - (Optional) Encrypted value of the secret using the GitHub public key in Base64 format. * `plaintext_value` - (Optional) Plaintext value of the secret to be encrypted @@ -62,4 +64,4 @@ $ terraform import github_actions_secret.example_secret repository/secret_name ``` NOTE: the implementation is limited in that it won't fetch the value of the -`plaintext_value` or `encrypted_value` fields when importing. You may need to ignore changes for these as a workaround. \ No newline at end of file +`plaintext_value` or `encrypted_value` fields when importing. You may need to ignore changes for these as a workaround.