Skip to content

fix: Avoid merge_commit_* drift when merge/squash strategies are disabled#3556

Open
ecerulm wants to merge 2 commits into
integrations:mainfrom
ecerulm:fix/3554-merge-commit-drift
Open

fix: Avoid merge_commit_* drift when merge/squash strategies are disabled#3556
ecerulm wants to merge 2 commits into
integrations:mainfrom
ecerulm:fix/3554-merge-commit-drift

Conversation

@ecerulm

@ecerulm ecerulm commented Jul 20, 2026

Copy link
Copy Markdown

Resolves #3554


Summary

merge_commit_title / merge_commit_message (and the squash_merge_commit_* equivalents) cannot be set on GitHub while the corresponding merge strategy is disabled. If allow_merge_commit = false, GitHub ignores/refuses these fields — the REST API returns:

HTTP 422 Validation Failed
Sorry, you need to allow the merge commit strategy in order to set the default
merge commit message title and message. (no_merge_strategy)

Because of this, a config that sets allow_merge_commit = false and specifies merge_commit_title / merge_commit_message produces a plan that can never converge.

Behaviour: v6.13.0 vs this PR

terraform-provider-github v6.13.0 (current)

To avoid the 422 above, the provider already skips setting these fields when the strategy is disabled — it simply never puts them in the API request:

// only configure merge commit if we are in commit merge strategy
allowMergeCommit, ok := d.Get("allow_merge_commit").(bool)
if ok {
	if allowMergeCommit {                     // <-- only when true
		repository.MergeCommitTitle = new(d.Get("merge_commit_title").(string))
		repository.MergeCommitMessage = new(d.Get("merge_commit_message").(string))
	}
}

The problem: nothing tells Terraform the fields are being ignored. The values still appear in the plan as a pending change, the apply silently does not send them, GitHub keeps its existing values, and the next plan shows the same change again — perpetual, non-convergent drift:

~ merge_commit_message = "PR_BODY" -> "BLANK"
~ merge_commit_title   = "PR_TITLE" -> "MERGE_MESSAGE"
Plan: 0 to add, 1 to change, 0 to destroy.   # ...forever, apply never fixes it

This PR

The fix keeps the "don't send them" behaviour (still correct — GitHub would 422), but makes the provider honest and convergent about it:

  1. The merge_commit_* / squash_merge_commit_* values are ignored from plan onwards while the strategy is disabled. A DiffSuppressFunc suppresses the diff on these fields whenever allow_merge_commit / allow_squash_merge is false, so the plan converges (no more perpetual drift) and re-applies are no-ops.
  2. The ignored setting is surfaced as a warning (emitted on create/apply, when an update runs) instead of silently having no effect:
Warning: merge commit setting ignored

  with github_repository.test,
  on main.tf line 31, in resource "github_repository" "test":
  31:   merge_commit_title   = var.merge_commit_title

"merge_commit_title" is ignored because allow_merge_commit is false; GitHub
does not allow changing it while merge commits are disabled.

When the strategy is enabled again, diffs on these fields work exactly as before.

Why the warning is emitted at apply time, not plan time

Ideally this warning would also appear during terraform plan. Unfortunately the Terraform Plugin SDK v2 (which this provider uses) has no hook that can emit a warning at plan time conditioned on another attribute:

  • CustomizeDiff is the only plan-time hook that can see sibling attributes (e.g. read allow_merge_commit while deciding about merge_commit_title). But its signature returns error only — it can fail the plan, not attach a warning. Turning this into a plan-time signal would mean erroring out and blocking apply, which is stricter than the ignored-setting deserves.
  • ValidateDiagFunc does run at plan/validate time and can return diag.Diagnostics (including warnings), but its signature is func(interface{}, cty.Path) — it only receives the single attribute's own value and path, with no access to sibling attributes. So a validator on merge_commit_title cannot know whether allow_merge_commit is false, which is exactly the condition we need to warn about.

There is therefore no way in SDK v2 to emit a conditional plan-time warning here. The warning is instead emitted from the create/update path, so it surfaces at apply time via diag.Diagnostics.

Consequence: if the only change in a plan is an ignored merge_commit_* value, that plan is a no-op, no update runs, and no warning is shown for that specific run — but the DiffSuppressFunc still suppresses the diff, which is what prevents the drift. The warning reliably appears whenever an update actually runs (e.g. on create, or when allow_merge_commit itself flips to false).

Verification

Verified end-to-end against a real repository, running the same sequence on both providers:

Step v6.13.0 This PR
apply allow_merge_commit=false + changed merge_commit_* applies "OK" silently applies OK, warning shown
gh API: did the values change on GitHub? No (ignored) No (ignored)
terraform plan again drift (never converges) No changes (fixed)

Pull request checklist

  • Schema migrations have been created if needed
  • Tests for the changes have been added (for bug fixes / features)
  • Docs have been reviewed and added / updated if needed (docs already state these fields are "Applicable only if allow_merge_commit / allow_squash_merge is true")

Does this introduce a breaking change?

  • Yes
  • No

@github-actions

Copy link
Copy Markdown

👋 Hi, and thank you for this contribution!

This repo is maintained by GitHub and community members on a best-effort basis. We'll get to this as soon as we can.

You can help us prioritize by joining the discussion on open issues and PRs, sharing details on the changes you need, and reviewing other contributions.


🤖 This is an automated message.

@github-actions github-actions Bot added the Type: Bug Something isn't working as documented label Jul 20, 2026
@ecerulm
ecerulm marked this pull request as draft July 20, 2026 11:04
@ecerulm
ecerulm force-pushed the fix/3554-merge-commit-drift branch from e3c41ab to b4a716f Compare July 20, 2026 11:06
@deiga

deiga commented Jul 20, 2026

Copy link
Copy Markdown
Collaborator

A similar thing is being done in #3310

But basically disallowing setting title and message if the settings are disabled

The proposed approach here is problematic, because we shouldn't be conditionally updating upstream state, unless it's specifically necessary.

In this case I would consider it a user error if they disable merge commits but keep the merge commit title configuration in code

… disabled

GitHub rejects any change to merge_commit_title/message (and the
squash_merge_commit_* equivalents) while the corresponding merge strategy
is disabled, returning HTTP 422 "no_merge_strategy". The provider avoids
that error by not sending these fields when the strategy is off -- but the
plan still shows a diff for them, so a config that both disables a strategy
and specifies different title/message values produces a plan that can never
converge (perpetual drift).

Add a DiffSuppressFunc to merge_commit_title, merge_commit_message,
squash_merge_commit_title and squash_merge_commit_message that suppresses
the diff while the corresponding allow_* strategy is false. Also emit a
warning diagnostic on create/update so users are told their configured
values are ignored in that state rather than silently having no effect.

Resolves integrations#3554
@ecerulm
ecerulm force-pushed the fix/3554-merge-commit-drift branch from b4a716f to 5833935 Compare July 20, 2026 11:57
@ecerulm

ecerulm commented Jul 20, 2026

Copy link
Copy Markdown
Author

In this case I would consider it a user error if they disable merge commits but keep the merge commit title configuration in code

My case is that I want to disable it for now but if I reenable it in two weeks, I want those merge_commit_title / merge_commit_message values.

Right now I'm forced to comment those out, and hope that the state did not save the wrong values, because if for some reason the values were changed in GitHub UI and differ from the state , the drift will be unsolvable without editing the state.

@deiga

deiga commented Jul 20, 2026

Copy link
Copy Markdown
Collaborator

hope that the state did not save the wrong values, because if for some reason the values were changed in GitHub UI and differ from the state , the drift will be unsolvable without editing the state.

@ecerulm that's not how terraform works. Your local configuration is the source of truth. If something is unset locally, it can get upstream values, but upstream can't override local values, at least not without drift.

In this case it's an error that the provider allows setting message and title when the actual setting is disabled, since (as you also point out) in that case upstream controls the values and not your local config.

For temporarily disabling something the correct approach is to comment it out. That will remove the values from state as well. And when adding them back it will send the values upstream again.

@ecerulm

ecerulm commented Jul 20, 2026

Copy link
Copy Markdown
Author

@ecerulm that's not how terraform works. Your local configuration is the source of truth. If something is unset locally, it can get upstream values, but upstream can't override local values, at least not without drift.

This PR attempts to

  • WARN the user on terraform apply about these with messages like "merge_commit_title" is ignored because allow_merge_commit is false; GitHub does not allow changing it while merge commits are disabled.
  • makes the plan to stop reporting drift by
    • updating the state with the values from GitHub
    • Hiding the discrepancy for merge_commit_* at plan time when amc = false, so sidestepping the "upstream can't override local values, at least not without drift" that @deiga mentions with hiding that part of the state when amc=false

For temporarily disabling something the correct approach is to comment it out. That will remove the values from state as well. And when adding them back it will send the values upstream again.

well it doesn't seem to work in terraform 6.13., commenting those out and the drift is still there after applying and planning again.

For me the situation is that now I'm stuck with

!       merge_commit_message                    = "PR_BODY" -> "PR_TITLE"
!       merge_commit_title                      = "PR_TITLE" -> "MERGE_MESSAGE"

even after commenting out these

  # merge_commit_title          = "PR_TITLE"
  # merge_commit_message        = "PR_BODY"
  allow_auto_merge = false

No matter how many times I apply this, because terraform apply won't actually even try to change these settings as this guard prevents it

	// only configure merge commit if we are in commit merge strategy
	allowMergeCommit, ok := d.Get("allow_merge_commit").(bool)
	if ok {
		if allowMergeCommit {
			repository.MergeCommitTitle = new(d.Get("merge_commit_title").(string))
			repository.MergeCommitMessage = new(d.Get("merge_commit_message").(string))
		}
	}

It does not even try to update those values because it knows it will get a 422 from the GitHub API if it try to do that.

I would need to change the terraform configuration to match the the current state, apply that, then comment out. I feel like at least the provider should WARN the user about what is going on, it was not self evident to me that those settings were ignored because amc=false.

In this case it's an error that the provider allows setting message and title when the actual setting is disabled, since (as you also point out) in that case upstream controls the values and not your local config.

maybe so , I don't have any problem on that being an error. But it does not solve the issue of drift.

I would need to change the terraform config to match the state first (and that will error out) , apply, and comment out after, right?

@deiga

deiga commented Jul 20, 2026

Copy link
Copy Markdown
Collaborator

Please attach a debug log of plan and apply to the issue to see what's going here.

Removing from config should reset the state correctly AFAIK and that linked guard should have nothing to do with it

@ecerulm
ecerulm marked this pull request as ready for review July 21, 2026 09:30
@ecerulm

ecerulm commented Jul 21, 2026

Copy link
Copy Markdown
Author

Please attach a debug log of plan and apply to the issue to see what's going here.

Removing from config should reset the state correctly AFAIK and that linked guard should have nothing to do with it

I have this repo with a run.sh script that does the following

  • step1: amc=true, title=PR_TITLE, message=PR_BODY -> plan & apply
  • step2: amc=false -> plan & apply
  • step3: plan again (amc=false, fields still PR_TITLE/PR_BODY) -> EXPECT NO DRIFT
  • step4: comment out merge_commit_title/message -> plan -> EXPECT DRIFT (reproduces [MAINT] Upgrade golangci-lint v2.10 & go to 1.26 #3244), plan confirms the drift still present
  • step5: terraform apply (commented-out config) -> EXPECT OK, no real change in GitHub despite what the plan says
  • step6: terraform plan after apply -> NO DRIFT
  • step7: terraform apply -refresh-only -> reconcile state with GitHub's real values
  • step8: terraform plan after refresh -> NO DRIFT.

So step4 is what I reported before that I still see the drift in the plan after commenting those lines. But it's true that if I apply that "new config" that is really a no-op towards GitHub (due to the guard when amc=false) , then the next plan will not show drift.

The step4 debug log

2026-07-21T13:08:34.491+0200 [INFO]  Terraform version: 1.11.4
2026-07-21T13:08:34.491+0200 [DEBUG] using github.com/hashicorp/go-tfe v1.70.0
2026-07-21T13:08:34.491+0200 [DEBUG] using github.com/hashicorp/hcl/v2 v2.23.0
2026-07-21T13:08:34.491+0200 [DEBUG] using github.com/hashicorp/terraform-svchost v0.1.1
2026-07-21T13:08:34.491+0200 [DEBUG] using github.com/zclconf/go-cty v1.16.0
2026-07-21T13:08:34.491+0200 [INFO]  Go runtime version: go1.23.3
2026-07-21T13:08:34.491+0200 [INFO]  CLI args: []string{"/Users/rubenlaguna/.config/tfenv/versions/1.11.4/terraform", "plan", "-no-color", "-detailed-exitcode", "-var", "owner=ecerulm", "-var", "repo_name=tpg-issue-3554-probe", "-var", "allow_merge_commit=false"}
2026-07-21T13:08:34.491+0200 [DEBUG] Attempting to open CLI config file: /Users/rubenlaguna/.terraformrc
2026-07-21T13:08:34.491+0200 [DEBUG] File doesn't exist, but doesn't need to. Ignoring.
2026-07-21T13:08:34.491+0200 [DEBUG] ignoring non-existing provider search directory terraform.d/plugins
2026-07-21T13:08:34.491+0200 [DEBUG] ignoring non-existing provider search directory /Users/rubenlaguna/.terraform.d/plugins
2026-07-21T13:08:34.491+0200 [DEBUG] ignoring non-existing provider search directory /Users/rubenlaguna/Library/Application Support/io.terraform/plugins
2026-07-21T13:08:34.491+0200 [DEBUG] ignoring non-existing provider search directory /Library/Application Support/io.terraform/plugins
2026-07-21T13:08:34.492+0200 [INFO]  CLI command args: []string{"plan", "-no-color", "-detailed-exitcode", "-var", "owner=ecerulm", "-var", "repo_name=tpg-issue-3554-probe", "-var", "allow_merge_commit=false"}
2026-07-21T13:08:34.512+0200 [DEBUG] checking for provisioner in "."
2026-07-21T13:08:34.512+0200 [DEBUG] checking for provisioner in "/Users/rubenlaguna/.config/tfenv/versions/1.11.4"
2026-07-21T13:08:34.514+0200 [INFO]  backend/local: starting Plan operation
2026-07-21T13:08:34.522+0200 [DEBUG] created provider logger: level=debug
2026-07-21T13:08:34.522+0200 [INFO]  provider: configuring client automatic mTLS
2026-07-21T13:08:34.530+0200 [DEBUG] provider: starting plugin: path=.terraform/providers/registry.terraform.io/integrations/github/6.13.0/darwin_arm64/terraform-provider-github_v6.13.0 args=[".terraform/providers/registry.terraform.io/integrations/github/6.13.0/darwin_arm64/terraform-provider-github_v6.13.0"]
2026-07-21T13:08:34.531+0200 [DEBUG] provider: plugin started: path=.terraform/providers/registry.terraform.io/integrations/github/6.13.0/darwin_arm64/terraform-provider-github_v6.13.0 pid=79172
2026-07-21T13:08:34.531+0200 [DEBUG] provider: waiting for RPC address: plugin=.terraform/providers/registry.terraform.io/integrations/github/6.13.0/darwin_arm64/terraform-provider-github_v6.13.0
2026-07-21T13:08:34.542+0200 [INFO]  provider.terraform-provider-github_v6.13.0: configuring server automatic mTLS: timestamp="2026-07-21T13:08:34.542+0200"
2026-07-21T13:08:34.548+0200 [DEBUG] provider: using plugin: version=5
2026-07-21T13:08:34.548+0200 [DEBUG] provider.terraform-provider-github_v6.13.0: plugin address: address=/var/folders/dv/bn33_2sj1s7bkzwcbvbb78gm0000gp/T/plugin1223541504 network=unix timestamp="2026-07-21T13:08:34.548+0200"
2026-07-21T13:08:34.562+0200 [DEBUG] provider.stdio: received EOF, stopping recv loop: err="rpc error: code = Unavailable desc = error reading from server: EOF"
2026-07-21T13:08:34.563+0200 [INFO]  provider: plugin process exited: plugin=.terraform/providers/registry.terraform.io/integrations/github/6.13.0/darwin_arm64/terraform-provider-github_v6.13.0 id=79172
2026-07-21T13:08:34.568+0200 [DEBUG] provider: plugin exited
2026-07-21T13:08:34.568+0200 [DEBUG] Building and walking validate graph
2026-07-21T13:08:34.569+0200 [DEBUG] ProviderTransformer: "github_repository.test" (*terraform.NodeValidatableResource) needs provider["registry.terraform.io/integrations/github"]
2026-07-21T13:08:34.570+0200 [DEBUG] ReferenceTransformer: "var.owner" references: []
2026-07-21T13:08:34.570+0200 [DEBUG] ReferenceTransformer: "provider[\"registry.terraform.io/integrations/github\"]" references: [var.owner]
2026-07-21T13:08:34.570+0200 [DEBUG] ReferenceTransformer: "github_repository.test" references: [var.allow_merge_commit var.repo_name]
2026-07-21T13:08:34.570+0200 [DEBUG] ReferenceTransformer: "var.repo_name" references: []
2026-07-21T13:08:34.570+0200 [DEBUG] ReferenceTransformer: "var.allow_merge_commit" references: []
2026-07-21T13:08:34.570+0200 [DEBUG] Starting graph walk: walkValidate
2026-07-21T13:08:34.571+0200 [DEBUG] created provider logger: level=debug
2026-07-21T13:08:34.571+0200 [INFO]  provider: configuring client automatic mTLS
2026-07-21T13:08:34.573+0200 [DEBUG] provider: starting plugin: path=.terraform/providers/registry.terraform.io/integrations/github/6.13.0/darwin_arm64/terraform-provider-github_v6.13.0 args=[".terraform/providers/registry.terraform.io/integrations/github/6.13.0/darwin_arm64/terraform-provider-github_v6.13.0"]
2026-07-21T13:08:34.574+0200 [DEBUG] provider: plugin started: path=.terraform/providers/registry.terraform.io/integrations/github/6.13.0/darwin_arm64/terraform-provider-github_v6.13.0 pid=79173
2026-07-21T13:08:34.574+0200 [DEBUG] provider: waiting for RPC address: plugin=.terraform/providers/registry.terraform.io/integrations/github/6.13.0/darwin_arm64/terraform-provider-github_v6.13.0
2026-07-21T13:08:34.580+0200 [INFO]  provider.terraform-provider-github_v6.13.0: configuring server automatic mTLS: timestamp="2026-07-21T13:08:34.580+0200"
2026-07-21T13:08:34.585+0200 [DEBUG] provider.terraform-provider-github_v6.13.0: plugin address: address=/var/folders/dv/bn33_2sj1s7bkzwcbvbb78gm0000gp/T/plugin2674728685 network=unix timestamp="2026-07-21T13:08:34.584+0200"
2026-07-21T13:08:34.585+0200 [DEBUG] provider: using plugin: version=5
2026-07-21T13:08:34.593+0200 [DEBUG] provider.stdio: received EOF, stopping recv loop: err="rpc error: code = Unavailable desc = error reading from server: EOF"
2026-07-21T13:08:34.594+0200 [INFO]  provider: plugin process exited: plugin=.terraform/providers/registry.terraform.io/integrations/github/6.13.0/darwin_arm64/terraform-provider-github_v6.13.0 id=79173
2026-07-21T13:08:34.598+0200 [DEBUG] provider: plugin exited
2026-07-21T13:08:34.598+0200 [INFO]  backend/local: plan calling Plan
2026-07-21T13:08:34.598+0200 [DEBUG] Building and walking plan graph for NormalMode
2026-07-21T13:08:34.599+0200 [DEBUG] ProviderTransformer: "github_repository.test (expand)" (*terraform.nodeExpandPlannableResource) needs provider["registry.terraform.io/integrations/github"]
2026-07-21T13:08:34.599+0200 [DEBUG] ReferenceTransformer: "provider[\"registry.terraform.io/integrations/github\"]" references: [var.owner]
2026-07-21T13:08:34.599+0200 [DEBUG] ReferenceTransformer: "github_repository.test (expand)" references: [var.repo_name var.allow_merge_commit]
2026-07-21T13:08:34.599+0200 [DEBUG] ReferenceTransformer: "var.owner" references: []
2026-07-21T13:08:34.599+0200 [DEBUG] ReferenceTransformer: "var.repo_name" references: []
2026-07-21T13:08:34.599+0200 [DEBUG] ReferenceTransformer: "var.allow_merge_commit" references: []
2026-07-21T13:08:34.599+0200 [DEBUG] Starting graph walk: walkPlan
2026-07-21T13:08:34.599+0200 [DEBUG] created provider logger: level=debug
2026-07-21T13:08:34.599+0200 [INFO]  provider: configuring client automatic mTLS
2026-07-21T13:08:34.601+0200 [DEBUG] provider: starting plugin: path=.terraform/providers/registry.terraform.io/integrations/github/6.13.0/darwin_arm64/terraform-provider-github_v6.13.0 args=[".terraform/providers/registry.terraform.io/integrations/github/6.13.0/darwin_arm64/terraform-provider-github_v6.13.0"]
2026-07-21T13:08:34.602+0200 [DEBUG] provider: plugin started: path=.terraform/providers/registry.terraform.io/integrations/github/6.13.0/darwin_arm64/terraform-provider-github_v6.13.0 pid=79174
2026-07-21T13:08:34.602+0200 [DEBUG] provider: waiting for RPC address: plugin=.terraform/providers/registry.terraform.io/integrations/github/6.13.0/darwin_arm64/terraform-provider-github_v6.13.0
2026-07-21T13:08:34.608+0200 [INFO]  provider.terraform-provider-github_v6.13.0: configuring server automatic mTLS: timestamp="2026-07-21T13:08:34.608+0200"
2026-07-21T13:08:34.613+0200 [DEBUG] provider.terraform-provider-github_v6.13.0: plugin address: address=/var/folders/dv/bn33_2sj1s7bkzwcbvbb78gm0000gp/T/plugin2685348074 network=unix timestamp="2026-07-21T13:08:34.613+0200"
2026-07-21T13:08:34.613+0200 [DEBUG] provider: using plugin: version=5
2026-07-21T13:08:34.617+0200 [WARN]  ValidateProviderConfig from "provider[\"registry.terraform.io/integrations/github\"]" changed the config value, but that value is unused
2026-07-21T13:08:34.617+0200 [DEBUG] provider.terraform-provider-github_v6.13.0: Configuring provider.: commit=20728bb30c112287ac3e8243cdb0307a45c6a0a0 name=terraform-provider-github tf_req_id=e83af1a1-71f7-ff6d-108f-21ca3054f002 tf_rpc=Configure @module=github tf_provider_addr=registry.terraform.io/integrations/github url=https://github.com/integrations/terraform-provider-github version=6.13.0 @caller=github.com/integrations/terraform-provider-github/v6/github/provider.go:340 timestamp="2026-07-21T13:08:34.617+0200"
2026-07-21T13:08:34.617+0200 [DEBUG] provider.terraform-provider-github_v6.13.0: Using base URL from provider configuration.: @caller=github.com/integrations/terraform-provider-github/v6/github/provider.go:364 @module=github tf_req_id=e83af1a1-71f7-ff6d-108f-21ca3054f002 tf_rpc=Configure base_url=https://api.github.com/ tf_provider_addr=registry.terraform.io/integrations/github timestamp="2026-07-21T13:08:34.617+0200"
2026-07-21T13:08:34.617+0200 [DEBUG] provider.terraform-provider-github_v6.13.0: Using owner attribute as owner.: @caller=github.com/integrations/terraform-provider-github/v6/github/provider.go:392 @module=github tf_provider_addr=registry.terraform.io/integrations/github tf_req_id=e83af1a1-71f7-ff6d-108f-21ca3054f002 tf_rpc=Configure owner=ecerulm timestamp="2026-07-21T13:08:34.617+0200"
2026-07-21T13:08:34.617+0200 [DEBUG] provider.terraform-provider-github_v6.13.0: Using token from provider configuration.: tf_provider_addr=registry.terraform.io/integrations/github tf_req_id=e83af1a1-71f7-ff6d-108f-21ca3054f002 tf_rpc=Configure @caller=github.com/integrations/terraform-provider-github/v6/github/provider.go:412 @module=github timestamp="2026-07-21T13:08:34.617+0200"
2026-07-21T13:08:34.617+0200 [DEBUG] provider.terraform-provider-github_v6.13.0: Using write delay from provider configuration.: @caller=github.com/integrations/terraform-provider-github/v6/github/provider.go:451 @module=github tf_req_id=e83af1a1-71f7-ff6d-108f-21ca3054f002 write_delay_ms=1000 tf_provider_addr=registry.terraform.io/integrations/github tf_rpc=Configure timestamp="2026-07-21T13:08:34.617+0200"
2026-07-21T13:08:34.617+0200 [DEBUG] provider.terraform-provider-github_v6.13.0: Using retry delay from provider configuration.: @module=github tf_req_id=e83af1a1-71f7-ff6d-108f-21ca3054f002 @caller=github.com/integrations/terraform-provider-github/v6/github/provider.go:458 tf_provider_addr=registry.terraform.io/integrations/github tf_rpc=Configure retry_delay_ms=1000 timestamp="2026-07-21T13:08:34.617+0200"
2026-07-21T13:08:34.617+0200 [DEBUG] provider.terraform-provider-github_v6.13.0: Using max retries from provider configuration.: max_retries=3 tf_rpc=Configure tf_provider_addr=registry.terraform.io/integrations/github tf_req_id=e83af1a1-71f7-ff6d-108f-21ca3054f002 @caller=github.com/integrations/terraform-provider-github/v6/github/provider.go:485 @module=github timestamp="2026-07-21T13:08:34.617+0200"
2026-07-21T13:08:34.617+0200 [DEBUG] provider.terraform-provider-github_v6.13.0: Using max per page from provider configuration.: @module=github tf_provider_addr=registry.terraform.io/integrations/github tf_rpc=Configure @caller=github.com/integrations/terraform-provider-github/v6/github/provider.go:492 max_per_page=100 tf_req_id=e83af1a1-71f7-ff6d-108f-21ca3054f002 timestamp="2026-07-21T13:08:34.617+0200"
2026-07-21T13:08:34.618+0200 [DEBUG] provider.terraform-provider-github_v6.13.0: Sending HTTP Request: Accept-Encoding=gzip X-Github-Api-Version=2022-11-28 tf_http_req_uri=/orgs/ecerulm tf_http_req_version=HTTP/1.1 tf_req_id=e83af1a1-71f7-ff6d-108f-21ca3054f002 @caller=github.com/hashicorp/terraform-plugin-sdk/v2@v2.40.1/helper/logging/logging_http_transport.go:162 @module=github tf_http_op_type=request tf_http_trans_id=a5ae83af-65d3-8d0c-6ef6-1412ccbf4688 Accept="application/vnd.github.surtur-preview+json,application/vnd.github.stone-crop-preview+json" User-Agent=go-github/v88.0.0 tf_http_req_body="" tf_provider_addr=registry.terraform.io/integrations/github tf_rpc=Configure Host=api.github.com tf_http_req_method=GET timestamp="2026-07-21T13:08:34.618+0200"
2026-07-21T13:08:34.864+0200 [DEBUG] provider.terraform-provider-github_v6.13.0: Received HTTP Response: X-Github-Api-Version-Selected=2022-11-28 tf_http_res_version=HTTP/2.0 tf_http_res_status_reason="404 Not Found" Access-Control-Allow-Origin="*" Access-Control-Expose-Headers="ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset, Warning" Content-Security-Policy="default-src 'none'" Strict-Transport-Security="max-age=31536000; includeSubdomains; preload" Vary="Accept-Encoding, Accept, X-Requested-With" X-Github-Media-Type="github.v3; param=surtur-preview.stone-crop-preview; format=json" X-Ratelimit-Reset=1784635520 X-Ratelimit-Resource=core Referrer-Policy="origin-when-cross-origin, strict-origin-when-cross-origin" X-Content-Type-Options=nosniff X-Oauth-Scopes="gist, read:org, repo, workflow" X-Ratelimit-Limit=5000 X-Ratelimit-Remaining=4972 @caller=github.com/hashicorp/terraform-plugin-sdk/v2@v2.40.1/helper/logging/logging_http_transport.go:162 Content-Type="application/json; charset=utf-8" X-Xss-Protection=0 tf_provider_addr=registry.terraform.io/integrations/github tf_req_id=e83af1a1-71f7-ff6d-108f-21ca3054f002 Date="Tue, 21 Jul 2026 11:08:34 GMT" X-Oauth-Client-Id=178c6fc778ccc68e1d6a @module=github X-Accepted-Oauth-Scopes="admin:org, read:org, repo, user, write:org" X-Ratelimit-Used=28 tf_http_trans_id=a5ae83af-65d3-8d0c-6ef6-1412ccbf4688 tf_rpc=Configure X-Frame-Options=deny X-Github-Request-Id=E5B0:FD030:3DBD41:455F83:6A5F5332 tf_http_op_type=response Server=github.com tf_http_res_body="{\"message\":\"Not Found\",\"documentation_url\":\"https://docs.github.com/rest/orgs/orgs#get-an-organization\",\"status\":\"404\"}" tf_http_res_status_code=404 timestamp="2026-07-21T13:08:34.857+0200"
2026-07-21T13:08:34.865+0200 [DEBUG] ReferenceTransformer: "github_repository.test" references: []
2026-07-21T13:08:34.879+0200 [DEBUG] provider.terraform-provider-github_v6.13.0: Sending HTTP Request: @module=github Host=api.github.com tf_http_trans_id=39be920d-08a2-d284-c8a1-054443ef1849 tf_provider_addr=registry.terraform.io/integrations/github tf_req_id=a9a553f0-af0a-09ea-176e-e7f7e1c90d7f tf_http_req_method=GET tf_http_req_version=HTTP/1.1 Accept-Encoding=gzip tf_http_op_type=request tf_http_req_body="" tf_resource_type=github_repository tf_rpc=ReadResource @caller=github.com/hashicorp/terraform-plugin-sdk/v2@v2.40.1/helper/logging/logging_http_transport.go:162 Accept="application/vnd.github.scarlet-witch-preview+json, application/vnd.github.mercy-preview+json, application/vnd.github.baptiste-preview+json, application/vnd.github.nebula-preview+json,application/vnd.github.stone-crop-preview+json" User-Agent=go-github/v88.0.0 X-Github-Api-Version=2022-11-28 tf_http_req_uri=/repos/ecerulm/tpg-issue-3554-probe timestamp="2026-07-21T13:08:34.879+0200"
2026-07-21T13:08:35.168+0200 [DEBUG] provider.terraform-provider-github_v6.13.0: Received HTTP Response: Content-Security-Policy="default-src 'none'" Strict-Transport-Security="max-age=31536000; includeSubdomains; preload" tf_resource_type=github_repository Vary="Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With" X-Github-Api-Version-Selected=2022-11-28 tf_http_res_version=HTTP/2.0 tf_req_id=a9a553f0-af0a-09ea-176e-e7f7e1c90d7f tf_http_res_status_code=304 tf_http_trans_id=39be920d-08a2-d284-c8a1-054443ef1849 @module=github Date="Tue, 21 Jul 2026 11:08:35 GMT" Last-Modified="Tue, 21 Jul 2026 08:39:42 GMT" X-Content-Type-Options=nosniff Access-Control-Allow-Origin="*" Cache-Control="private, max-age=60, s-maxage=60" X-Ratelimit-Reset=1784635520 tf_rpc=ReadResource X-Frame-Options=deny X-Xss-Protection=0 tf_http_res_body="" Server=github.com X-Github-Request-Id=E5B0:FD030:3DBD5C:455FA8:6A5F5332 X-Ratelimit-Limit=5000 X-Ratelimit-Remaining=4972 X-Ratelimit-Used=28 @caller=github.com/hashicorp/terraform-plugin-sdk/v2@v2.40.1/helper/logging/logging_http_transport.go:162 Access-Control-Expose-Headers="ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset, Warning" Etag="\"65322b5f94533e8053d3bdb53fb4c485841e74957307a000c6b66b432bfb23c0\"" Referrer-Policy="origin-when-cross-origin, strict-origin-when-cross-origin" X-Ratelimit-Resource=core tf_http_op_type=response tf_http_res_status_reason="304 Not Modified" tf_provider_addr=registry.terraform.io/integrations/github timestamp="2026-07-21T13:08:35.167+0200"
2026-07-21T13:08:35.181+0200 [WARN]  Provider "registry.terraform.io/integrations/github" produced an invalid plan for github_repository.test, but we are tolerating it because it is using the legacy plugin SDK.
    The following problems may be the cause of any confusing errors from downstream operations:
      - .archived: planned value cty.False for a non-computed attribute
      - .delete_branch_on_merge: planned value cty.False for a non-computed attribute
      - .is_template: planned value cty.False for a non-computed attribute
      - .description: planned value cty.StringVal("") for a non-computed attribute
      - .squash_merge_commit_message: planned value cty.StringVal("COMMIT_MESSAGES") for a non-computed attribute
      - .allow_auto_merge: planned value cty.False for a non-computed attribute
      - .homepage_url: planned value cty.StringVal("") for a non-computed attribute
      - .merge_commit_title: planned value cty.StringVal("MERGE_MESSAGE") for a non-computed attribute
      - .allow_rebase_merge: planned value cty.True for a non-computed attribute
      - .allow_squash_merge: planned value cty.True for a non-computed attribute
      - .allow_update_branch: planned value cty.False for a non-computed attribute
      - .has_issues: planned value cty.False for a non-computed attribute
      - .has_projects: planned value cty.False for a non-computed attribute
      - .has_wiki: planned value cty.False for a non-computed attribute
      - .squash_merge_commit_title: planned value cty.StringVal("COMMIT_OR_PR_TITLE") for a non-computed attribute
      - .has_downloads: planned value cty.False for a non-computed attribute
      - .merge_commit_message: planned value cty.StringVal("PR_TITLE") for a non-computed attribute
      - .has_discussions: planned value cty.False for a non-computed attribute
      - .ignore_vulnerability_alerts_during_read: planned value cty.False for a non-computed attribute
2026-07-21T13:08:35.185+0200 [DEBUG] provider.stdio: received EOF, stopping recv loop: err="rpc error: code = Unavailable desc = error reading from server: EOF"
2026-07-21T13:08:35.190+0200 [INFO]  provider: plugin process exited: plugin=.terraform/providers/registry.terraform.io/integrations/github/6.13.0/darwin_arm64/terraform-provider-github_v6.13.0 id=79174
2026-07-21T13:08:35.194+0200 [DEBUG] provider: plugin exited
2026-07-21T13:08:35.196+0200 [DEBUG] building apply graph to check for errors
2026-07-21T13:08:35.197+0200 [DEBUG] ProviderTransformer: "github_repository.test (expand)" (*terraform.nodeExpandApplyableResource) needs provider["registry.terraform.io/integrations/github"]
2026-07-21T13:08:35.197+0200 [DEBUG] ProviderTransformer: "github_repository.test" (*terraform.NodeApplyableResourceInstance) needs provider["registry.terraform.io/integrations/github"]
2026-07-21T13:08:35.197+0200 [DEBUG] ReferenceTransformer: "github_repository.test (expand)" references: [var.repo_name var.allow_merge_commit]
2026-07-21T13:08:35.197+0200 [DEBUG] ReferenceTransformer: "var.owner" references: []
2026-07-21T13:08:35.197+0200 [DEBUG] ReferenceTransformer: "var.repo_name" references: []
2026-07-21T13:08:35.197+0200 [DEBUG] ReferenceTransformer: "var.allow_merge_commit" references: []
2026-07-21T13:08:35.197+0200 [DEBUG] ReferenceTransformer: "github_repository.test" references: [var.allow_merge_commit var.repo_name]
2026-07-21T13:08:35.197+0200 [DEBUG] ReferenceTransformer: "provider[\"registry.terraform.io/integrations/github\"]" references: [var.owner]
2026-07-21T13:08:35.198+0200 [INFO]  backend/local: plan operation completed

@ecerulm

ecerulm commented Jul 21, 2026

Copy link
Copy Markdown
Author

But in any case from the point of view of usability (for the next guy that faces this) I think this PR approach is better.

  • It WARNS the user about amc=false being "incompatible" with setting mct and mcm
  • It hides mct amd mcm from the planning if amc=false, so you don't get drift when planning, avoiding the need to comment, plan (still see confusing drift), apply, plan again to see the drift gone.

But I understand that if you want to handle this in a different way, I don't know when the #3310 is planned to be merged, but I guess that at least failing on the planning phase if amc=false and mct/mcm present would be an improvement (#3558 although this will still show drift after resolving the issue by removing/commenting the mct/mcm like in step4 above)

@ecerulm

ecerulm commented Jul 21, 2026

Copy link
Copy Markdown
Author

And to add some more context, in production I'm not using github_repository directly but via a terraform module and I'm using Atlantis. And in there I can't get rid of the drift.

First the module will set the merge_commit_title/ merge_commit_message to it's default values if I don't pass them. So it's difficult to do the "comment out" since I can comment when I call the module but I can't comment in the github_repository in the module itself.

Also I don't know if Atlantis has any difference in the handling of the state.

@deiga

deiga commented Jul 21, 2026

Copy link
Copy Markdown
Collaborator

I don't agree with your proposal.
My PR will make it a plan-time error to have amc=false and title/message configured.
That is IMO a cleaner approach than conditionally hiding things from diffs.

Those conditionals are hard to test for all edge-cases and hard to maintain.
Having clear errors for configs that shouldn't work will be simpler for all parties.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Type: Bug Something isn't working as documented

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG]: github_repository reports drift on merge_commit_message and merge_commit_title if allow_merge_commit is false

2 participants