diff --git a/github/data_source_github_repository_file_test.go b/github/data_source_github_repository_file_test.go index c4b3005a5..659791cf5 100644 --- a/github/data_source_github_repository_file_test.go +++ b/github/data_source_github_repository_file_test.go @@ -294,6 +294,8 @@ func TestDataSourceGithubRepositoryFileRead(t *testing.T) { "commit_message": {Type: schema.TypeString}, "content": {Type: schema.TypeString}, "id": {Type: schema.TypeString}, + "sha": {Type: schema.TypeString}, + "ref": {Type: schema.TypeString}, } schema := schema.TestResourceDataRaw(t, testSchema, map[string]interface{}{ @@ -366,6 +368,8 @@ func TestDataSourceGithubRepositoryFileRead(t *testing.T) { "commit_message": {Type: schema.TypeString}, "content": {Type: schema.TypeString}, "id": {Type: schema.TypeString}, + "sha": {Type: schema.TypeString}, + "ref": {Type: schema.TypeString}, } schema := schema.TestResourceDataRaw(t, testSchema, map[string]interface{}{ @@ -408,8 +412,8 @@ func TestDataSourceGithubRepositoryFileRead(t *testing.T) { `, randomID) check := resource.ComposeTestCheckFunc( - resource.TestCheckNoResourceAttr( - "data.github_repository_file.test", "id", + resource.TestCheckResourceAttr( + "data.github_repository_file.test", "id", "", ), ) diff --git a/github/resource_github_actions_environment_variable.go b/github/resource_github_actions_environment_variable.go index a4b8132fd..866f611cb 100644 --- a/github/resource_github_actions_environment_variable.go +++ b/github/resource_github_actions_environment_variable.go @@ -12,9 +12,9 @@ import ( func resourceGithubActionsEnvironmentVariable() *schema.Resource { return &schema.Resource{ - Create: resourceGithubActionsEnvironmentVariableCreate, + Create: resourceGithubActionsEnvironmentVariableCreateOrUpdate, Read: resourceGithubActionsEnvironmentVariableRead, - Update: resourceGithubActionsEnvironmentVariableUpdate, + Update: resourceGithubActionsEnvironmentVariableCreateOrUpdate, Delete: resourceGithubActionsEnvironmentVariableDelete, Importer: &schema.ResourceImporter{ StateContext: schema.ImportStatePassthroughContext, @@ -58,7 +58,7 @@ func resourceGithubActionsEnvironmentVariable() *schema.Resource { } } -func resourceGithubActionsEnvironmentVariableCreate(d *schema.ResourceData, meta interface{}) error { +func resourceGithubActionsEnvironmentVariableCreateOrUpdate(d *schema.ResourceData, meta interface{}) error { client := meta.(*Owner).v3client owner := meta.(*Owner).name ctx := context.Background() @@ -73,33 +73,22 @@ func resourceGithubActionsEnvironmentVariableCreate(d *schema.ResourceData, meta Value: d.Get("value").(string), } + // Try to create the variable first _, err := client.Actions.CreateEnvVariable(ctx, owner, repoName, escapedEnvName, variable) if err != nil { - return err - } - - d.SetId(buildThreePartID(repoName, envName, name)) - return resourceGithubActionsEnvironmentVariableRead(d, meta) -} - -func resourceGithubActionsEnvironmentVariableUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*Owner).v3client - owner := meta.(*Owner).name - ctx := context.Background() - - repoName := d.Get("repository").(string) - envName := d.Get("environment").(string) - escapedEnvName := url.PathEscape(envName) - name := d.Get("variable_name").(string) - - variable := &github.ActionsVariable{ - Name: name, - Value: d.Get("value").(string), - } - - _, err := client.Actions.UpdateEnvVariable(ctx, owner, repoName, escapedEnvName, variable) - if err != nil { - return err + if ghErr, ok := err.(*github.ErrorResponse); ok { + if ghErr.Response.StatusCode == http.StatusConflict { + // Variable already exists, try to update instead + _, err = client.Actions.UpdateEnvVariable(ctx, owner, repoName, escapedEnvName, variable) + if err != nil { + return err + } + } else { + return err + } + } else { + return err + } } d.SetId(buildThreePartID(repoName, envName, name)) diff --git a/github/resource_github_actions_environment_variable_test.go b/github/resource_github_actions_environment_variable_test.go index cbab1e20d..9b8446e1c 100644 --- a/github/resource_github_actions_environment_variable_test.go +++ b/github/resource_github_actions_environment_variable_test.go @@ -1,13 +1,16 @@ package github import ( + "context" "fmt" + "net/url" "strings" "testing" + "github.com/google/go-github/v66/github" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" ) func TestAccGithubActionsEnvironmentVariable(t *testing.T) { @@ -195,3 +198,86 @@ func TestAccGithubActionsEnvironmentVariable(t *testing.T) { }) }) } + +func TestAccGithubActionsEnvironmentVariable_alreadyExists(t *testing.T) { + randomID := acctest.RandStringFromCharSet(5, acctest.CharSetAlphaNum) + repoName := fmt.Sprintf("tf-acc-test-%s", randomID) + envName := "environment / test" + varName := "test_variable" + value := "my_variable_value" + + config := fmt.Sprintf(` + resource "github_repository" "test" { + name = "%s" + vulnerability_alerts = true + } + + resource "github_repository_environment" "test" { + repository = github_repository.test.name + environment = "%s" + } + + resource "github_actions_environment_variable" "variable" { + repository = github_repository.test.name + environment = github_repository_environment.test.environment + variable_name = "%s" + value = "%s" + } + `, repoName, envName, varName, value) + + testCase := func(t *testing.T, mode string) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { + skipUnlessMode(t, mode) + }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + // First, create the repository and environment. + Config: fmt.Sprintf(` + resource "github_repository" "test" { + name = "%s" + vulnerability_alerts = true + } + + resource "github_repository_environment" "test" { + repository = github_repository.test.name + environment = "%s" + } + `, repoName, envName), + Check: resource.ComposeTestCheckFunc( + func(s *terraform.State) error { + // Now that the repo and env are created, create the variable using the API. + client := testAccProvider.Meta().(*Owner).v3client + owner := testAccProvider.Meta().(*Owner).name + ctx := context.Background() + escapedEnvName := url.PathEscape(envName) + + variable := &github.ActionsVariable{ + Name: varName, + Value: value, + } + _, err := client.Actions.CreateEnvVariable(ctx, owner, repoName, escapedEnvName, variable) + return err + }, + ), + }, + { + // Now, run the full config. Terraform should detect the existing variable and "adopt" it. + Config: config, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("github_actions_environment_variable.variable", "value", value), + ), + }, + }, + }) + } + + 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) + }) +}