Skip to content

[BUG]: unexpected 'contexts' deletion in github_branch_protection when archiving repository #3306

@hanyouqing

Description

@hanyouqing

Expected Behavior

Archiving a repository should not trigger changes to the required_status_checks.0.contexts list in the
Terraform state. The provider should recognize that the status checks still exist in the modern checks array
(which the GitHub API continues to return) and maintain the legacy contexts state to avoid unnecessary plan
churn.

Actual Behavior

After archiving a repository, terraform plan shows an unexpected change to delete the contexts list:

   1   ~ resource "github_branch_protection_v3" "example" {
   2       ~ required_status_checks {
   3           - contexts = [
   4               - "ci/test",
   5               - "ci/build",
   6             ] -> null
   7             # ... (other fields like 'checks' remain unchanged)
   8         }
   9     }

This caused the error below when archiving a repo:

│ Error: PUT https://api.github.com/repos/ORG/REPO_NAME/branches/master/protection: 403 Repository was archived so is read-only. []
--
│

This happens because the legacy contexts field is being returned as an empty list by the GitHub API for
archived repositories, while the modern checks array remains populated.

Root Cause Analysis

  1. Dual-Population: When a branch protection rule is created using the modern checks array, GitHub's
    backend auto-populates the legacy contexts field for backward compatibility.
  2. Computed State: Because contexts is marked as Computed: true in the provider, Terraform saves these
    auto-populated values into the .tfstate during the initial Read.
  3. API Change on Archive: When a repository is archived, the GitHub REST (v3) API returns an empty list for
    the legacy contexts field, but correctly returns the data in the checks array.
  4. Drift Detection: The provider's Read function receives the empty contexts from the API and, since it
    differs from the saved state, Terraform interprets this as a deletion.

Proposed Fix
The provider's Read logic should be updated to be more resilient to this API inconsistency:

  • Fallback Logic: In github/resource_github_branch_protection_v3_utils.go, the
    flattenAndSetRequiredStatusChecks function should fallback to populating the contexts state from the
    names in the checks array if the legacy contexts field is returned as empty.
  • Schema Update: In github/resource_github_branch_protection.go, ensure the contexts field is marked as
    Computed: true to prevent drift detection for auto-populated legacy values.

Terraform Version

  • terraform 1.4.7

Affected Resource(s)

  • github_branch_protection (GraphQL/v4)
  • github_branch_protection_v3 (REST/v3)

Terraform Configuration Files

Steps to Reproduce

  • Create a repo with terraform
  • Update archive = true

Introduced in

https://github.com/integrations/terraform-provider-github/releases/tag/v5.16.0

https://github.com/integrations/terraform-provider-github/pull/1415/changes#diff-a483da9852b3cd77bdd18a439d5d0[…]8f2c5970b4a1e4e03d8747526e29R56-R63 (edited) 
[10:13 AM]https://github.com/integrations/terraform-provider-github/pull/1415/changes#diff-63892fd5ebce048bce10d1f8c7defe1356f154a22acf8cc2f82ece6c3c6914b7L44

Debug Output

Panic Output

Code of Conduct

  • I agree to follow this project's Code of Conduct

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type: BugSomething isn't working as documented

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions