Skip to content

fix: prevent inconsistent final plan for prevent_self_review in github_repository_environment - #3583

Open
kishaningithub wants to merge 5 commits into
integrations:mainfrom
kishaningithub:fix-prevent-self-review-no-reviewers
Open

fix: prevent inconsistent final plan for prevent_self_review in github_repository_environment#3583
kishaningithub wants to merge 5 commits into
integrations:mainfrom
kishaningithub:fix-prevent-self-review-no-reviewers

Conversation

@kishaningithub

@kishaningithub kishaningithub commented Jul 28, 2026

Copy link
Copy Markdown

Fixes an issue where Terraform reports "Provider produced inconsistent final plan" for the prevent_self_review attribute on github_repository_environment resources that have no reviewers configured.

Resolves a missed edge case in #1967

Problem

When an environment has no reviewers, the GitHub API does not return a required_reviewers protection rule. The read function only set prevent_self_review inside the case "required_reviewers" branch, so the attribute was never written to state—leaving it as null. Terraform's plan expected false (the schema default), causing the following mismatch:

Error: Provider produced inconsistent final plan .prevent_self_review: was cty.False, but now null.

Root Cause

  1. prevent_self_review was only set in state when a required_reviewers protection rule existed in the API response.
  2. pr.PreventSelfReview (a *bool) was passed directly to d.Set() without nil-checking, which could also store null in state.

Fix

  • Set prevent_self_review to false before iterating protection rules, ensuring it always has a value in state.
  • Safely dereference pr.PreventSelfReview with a nil guard, defaulting to false.

Testing

Environments without reviewers (the failing case) are already exercised by the create_with_id_separator_in_name and update_to_add_reviewers acceptance tests which create environments with no initial reviewers.

Pull request checklist

  • Schema migrations have been created if needed (example)
  • Tests for the changes have been added (for bug fixes / features)
  • Docs have been reviewed and added / updated if needed (for bug fixes / features)

Does this introduce a breaking change?

Please see our docs on breaking changes to help!

  • 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 28, 2026
@deiga deiga added r/repository_environment Status: Triage This is being looked at and prioritized labels Jul 28, 2026
@deiga
deiga requested a review from Copilot July 28, 2026 16:51
@deiga

deiga commented Jul 28, 2026

Copy link
Copy Markdown
Collaborator

Nice, thanks! Could you add a regression acceptance test case as well?

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

These provider review instructions are being used.

Fixes prevent_self_review state normalization when GitHub omits reviewer protection data.

Changes:

  • Defaults prevent_self_review state to false.
  • Safely handles a nil API value.

Comment thread github/resource_github_repository_environment.go
@kishaningithub

Copy link
Copy Markdown
Author

@deiga Have added the test. Can you kindly review?

Comment thread github/resource_github_repository_environment.go Outdated
Comment thread github/resource_github_repository_environment_test.go Outdated
@kishaningithub

Copy link
Copy Markdown
Author

@deiga Have resolved your PR review feedback. Can you kindly check once?

@deiga

deiga commented Aug 3, 2026

Copy link
Copy Markdown
Collaborator

@kishaningithub I ran your test without any other code changes and the test doesn't fail. Can you please provide DEBUG level logs of the issue you are trying to resolve here?

@kishaningithub

Copy link
Copy Markdown
Author

@deiga The issue was with the test

The original test did not reproduce the issue because it asserted the value immediately after creation. At that point, the schema default had already populated prevent_self_review = false, so the test passed even without the read-path fix.

The failing scenario is a refresh/read from imported or legacy state where prevent_self_review is absent and the GitHub API returns no required_reviewers protection rule.

I replaced the test with a read-path regression test that starts with the attribute absent from state and mocks that API response.

The corrected test fails without the production change and passes with it. I also removed prevent_self_review from ImportStateVerifyIgnore so the import test verifies this state value.

Comment thread github/resource_github_repository_environment_test.go Outdated
@kishaningithub
kishaningithub force-pushed the fix-prevent-self-review-no-reviewers branch from b0a5831 to 7aaf5ec Compare August 5, 2026 08:14
Comment thread github/resource_github_repository_environment.go
@kishaningithub
kishaningithub force-pushed the fix-prevent-self-review-no-reviewers branch from 7aaf5ec to 8ec4533 Compare August 10, 2026 05:44
@kishaningithub

Copy link
Copy Markdown
Author

@deiga This is the exact scenario.. I have a state which is like this

Result of terraform show (redacted)

resource "github_repository_environment" "repo_environment" {
    can_admins_bypass = true
    environment       = "dev_bot"
    id                = "example-repo:dev_bot"
    repository        = "example-repo"
    repository_id     = 123456789
    wait_timer        = 0

    reviewers {}
}

Result of terraform plan (redacted)

Then we have a plan run where prevent_self_review is being set explicitly

~ resource "github_repository_environment" "repo_environment" {
      id                  = "example-repo:dev_bot"
    + prevent_self_review = false
      # (5 unchanged attributes hidden)
    ~ reviewers {
        + teams = (known after apply)
      }
  }

Result of `terraform apply (redacted)

The apply fails with the below error

Error: Provider produced inconsistent final plan

When expanding the plan for
github_repository_environment.repo_environment["dev_bot"]
to include new values learned so far during apply, provider
"registry.terraform.io/integrations/github" produced an invalid new value for
.prevent_self_review: was cty.False, but now null.

This is a bug in the provider, which should be reported in the provider's own
issue tracker.

@kishaningithub

Copy link
Copy Markdown
Author

@deiga Given the above context. Which route do you think i must take for the fix? Any suggestions?

@deiga

deiga commented Aug 10, 2026

Copy link
Copy Markdown
Collaborator

@kishaningithub Please provide a testcase that reproduces your error-case and/or DEBUG level logs if the apply run

@deiga

deiga commented Aug 22, 2026

Copy link
Copy Markdown
Collaborator

I think this PR would/should resolve #3609 as well

@deiga

deiga commented Aug 22, 2026

Copy link
Copy Markdown
Collaborator

@kishaningithub I tried creating a test case which follows your example, but I couldn't get it to fail like that

@kishaningithub

Copy link
Copy Markdown
Author

@deiga Yes I tried it too.. But could not make it fail.. We need to simulate it like this somehow in the test case (which I am trying)

Use provider version 6.8.3, Create the github_repository_environment without reviewers and prevent_self_review

Upgrade to latest provider version setting the legacy_client provider attribute to false,Then set prevent_self_review setting it to false for this resource and run a terraform plan and apply

That's my exact production scenario

@deiga

deiga commented Aug 23, 2026

Copy link
Copy Markdown
Collaborator

@kishaningithub Ah! This is about a migration between provider versions?
That makes this clearer.
Writing a test for that is slightly harder, we don't have a working example of that currently

@kishaningithub

Copy link
Copy Markdown
Author

Yes @deiga We hit this issue when upgrading the provider version from 6.8.3 to latest version disabling the legacy client

@deiga

deiga commented Aug 23, 2026

Copy link
Copy Markdown
Collaborator

@kishaningithub Have you tried pinpointing which version upgrade causes this?

@kishaningithub

kishaningithub commented Aug 24, 2026

Copy link
Copy Markdown
Author

@deiga Thats the challenge. Putting here the exact state file entries (redacted) causing this issue for reference

 {
  "index_key": "example_environment",
  "schema_version": 1,
  "attributes": {
    "can_admins_bypass": true,
    "deployment_branch_policy": [],
    "environment": "example_environment",
    "id": "example-repo:example_environment",
    "prevent_self_review": null,
    "repository": "example-repo",
    "repository_id": 123456789,
    "reviewers": [
      {
        "teams": null,
        "users": null
      }
    ],
    "wait_timer": 0
  },
  "sensitive_attributes": [],
}

@kishaningithub
kishaningithub force-pushed the fix-prevent-self-review-no-reviewers branch from bd0d53e to f88454d Compare August 24, 2026 06:41
@deiga

deiga commented Aug 24, 2026

Copy link
Copy Markdown
Collaborator

@kishaningithub Thanks!

I wonder how that state was even achieved, since the default has been "false" for years.

But a plan/apply with 6.8.3 does not have those issue? Can you test if it already happens on 6.9 or 6.10?

@kishaningithub

kishaningithub commented Aug 24, 2026

Copy link
Copy Markdown
Author

[For issue followers] In case you are wondering how to work around this issue without directly editing the statefile here is a possible solution (this is what i did)

  • Download the statefile json. Find out the affected repos by searching for "prevent_self_review": null in the file the line above that contains the id from which you can extract the repository name
  • Delete the affected environements either via UI or via curl
curl -L \
  -X DELETE \
  -H "Authorization: Bearer YOUR_GITHUB_TOKEN" \
  https://api.github.com/repos/OWNER/REPO/environments/ENVIRONMENT_NAME
  • Run a targetted terraform plan and terraform apply on the affected resources

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

Labels

r/repository_environment Status: Triage This is being looked at and prioritized Type: Bug Something isn't working as documented

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants