From a1a61d8b7391ce44f5f77d92d51489db276d4c8e Mon Sep 17 00:00:00 2001 From: whgiles Date: Wed, 13 Nov 2024 14:40:05 -0500 Subject: [PATCH 1/4] added Import function for action env secrets --- ...ource_github_actions_environment_secret.go | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/github/resource_github_actions_environment_secret.go b/github/resource_github_actions_environment_secret.go index d1568a567a..1f06007576 100644 --- a/github/resource_github_actions_environment_secret.go +++ b/github/resource_github_actions_environment_secret.go @@ -3,9 +3,11 @@ package github import ( "context" "encoding/base64" + "fmt" "log" "net/http" "net/url" + "strings" "github.com/google/go-github/v65/github" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" @@ -17,6 +19,9 @@ func resourceGithubActionsEnvironmentSecret() *schema.Resource { Create: resourceGithubActionsEnvironmentSecretCreateOrUpdate, Read: resourceGithubActionsEnvironmentSecretRead, Delete: resourceGithubActionsEnvironmentSecretDelete, + Importer: &schema.ResourceImporter{ + State: resourceGithubActionsSecretImport, + }, Schema: map[string]*schema.Schema{ "repository": { @@ -211,6 +216,42 @@ func resourceGithubActionsEnvironmentSecretDelete(d *schema.ResourceData, meta i return err } +func resourceGithubActionsEnvironmentSecretImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { + client := meta.(*Owner).v3client + owner := meta.(*Owner).name + ctx := context.Background() + + parts := strings.Split(d.Id(), "/") + if len(parts) != 3 { + return nil, fmt.Errorf("invalid ID specified: supplied ID must be written as //") + } + + d.SetId(buildThreePartID(parts[0], parts[1], parts[2])) + + repoName, envName, secretName, err := parseThreePartID(d.Id(), "repository", "environment", "secret_name") + if err != nil { + return nil, err + } + + repo, _, err := client.Repositories.Get(ctx, owner, repoName) + + secret, _, err := client.Actions.GetEnvSecret(ctx, int(repo.GetID()), escapedEnvName, secretName) + if err != nil { + return nil, err + } + + d.Set("repository", repoName) + d.Set("secret_name", secretName) + d.Set("environment", envName) + + // encrypted_value or plaintext_value can not be imported + + d.Set("created_at", secret.CreatedAt.String()) + d.Set("updated_at", secret.UpdatedAt.String()) + + return []*schema.ResourceData{d}, nil +} + func getEnvironmentPublicKeyDetails(repoID int64, envName string, meta interface{}) (keyId, pkValue string, err error) { client := meta.(*Owner).v3client ctx := context.Background() From d083de042f87ed44ee71f3e5694b1ab791e2ae69 Mon Sep 17 00:00:00 2001 From: whgiles Date: Wed, 13 Nov 2024 14:42:14 -0500 Subject: [PATCH 2/4] updated website --- .../actions_environment_secret.html.markdown | 24 ++++++++++++------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/website/docs/r/actions_environment_secret.html.markdown b/website/docs/r/actions_environment_secret.html.markdown index 03f5bb88a8..00a04abf91 100644 --- a/website/docs/r/actions_environment_secret.html.markdown +++ b/website/docs/r/actions_environment_secret.html.markdown @@ -57,18 +57,24 @@ resource "github_actions_environment_secret" "test_secret" { The following arguments are supported: - -* `repository` - (Required) Name of the repository. -* `environment` - (Required) Name of the environment. -* `secret_name` - (Required) Name of the secret. -* `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. +- `repository` - (Required) Name of the repository. +- `environment` - (Required) Name of the environment. +- `secret_name` - (Required) Name of the secret. +- `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. ## Attributes Reference -* `created_at` - Date of actions_environment_secret creation. -* `updated_at` - Date of actions_environment_secret update. +- `created_at` - Date of actions_environment_secret creation. +- `updated_at` - Date of actions_environment_secret update. ## Import -This resource does not support importing. If you'd like to help contribute it, please visit our [GitHub page](https://github.com/integrations/terraform-provider-github)! \ No newline at end of file +This resource can be imported using an ID made up of the `repository`, `environment` and `secret_name`: + +``` +$ terraform import github_actions_secret.example_secret // +``` + +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. From 96f2a87a523341749b882837d6567bbb8c2dd1bc Mon Sep 17 00:00:00 2001 From: whgiles Date: Wed, 13 Nov 2024 14:54:10 -0500 Subject: [PATCH 3/4] fix --- github/resource_github_actions_environment_secret.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/github/resource_github_actions_environment_secret.go b/github/resource_github_actions_environment_secret.go index 1f06007576..b319b11fa8 100644 --- a/github/resource_github_actions_environment_secret.go +++ b/github/resource_github_actions_environment_secret.go @@ -20,7 +20,7 @@ func resourceGithubActionsEnvironmentSecret() *schema.Resource { Read: resourceGithubActionsEnvironmentSecretRead, Delete: resourceGithubActionsEnvironmentSecretDelete, Importer: &schema.ResourceImporter{ - State: resourceGithubActionsSecretImport, + State: resourceGithubActionsEnvironmentSecretImport, }, Schema: map[string]*schema.Schema{ From 3bc2804ac6dd2a7d08d96bc7c1a64b5202f181b4 Mon Sep 17 00:00:00 2001 From: whgiles Date: Thu, 14 Nov 2024 09:51:56 -0500 Subject: [PATCH 4/4] added tests --- ..._github_actions_environment_secret_test.go | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/github/resource_github_actions_environment_secret_test.go b/github/resource_github_actions_environment_secret_test.go index 0f55863370..6398ea186b 100644 --- a/github/resource_github_actions_environment_secret_test.go +++ b/github/resource_github_actions_environment_secret_test.go @@ -167,4 +167,59 @@ func TestAccGithubActionsEnvironmentSecret(t *testing.T) { }) + t.Run("imports secret without error", func(t *testing.T) { + secretValue := "super_secret_value" + envName := "environment / test" + secretName := "test_plaintext_secret_name" + secretValue := "secret_value" + + config := fmt.Sprintf(` + resource "github_repository" "test" { + name = "tf-acc-test-%s" + } + + resource "github_repository_environment" "test" { + repository = github_repository.test.name + environment = "%s" + } + + resource "github_actions_environment_secret" "secret" { + repository = github_repository.test.name + environment = github_repository_environment.test.environment + secret_name = "%s" + plaintext_value = "%s" + } + `, randomID, envName, secretName, secretValue) + + testCase := func(t *testing.T, mode string) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { skipUnlessMode(t, mode) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: config, + }, + { + ResourceName: "github_actions_environment_secret.secret", + ImportStateId: fmt.Sprintf(`tf-acc-test-%s:%s:%s`, randomID, envName, secretName), + 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) + }) + + }) }