diff --git a/CHANGELOG.md b/CHANGELOG.md index cac791ff07..7afab2fbf9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,17 @@ +## 4.11.0 (Jun 7, 2021) + +BREAKING CHANGES: + +- Allow PEM data to be passed directly for GitHub App provider authentication ([#803](https://github.com/integrations/terraform-provider-github/issues/803)) + +ENHANCEMENTS: + +- Add `encrypted_value` field to `github_actions_secret` and `github_actions_organization_secret` resources ([#807](https://github.com/integrations/terraform-provider-github/issues/807)) + +BUG FIXES: + +- Fix error handling when branch does not exist for `github_branch` resource ([#806](https://github.com/integrations/terraform-provider-github/issues/806)) + ## 4.10.1 (May 25, 2021) BUG FIXES: diff --git a/github/apps.go b/github/apps.go index ace8c5e12e..4466f9357d 100644 --- a/github/apps.go +++ b/github/apps.go @@ -4,23 +4,20 @@ import ( "crypto/x509" "encoding/json" "encoding/pem" + "errors" "fmt" - "gopkg.in/square/go-jose.v2" - "gopkg.in/square/go-jose.v2/jwt" "io/ioutil" "net/http" "time" -) -// GenerateOAuthTokenFromApp generates a GitHub OAuth access token from a set of valid GitHub App credentials. The -// returned token can be used to interact with both GitHub's REST and GraphQL APIs. -func GenerateOAuthTokenFromApp(baseURL, appID, appInstallationID, appPemFile string) (string, error) { - pemData, err := ioutil.ReadFile(appPemFile) - if err != nil { - return "", err - } + "gopkg.in/square/go-jose.v2" + "gopkg.in/square/go-jose.v2/jwt" +) - appJWT, err := generateAppJWT(appID, time.Now(), pemData) +// GenerateOAuthTokenFromApp generates a GitHub OAuth access token from a set of valid GitHub App credentials. +// The returned token can be used to interact with both GitHub's REST and GraphQL APIs. +func GenerateOAuthTokenFromApp(baseURL, appID, appInstallationID, pemData string) (string, error) { + appJWT, err := generateAppJWT(appID, time.Now(), []byte(pemData)) if err != nil { return "", err } @@ -73,6 +70,10 @@ func getInstallationAccessToken(baseURL string, jwt string, installationID strin func generateAppJWT(appID string, now time.Time, pemData []byte) (string, error) { block, _ := pem.Decode(pemData) + if block == nil { + return "", errors.New("No decodeable PEM data found") + } + privateKey, err := x509.ParsePKCS1PrivateKey(block.Bytes) if err != nil { return "", err diff --git a/github/apps_test.go b/github/apps_test.go index 15de2b63a4..1affd81ff9 100644 --- a/github/apps_test.go +++ b/github/apps_test.go @@ -5,33 +5,30 @@ import ( "crypto/x509" "encoding/pem" "fmt" - "gopkg.in/square/go-jose.v2" - "gopkg.in/square/go-jose.v2/jwt" "io/ioutil" "strings" "testing" "time" + + "gopkg.in/square/go-jose.v2" + "gopkg.in/square/go-jose.v2/jwt" ) const ( testGitHubAppID string = "123456789" testGitHubAppInstallationID string = "987654321" - testGitHubAppPrivateKeyFile string = "test-fixtures/github-app-key.pem" testGitHubAppPublicKeyFile string = "test-fixtures/github-app-key.pub" + testGitHubAppPrivateKeyFile string = "test-fixtures/github-app-key.pem" ) var ( testEpochTime = time.Unix(0, 0) + + testGitHubAppPrivateKeyPemData, _ = ioutil.ReadFile(testGitHubAppPrivateKeyFile) ) func TestGenerateAppJWT(t *testing.T) { - pemData, err := ioutil.ReadFile(testGitHubAppPrivateKeyFile) - if err != nil { - t.Logf("Failed to read private key file '%s': %s", testGitHubAppPrivateKeyFile, err) - t.FailNow() - } - - appJWT, err := generateAppJWT(testGitHubAppID, testEpochTime, pemData) + appJWT, err := generateAppJWT(testGitHubAppID, testEpochTime, testGitHubAppPrivateKeyPemData) t.Log(appJWT) if err != nil { t.Logf("Failed to generate GitHub app JWT: %s", err) diff --git a/github/data_source_github_branch.go b/github/data_source_github_branch.go index 3fd9845722..8d01225a74 100644 --- a/github/data_source_github_branch.go +++ b/github/data_source_github_branch.go @@ -2,9 +2,10 @@ package github import ( "context" - "fmt" "log" + "net/http" + "github.com/google/go-github/v35/github" "github.com/hashicorp/terraform-plugin-sdk/helper/schema" ) @@ -46,13 +47,17 @@ func dataSourceGithubBranchRead(d *schema.ResourceData, meta interface{}) error branchName := d.Get("branch").(string) branchRefName := "refs/heads/" + branchName - log.Printf("[DEBUG] Reading GitHub branch reference %s/%s (%s)", - orgName, repoName, branchRefName) - ref, resp, err := client.Git.GetRef( - context.TODO(), orgName, repoName, branchRefName) + log.Printf("[DEBUG] Reading GitHub branch reference %s/%s (%s)", orgName, repoName, branchRefName) + ref, resp, err := client.Git.GetRef(context.TODO(), orgName, repoName, branchRefName) if err != nil { - return fmt.Errorf("Error reading GitHub branch reference %s/%s (%s): %s", - orgName, repoName, branchRefName, err) + if err, ok := err.(*github.ErrorResponse); ok { + if err.Response.StatusCode == http.StatusNotFound { + log.Printf("Error reading GitHub branch reference %s/%s (%s): %s", orgName, repoName, branchRefName, err) + d.SetId("") + return nil + } + } + return err } d.SetId(buildTwoPartID(repoName, branchName)) diff --git a/github/data_source_github_branch_test.go b/github/data_source_github_branch_test.go index a958edba5f..a90dda10bb 100644 --- a/github/data_source_github_branch_test.go +++ b/github/data_source_github_branch_test.go @@ -59,4 +59,51 @@ func TestAccGithubBranchDataSource(t *testing.T) { }) }) + + t.Run("queries an invalid branch without error", func(t *testing.T) { + + config := fmt.Sprintf(` + resource "github_repository" "test" { + name = "tf-acc-test-%[1]s" + auto_init = true + } + + data "github_branch" "test" { + repository = github_repository.test.id + branch = "xxxxxx" + } + `, randomID) + + check := resource.ComposeTestCheckFunc( + resource.TestCheckNoResourceAttr( + "data.github_branch.test", "id", + ), + ) + + 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, + }, + }, + }) + } + + 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/provider.go b/github/provider.go index a52b5fc00c..cb5ed60083 100644 --- a/github/provider.go +++ b/github/provider.go @@ -153,7 +153,7 @@ func init() { "`token`. Anonymous mode is enabled if both `token` and `app_auth` are not set.", "app_auth.id": "The GitHub App ID.", "app_auth.installation_id": "The GitHub App installation instance ID.", - "app_auth.pem_file": "The GitHub App PEM file path.", + "app_auth.pem_file": "The GitHub App PEM file contents.", } } diff --git a/github/resource_github_actions_organization_secret.go b/github/resource_github_actions_organization_secret.go index 3e55589bcb..4e23ae5f3e 100644 --- a/github/resource_github_actions_organization_secret.go +++ b/github/resource_github_actions_organization_secret.go @@ -9,6 +9,7 @@ import ( "github.com/google/go-github/v35/github" "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/helper/validation" ) func resourceGithubActionsOrganizationSecret() *schema.Resource { @@ -31,11 +32,20 @@ func resourceGithubActionsOrganizationSecret() *schema.Resource { ForceNew: true, ValidateFunc: validateSecretNameFunc, }, + "encrypted_value": { + Type: schema.TypeString, + ForceNew: true, + Optional: true, + Sensitive: true, + ConflictsWith: []string{"plaintext_value"}, + ValidateFunc: validation.StringIsBase64, + }, "plaintext_value": { - Type: schema.TypeString, - Required: true, - ForceNew: true, - Sensitive: true, + Type: schema.TypeString, + ForceNew: true, + Optional: true, + Sensitive: true, + ConflictsWith: []string{"encrypted_value"}, }, "visibility": { Type: schema.TypeString, @@ -70,6 +80,7 @@ func resourceGithubActionsOrganizationSecretCreateOrUpdate(d *schema.ResourceDat secretName := d.Get("secret_name").(string) plaintextValue := d.Get("plaintext_value").(string) + var encryptedValue string visibility := d.Get("visibility").(string) selectedRepositories, hasSelectedRepositories := d.GetOk("selected_repository_ids") @@ -95,9 +106,14 @@ func resourceGithubActionsOrganizationSecretCreateOrUpdate(d *schema.ResourceDat return err } - encryptedText, err := encryptPlaintext(plaintextValue, publicKey) - if err != nil { - return err + if encryptedText, ok := d.GetOk("encrypted_value"); ok { + encryptedValue = encryptedText.(string) + } else { + encryptedBytes, err := encryptPlaintext(plaintextValue, publicKey) + if err != nil { + return err + } + encryptedValue = base64.StdEncoding.EncodeToString(encryptedBytes) } // Create an EncryptedSecret and encrypt the plaintext value into it @@ -106,7 +122,7 @@ func resourceGithubActionsOrganizationSecretCreateOrUpdate(d *schema.ResourceDat KeyID: keyId, Visibility: visibility, SelectedRepositoryIDs: selectedRepositoryIDs, - EncryptedValue: base64.StdEncoding.EncodeToString(encryptedText), + EncryptedValue: encryptedValue, } _, err = client.Actions.CreateOrUpdateOrgSecret(ctx, owner, eSecret) @@ -136,6 +152,7 @@ func resourceGithubActionsOrganizationSecretRead(d *schema.ResourceData, meta in return err } + d.Set("encrypted_value", d.Get("encrypted_value")) d.Set("plaintext_value", d.Get("plaintext_value")) d.Set("created_at", secret.CreatedAt.String()) d.Set("visibility", secret.Visibility) diff --git a/github/resource_github_actions_organization_secret_test.go b/github/resource_github_actions_organization_secret_test.go index 059d255c8e..33dca385b4 100644 --- a/github/resource_github_actions_organization_secret_test.go +++ b/github/resource_github_actions_organization_secret_test.go @@ -14,36 +14,50 @@ func TestAccGithubActionsOrganizationSecret(t *testing.T) { updatedSecretValue := "updated_super_secret_value" config := fmt.Sprintf(` - resource "github_actions_organization_secret" "test_secret" { - secret_name = "test_secret_name" + resource "github_actions_organization_secret" "plaintext_secret" { + secret_name = "test_plaintext_secret" plaintext_value = "%s" visibility = "private" } - `, secretValue) + + resource "github_actions_organization_secret" "encrypted_secret" { + secret_name = "test_encrypted_secret" + encrypted_value = "%s" + visibility = "private" + } + `, secretValue, secretValue) checks := map[string]resource.TestCheckFunc{ "before": resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr( - "github_actions_organization_secret.test_secret", "plaintext_value", + "github_actions_organization_secret.plaintext_secret", "plaintext_value", + secretValue, + ), + resource.TestCheckResourceAttr( + "github_actions_organization_secret.encrypted_secret", "encrypted_value", secretValue, ), resource.TestCheckResourceAttrSet( - "github_actions_organization_secret.test_secret", "created_at", + "github_actions_organization_secret.plaintext_secret", "created_at", ), resource.TestCheckResourceAttrSet( - "github_actions_organization_secret.test_secret", "updated_at", + "github_actions_organization_secret.plaintext_secret", "updated_at", ), ), "after": resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr( - "github_actions_organization_secret.test_secret", "plaintext_value", + "github_actions_organization_secret.plaintext_secret", "plaintext_value", + updatedSecretValue, + ), + resource.TestCheckResourceAttr( + "github_actions_organization_secret.encrypted_secret", "encrypted_value", updatedSecretValue, ), resource.TestCheckResourceAttrSet( - "github_actions_organization_secret.test_secret", "created_at", + "github_actions_organization_secret.plaintext_secret", "created_at", ), resource.TestCheckResourceAttrSet( - "github_actions_organization_secret.test_secret", "updated_at", + "github_actions_organization_secret.plaintext_secret", "updated_at", ), ), } @@ -60,7 +74,7 @@ func TestAccGithubActionsOrganizationSecret(t *testing.T) { { Config: strings.Replace(config, secretValue, - updatedSecretValue, 1), + updatedSecretValue, 2), Check: checks["after"], }, }, @@ -81,15 +95,17 @@ func TestAccGithubActionsOrganizationSecret(t *testing.T) { }) t.Run("deletes secrets without error", func(t *testing.T) { - secretValue := "super_secret_value" + config := ` + resource "github_actions_organization_secret" "plaintext_secret" { + secret_name = "test_plaintext_secret" + visibility = "private" + } - config := fmt.Sprintf(` - resource "github_actions_organization_secret" "test_secret" { - secret_name = "test_secret_name" - plaintext_value = "%s" + resource "github_actions_organization_secret" "encrypted_secret" { + secret_name = "test_encrypted_secret" visibility = "private" } - `, secretValue) + ` testCase := func(t *testing.T, mode string) { resource.Test(t, resource.TestCase{ @@ -122,7 +138,7 @@ func TestAccGithubActionsOrganizationSecret(t *testing.T) { config := fmt.Sprintf(` resource "github_actions_organization_secret" "test_secret" { - secret_name = "test_secret_name" + secret_name = "test_plaintext_secret" plaintext_value = "%s" visibility = "private" } diff --git a/github/resource_github_actions_secret.go b/github/resource_github_actions_secret.go index c1ad5d784f..034734d48a 100644 --- a/github/resource_github_actions_secret.go +++ b/github/resource_github_actions_secret.go @@ -30,10 +30,19 @@ func resourceGithubActionsSecret() *schema.Resource { ForceNew: true, ValidateFunc: validateSecretNameFunc, }, + "encrypted_value": { + Type: schema.TypeString, + ForceNew: true, + Optional: true, + Sensitive: true, + ConflictsWith: []string{"plaintext_value"}, + }, "plaintext_value": { - Type: schema.TypeString, - Required: true, - Sensitive: true, + Type: schema.TypeString, + ForceNew: true, + Optional: true, + Sensitive: true, + ConflictsWith: []string{"encrypted_value"}, }, "created_at": { Type: schema.TypeString, @@ -55,22 +64,28 @@ func resourceGithubActionsSecretCreateOrUpdate(d *schema.ResourceData, meta inte repo := d.Get("repository").(string) secretName := d.Get("secret_name").(string) plaintextValue := d.Get("plaintext_value").(string) + var encryptedValue string keyId, publicKey, err := getPublicKeyDetails(owner, repo, meta) if err != nil { return err } - encryptedText, err := encryptPlaintext(plaintextValue, publicKey) - if err != nil { - return err + if encryptedText, ok := d.GetOk("encrypted_value"); ok { + encryptedValue = encryptedText.(string) + } else { + encryptedBytes, err := encryptPlaintext(plaintextValue, publicKey) + if err != nil { + return err + } + encryptedValue = base64.StdEncoding.EncodeToString(encryptedBytes) } // Create an EncryptedSecret and encrypt the plaintext value into it eSecret := &github.EncryptedSecret{ Name: secretName, KeyID: keyId, - EncryptedValue: base64.StdEncoding.EncodeToString(encryptedText), + EncryptedValue: encryptedValue, } _, err = client.Actions.CreateOrUpdateRepoSecret(ctx, owner, repo, eSecret) @@ -105,6 +120,7 @@ func resourceGithubActionsSecretRead(d *schema.ResourceData, meta interface{}) e return err } + d.Set("encrypted_value", d.Get("encrypted_value")) d.Set("plaintext_value", d.Get("plaintext_value")) d.Set("created_at", secret.CreatedAt.String()) diff --git a/github/resource_github_actions_secret_test.go b/github/resource_github_actions_secret_test.go index c072b743a7..8137182ba7 100644 --- a/github/resource_github_actions_secret_test.go +++ b/github/resource_github_actions_secret_test.go @@ -74,36 +74,50 @@ func TestAccGithubActionsSecret(t *testing.T) { name = "tf-acc-test-%s" } - resource "github_actions_secret" "test_secret" { + resource "github_actions_secret" "plaintext_secret" { repository = github_repository.test.name - secret_name = "test_secret_name" + secret_name = "test_plaintext_secret" plaintext_value = "%s" } - `, randomID, secretValue) + + resource "github_actions_secret" "encrypted_secret" { + repository = github_repository.test.name + secret_name = "test_encrypted_secret" + encrypted_value = "%s" + } + `, randomID, secretValue, secretValue) checks := map[string]resource.TestCheckFunc{ "before": resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr( - "github_actions_secret.test_secret", "plaintext_value", + "github_actions_secret.plaintext_secret", "plaintext_value", + secretValue, + ), + resource.TestCheckResourceAttr( + "github_actions_secret.encrypted_secret", "encrypted_value", secretValue, ), resource.TestCheckResourceAttrSet( - "github_actions_secret.test_secret", "created_at", + "github_actions_secret.plaintext_secret", "created_at", ), resource.TestCheckResourceAttrSet( - "github_actions_secret.test_secret", "updated_at", + "github_actions_secret.plaintext_secret", "updated_at", ), ), "after": resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr( - "github_actions_secret.test_secret", "plaintext_value", + "github_actions_secret.plaintext_secret", "plaintext_value", + updatedSecretValue, + ), + resource.TestCheckResourceAttr( + "github_actions_secret.encrypted_secret", "encrypted_value", updatedSecretValue, ), resource.TestCheckResourceAttrSet( - "github_actions_secret.test_secret", "created_at", + "github_actions_secret.plaintext_secret", "created_at", ), resource.TestCheckResourceAttrSet( - "github_actions_secret.test_secret", "updated_at", + "github_actions_secret.plaintext_secret", "updated_at", ), ), } @@ -120,7 +134,7 @@ func TestAccGithubActionsSecret(t *testing.T) { { Config: strings.Replace(config, secretValue, - updatedSecretValue, 1), + updatedSecretValue, 2), Check: checks["after"], }, }, @@ -138,24 +152,24 @@ func TestAccGithubActionsSecret(t *testing.T) { t.Run("with an organization account", func(t *testing.T) { testCase(t, organization) }) - }) t.Run("deletes secrets without error", func(t *testing.T) { - - secretValue := "super_secret_value" - config := fmt.Sprintf(` resource "github_repository" "test" { name = "tf-acc-test-%s" } - resource "github_actions_secret" "test_secret" { - repository = github_repository.test.name - secret_name = "test_secret_name" - plaintext_value = "%s" + resource "github_actions_secret" "plaintext_secret" { + repository = github_repository.test.name + secret_name = "test_plaintext_secret" + } + + resource "github_actions_secret" "encrypted_secret" { + repository = github_repository.test.name + secret_name = "test_encrypted_secret" } - `, randomID, secretValue) + `, randomID) testCase := func(t *testing.T, mode string) { resource.Test(t, resource.TestCase{ @@ -183,5 +197,4 @@ func TestAccGithubActionsSecret(t *testing.T) { }) }) - } diff --git a/website/docs/index.html.markdown b/website/docs/index.html.markdown index f6d42dac5f..01b5d7d374 100644 --- a/website/docs/index.html.markdown +++ b/website/docs/index.html.markdown @@ -104,7 +104,9 @@ The following arguments are supported in the `provider` block: * `app_auth` - (Optional) Configuration block to use GitHub App installation token. When not provided, the provider can only access resources available anonymously. * `id` - (Required) This is the ID of the GitHub App. It can sourced from the `GITHUB_APP_ID` environment variable. * `installation_id` - (Required) This is the ID of the GitHub App installation. It can sourced from the `GITHUB_APP_INSTALLATION_ID` environment variable. - * `pem_file` - (Required) This is the path to the GitHub App private key file. It can sourced from the `GITHUB_APP_PEM_FILE` environment variable. + * `pem_file` - (Required) This is the contents of the GitHub App private key PEM file. It can also be sourced from the `GITHUB_APP_PEM_FILE` environment variable. + +Note: If you have a PEM file on disk, you can pass it in via `pem_file = file("path/to/file.pem")`. For backwards compatibility, if more than one of `owner`, `organization`, `GITHUB_OWNER` and `GITHUB_ORGANIZATION` are set, the first in this diff --git a/website/docs/r/actions_organization_secret.html.markdown b/website/docs/r/actions_organization_secret.html.markdown index 63f0e5e08e..1f62725fdb 100644 --- a/website/docs/r/actions_organization_secret.html.markdown +++ b/website/docs/r/actions_organization_secret.html.markdown @@ -15,7 +15,7 @@ interoperable with [libsodium](https://libsodium.gitbook.io/doc/). Libsodium is For the purposes of security, the contents of the `plaintext_value` field have been marked as `sensitive` to Terraform, but it is important to note that **this does not hide it from state files**. You should treat state as sensitive always. -It is also advised that you do not store plaintext values in your code but rather populate the `plaintext_value` +It is also advised that you do not store plaintext values in your code but rather populate the `encrypted_value` using fields from a resource, data source or variable as, while encrypted in state, these will be easily accessible in your code. See below for an example of this abstraction. @@ -27,6 +27,12 @@ resource "github_actions_organization_secret" "example_secret" { visibility = "private" plaintext_value = var.some_secret_string } + +resource "github_actions_organization_secret" "example_secret" { + secret_name = "example_secret_name" + visibility = "private" + encrypted_value = var.some_encrypted_secret_string +} ``` ```hcl @@ -40,6 +46,13 @@ resource "github_actions_organization_secret" "example_secret" { plaintext_value = var.some_secret_string selected_repository_ids = [data.github_repository.repo.repo_id] } + +resource "github_actions_organization_secret" "example_secret" { + secret_name = "example_secret_name" + visibility = "selected" + encrypted_value = var.some_encrypted_secret_string + selected_repository_ids = [data.github_repository.repo.repo_id] +} ``` ## Argument Reference @@ -47,7 +60,8 @@ resource "github_actions_organization_secret" "example_secret" { The following arguments are supported: * `secret_name` - (Required) Name of the secret -* `plaintext_value` - (Required) Plaintext value of the secret to be encrypted +* `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 * `visiblity` - (Required) Configures the access that repositories have to the organization secret. Must be one of `all`, `private`, `selected`. `selected_repository_ids` is required if set to `selected`. * `selected_repository_ids` - (Optional) An array of repository ids that can access the organization secret. @@ -66,5 +80,4 @@ $ terraform import github_actions_organization_secret.test_secret test_secret_na ``` NOTE: the implementation is limited in that it won't fetch the value of the -`plaintext_value` field when importing. You may need to ignore changes for the -`plaintext_value` as a workaround. +`plaintext_value` or `encrypted_value` fields when importing. You may need to ignore changes for these as a workaround. diff --git a/website/docs/r/actions_secret.html.markdown b/website/docs/r/actions_secret.html.markdown index d4becd7239..dd4adca7b2 100644 --- a/website/docs/r/actions_secret.html.markdown +++ b/website/docs/r/actions_secret.html.markdown @@ -15,7 +15,7 @@ interoperable with [libsodium](https://libsodium.gitbook.io/doc/). Libsodium is For the purposes of security, the contents of the `plaintext_value` field have been marked as `sensitive` to Terraform, but it is important to note that **this does not hide it from state files**. You should treat state as sensitive always. -It is also advised that you do not store plaintext values in your code but rather populate the `plaintext_value` +It is also advised that you do not store plaintext values in your code but rather populate the `encrypted_value` using fields from a resource, data source or variable as, while encrypted in state, these will be easily accessible in your code. See below for an example of this abstraction. @@ -31,6 +31,12 @@ resource "github_actions_secret" "example_secret" { secret_name = "example_secret_name" plaintext_value = var.some_secret_string } + +resource "github_actions_secret" "example_secret" { + repository = "example_repository" + secret_name = "example_secret_name" + encrypted_value = var.some_encrypted_secret_string +} ``` ## Argument Reference @@ -39,7 +45,8 @@ The following arguments are supported: * `repository` - (Required) Name of the repository * `secret_name` - (Required) Name of the secret -* `plaintext_value` - (Required) Plaintext value of the secret to be encrypted +* `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