From 192b5bcd784173762457f5fc16ae09f5154307f5 Mon Sep 17 00:00:00 2001 From: Alexis Couvreur Date: Mon, 4 May 2026 21:19:24 +0200 Subject: [PATCH] fix: import or update autolinks on creation --- ...ce_github_repository_autolink_reference.go | 20 +++++++++ ...thub_repository_autolink_reference_test.go | 41 +++++++++++++++++++ ...epository_autolink_reference.html.markdown | 8 +++- 3 files changed, 68 insertions(+), 1 deletion(-) diff --git a/github/resource_github_repository_autolink_reference.go b/github/resource_github_repository_autolink_reference.go index dbcad6a414..5d158b7d62 100644 --- a/github/resource_github_repository_autolink_reference.go +++ b/github/resource_github_repository_autolink_reference.go @@ -102,6 +102,26 @@ func resourceGithubRepositoryAutolinkReferenceCreate(d *schema.ResourceData, met isAlphanumeric := d.Get("is_alphanumeric").(bool) ctx := context.Background() + // Check if an autolink with this key prefix already exists. + // The GitHub API returns 422 when attempting to create a duplicate, so we + // handle it ourselves: import the existing one if its settings match, or + // delete and recreate it if they differ. + existing, err := getAutolinkByKeyPrefix(ctx, client, owner, repoName, keyPrefix) + if err == nil { + if existing.GetURLTemplate() == targetURLTemplate && existing.GetIsAlphanumeric() == isAlphanumeric { + log.Printf("[INFO] Autolink reference with key prefix %q already exists in %s/%s (id=%d), importing it", + keyPrefix, owner, repoName, existing.GetID()) + d.SetId(strconv.FormatInt(existing.GetID(), 10)) + return resourceGithubRepositoryAutolinkReferenceRead(d, meta) + } + // Settings differ – delete the existing autolink so we can recreate it below. + log.Printf("[INFO] Autolink reference with key prefix %q already exists in %s/%s (id=%d) but with different settings, replacing it", + keyPrefix, owner, repoName, existing.GetID()) + if _, delErr := client.Repositories.DeleteAutolink(ctx, owner, repoName, existing.GetID()); delErr != nil { + return delErr + } + } + opts := &github.AutolinkOptions{ KeyPrefix: &keyPrefix, URLTemplate: &targetURLTemplate, diff --git a/github/resource_github_repository_autolink_reference_test.go b/github/resource_github_repository_autolink_reference_test.go index e97b14abf6..a1ecd5e5f5 100644 --- a/github/resource_github_repository_autolink_reference_test.go +++ b/github/resource_github_repository_autolink_reference_test.go @@ -268,6 +268,47 @@ func TestAccGithubRepositoryAutolinkReference(t *testing.T) { }) }) + t.Run("imports existing autolink reference on create without error", func(t *testing.T) { + randomID := acctest.RandStringFromCharSet(5, acctest.CharSetAlphaNum) + repoName := fmt.Sprintf("%srepo-autolink-%s", testResourcePrefix, randomID) + + // Step 1: create the autolink once. + // Step 2: apply again with an identical resource – the provider should detect + // the existing autolink by key prefix and import it instead of failing. + config := fmt.Sprintf(` + resource "github_repository" "test" { + name = "%s" + description = "Test autolink idempotent create" + } + + resource "github_repository_autolink_reference" "autolink" { + repository = github_repository.test.name + key_prefix = "JIRA-" + target_url_template = "https://example.com/JIRA-" + } + `, repoName) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { skipUnauthenticated(t) }, + ProviderFactories: providerFactories, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.TestCheckResourceAttr( + "github_repository_autolink_reference.autolink", "key_prefix", "JIRA-", + ), + }, + // Applying the same config a second time should succeed (idempotent). + { + Config: config, + Check: resource.TestCheckResourceAttr( + "github_repository_autolink_reference.autolink", "key_prefix", "JIRA-", + ), + }, + }, + }) + }) + t.Run("deletes repository autolink reference without error", func(t *testing.T) { randomID := acctest.RandStringFromCharSet(5, acctest.CharSetAlphaNum) repoName := fmt.Sprintf("%srepo-autolink-%s", testResourcePrefix, randomID) diff --git a/website/docs/r/repository_autolink_reference.html.markdown b/website/docs/r/repository_autolink_reference.html.markdown index 1fbebc5b22..09f25bb057 100644 --- a/website/docs/r/repository_autolink_reference.html.markdown +++ b/website/docs/r/repository_autolink_reference.html.markdown @@ -9,6 +9,12 @@ description: |- This resource allows you to create and manage an autolink reference for a single repository. +When a `github_repository_autolink_reference` resource is created, the provider first checks whether an autolink with the same `key_prefix` already exists in the repository: + +* If one exists **with identical settings**, it is imported into Terraform state rather than creating a duplicate (the GitHub API would otherwise return an error). +* If one exists **with different settings** (`target_url_template` or `is_alphanumeric`), the existing autolink is deleted and recreated with the desired configuration. +* If none exists, the autolink is created normally. + ## Example Usage ```hcl @@ -34,7 +40,7 @@ The following arguments are supported: * `repository` - (Required) The repository of the autolink reference. -* `key_prefix` - (Required) This prefix appended by a number will generate a link any time it is found in an issue, pull request, or commit. +* `key_prefix` - (Required) This prefix appended by a number will generate a link any time it is found in an issue, pull request, or commit. If an autolink reference with this key prefix already exists, the provider imports it when the settings match, or replaces it when the settings differ. * `target_url_template` - (Required) The template of the target URL used for the links; must be a valid URL and contain `` for the reference number