diff --git a/github/resource_github_repository_custom_property.go b/github/resource_github_repository_custom_property.go index 6de2a7dce..fdeb2e4e4 100644 --- a/github/resource_github_repository_custom_property.go +++ b/github/resource_github_repository_custom_property.go @@ -22,7 +22,7 @@ func resourceGithubRepositoryCustomProperty() *schema.Resource { Read: resourceGithubRepositoryCustomPropertyRead, Delete: resourceGithubRepositoryCustomPropertyDelete, Importer: &schema.ResourceImporter{ - StateContext: schema.ImportStatePassthroughContext, + StateContext: resourceGithubRepositoryCustomPropertyImport, }, Schema: map[string]*schema.Schema{ @@ -140,6 +140,34 @@ func resourceGithubRepositoryCustomPropertyDelete(d *schema.ResourceData, meta i return nil } +func resourceGithubRepositoryCustomPropertyImport(ctx context.Context, d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { + + client := meta.(*Owner).v3client + + err := resourceGithubRepositoryCustomPropertyRead(d, meta) + if err != nil { + return nil, err + } + + owner, _, propertyName, err := parseThreePartID(d.Id(), "owner", "repoName", "propertyName") + if err != nil { + return nil, err + } + + // Type is stored in state but not available on the endpoint used to read and not refreshed. + // This causes imported properties to be given null as their property type, which then is + // overridden in resource config, forcing replacement. + // Instead, import the type of the property from the organization's property schema. + wantedCustomPropertySchema, _, err := client.Organizations.GetCustomProperty(ctx, owner, propertyName) + if err != nil { + return nil, err + } + + d.Set("property_type", wantedCustomPropertySchema.ValueType) + + return []*schema.ResourceData{d}, nil +} + func readRepositoryCustomPropertyValue(ctx context.Context, client *github.Client, owner, repoName, propertyName string) ([]string, error) { allCustomProperties, _, err := client.Repositories.GetAllCustomPropertyValues(ctx, owner, repoName) if err != nil { diff --git a/github/resource_github_repository_custom_property_test.go b/github/resource_github_repository_custom_property_test.go index eba159011..141f9703b 100644 --- a/github/resource_github_repository_custom_property_test.go +++ b/github/resource_github_repository_custom_property_test.go @@ -13,7 +13,7 @@ func TestAccGithubRepositoryCustomProperty(t *testing.T) { t.Skip("You need an org with custom properties already setup as described in the variables below") // TODO: at the time of writing org_custom_properties are not supported by this terraform provider, so cant be setup in the test itself for now singleSelectPropertyName := "single-select" // Needs to be a of type single_select, and have "option1" as an option multiSelectPropertyName := "multi-select" // Needs to be a of type multi_select, and have "option1" and "option2" as an options - trueFlasePropertyName := "true-false" // Needs to be a of type true_false + trueFalsePropertyName := "true-false" // Needs to be a of type true_false stringPropertyName := "string" // Needs to be a of type string randomID := acctest.RandStringFromCharSet(5, acctest.CharSetAlphaNum) @@ -48,6 +48,12 @@ func TestAccGithubRepositoryCustomProperty(t *testing.T) { Config: config, Check: check, }, + { + ResourceName: "github_repository_custom_property.test", + ImportStateId: fmt.Sprintf(`%s:tf-acc-test-%s:%s`, testOrganization, randomID, singleSelectPropertyName), + ImportState: true, + ImportStateVerify: true, + }, }, }) } @@ -96,6 +102,12 @@ func TestAccGithubRepositoryCustomProperty(t *testing.T) { Config: config, Check: checkWithOwner, }, + { + ResourceName: "github_repository_custom_property.test", + ImportStateId: fmt.Sprintf(`%s:tf-acc-test-%s:%s`, testOrganization, randomID, multiSelectPropertyName), + ImportState: true, + ImportStateVerify: true, + }, }, }) } @@ -126,10 +138,10 @@ func TestAccGithubRepositoryCustomProperty(t *testing.T) { property_type = "true_false" property_value = ["true"] } - `, randomID, trueFlasePropertyName) + `, randomID, trueFalsePropertyName) checkWithOwner := resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr("github_repository_custom_property.test", "property_name", trueFlasePropertyName), + resource.TestCheckResourceAttr("github_repository_custom_property.test", "property_name", trueFalsePropertyName), resource.TestCheckResourceAttr("github_repository_custom_property.test", "property_value.#", "1"), resource.TestCheckResourceAttr("github_repository_custom_property.test", "property_value.0", "true"), ) @@ -143,6 +155,12 @@ func TestAccGithubRepositoryCustomProperty(t *testing.T) { Config: config, Check: checkWithOwner, }, + { + ResourceName: "github_repository_custom_property.test", + ImportStateId: fmt.Sprintf(`%s:tf-acc-test-%s:%s`, testOrganization, randomID, trueFalsePropertyName), + ImportState: true, + ImportStateVerify: true, + }, }, }) } @@ -190,6 +208,12 @@ func TestAccGithubRepositoryCustomProperty(t *testing.T) { Config: config, Check: checkWithOwner, }, + { + ResourceName: "github_repository_custom_property.test", + ImportStateId: fmt.Sprintf(`%s:tf-acc-test-%s:%s`, testOrganization, randomID, stringPropertyName), + ImportState: true, + ImportStateVerify: true, + }, }, }) }