Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[bug]: github_branch does not refresh state if branch have been deleted #981

Closed
nikophil opened this issue Nov 19, 2021 · 9 comments · Fixed by #1937
Closed

[bug]: github_branch does not refresh state if branch have been deleted #981

nikophil opened this issue Nov 19, 2021 · 9 comments · Fixed by #1937
Labels
hacktoberfest Issues for participation in Hacktoberfest r/branch Status: Up for grabs Issues that are ready to be worked on by anyone Type: Bug Something isn't working as documented

Comments

@nikophil
Copy link

Hello,

I'm trying to update some files in the repositories with terraform.

What I want to achieve is to create a PR on my repositories with some modified files. The problem occurs when the PR gets merged and the branch is deleted by github itself. When applying another time I get a 404 error when creating the file.

Terraform Version

$ tf -v
Terraform v1.0.11
on linux_amd64
+ provider registry.terraform.io/hashicorp/github v4.18.0
+ provider registry.terraform.io/integrations/github v4.18.0

Affected Resource(s)

Please list the resources as a list, for example:

  • github_branch
  • github_repository_file

Terraform Configuration Files

resource "github_branch" "dependabot" {
  repository = "repo"
  branch     = "terraform-dependabot"
}

resource "github_repository_file" "dependabot" {
  repository = "repo"
  branch              = "terraform-dependabot"
  file                = ".github/dependabot.yml"
  content             = file("github-conf-files/dependabot.yml")
  commit_message      = "chore: Dependabot file updated by terraform"
  commit_author       = data.github_user.self.login
  commit_email        = "[email protected]"
  overwrite_on_create = true
}

resource "github_repository_pull_request" "dependabot" {
  repository = "repo"
  base_ref   = "develop"
  head_ref   = "terraform-dependabot"
  title      = "chore: Dependabot file updated by terraform"
}

Expected Behavior

The resource "github_branch" directive should refresh its state if the branch have been deleted. And then the branch should be re-created and the file should be created afterwards.

Actual Behavior

│ Error: unexpected status code: 404 Not Found
│ 
│   with github_repository_file.dependabot,
│   on repository-config-files.tf line 13, in resource "github_repository_file" "dependabot":
│   13: resource "github_repository_file" "dependabot" {

Steps to Reproduce

Please list the steps required to reproduce the issue, for example:

  1. terraform apply # will create the branch / the file / the PR
  2. merge the PR with delete_branch_on_merge option activated
  3. terraform apply # error 404 when trying to create the file: the branch does not exist

Thanks for your help :)

@toelke
Copy link

toelke commented Nov 29, 2021

FWIW, the behaviour is the same since at least 4.2.0 (the earliest version currently available in the terraform registry), but the error message was much clearer until including version 4.13.0:

╷
│ Error: Branch [redacted] not found in repository [redacted] or repository is not readable
│ 
│   with module.[redacted],
│   on modules/[redacted].tf line 5, in resource "github_repository_file" "[redacted]":
│    5: resource "github_repository_file" "[redacted]" {
│ 
╵

Does anyone have a working solution for how to handle deleted branches? E.g. when they are deleted after a PR?

@jcudit jcudit added Type: Bug Something isn't working as documented r/branch labels Jan 5, 2022
@mcintyre321
Copy link

@toelke Did you find a solution for this?

@toelke
Copy link

toelke commented Feb 23, 2022

"Yes". We have this in our README:

When terraform gives you cryptic 404 errors, then the branch terraform was deleted in some repositoy.
Either re-create the branch in the repository manually or remove the affected github_repository_file with terraform state rm "module.[...].github_repository_file.[...]".

We are also toying with the idea of using this abomination which we call "very hack, such curl":

resource "null_resource" "local-exec" {
  for_each = var.files
  provisioner "local-exec" {
    interpreter = ["bash", "-exuc"]
    command     = <<EOC
      # first, check if the file exists in the default-branch and has the correct content
      if [ $(sha1sum <(curl -H "Authorization: token $GITHUB_TOKEN" https://api.github.com/repos/${var.repository}/contents/${each.key} | jq -r '.content' | base64 -d) | awk '{ printf $1;}') == ${sha1(each.value)} ]; then
        exit 0
      fi
      # then, check if the file exists in the branch and has the correct content
      if [ $(sha1sum <(curl -H "Authorization: token $GITHUB_TOKEN" https://api.github.com/repos/${var.repository}/contents/${each.key}?ref=${var.branch} | jq -r '.content' | base64 -d) | awk '{ printf $1;}') == ${sha1(each.value)} ]; then
        exit 0
      fi
      branch_is_new=false
      # Check if the target branch exists and create it if not
      if [ "$(curl -s -w "%%{http_code}" -X HEAD -H "Authorization: token $GITHUB_TOKEN" https://api.github.com/repos/${var.repository}/branches/${var.branch})" == "404" ]; then
        default_branch_sha=$(curl -s -X GET -H "Authorization: token $GITHUB_TOKEN" https://api.github.com/repos/${var.repository}/branches/${var.default_branch} | jq -r .commit.sha)
        curl -X POST -H "Authorization: token $GITHUB_TOKEN" https://api.github.com/repos/${var.repository}/git/refs -d '{"ref": "refs/heads/${var.branch}", "sha": "'$default_branch_sha'"}'
        branch_is_new=true
      fi
      # Commit the file
      curl -H "Authorization: token $GITHUB_TOKEN" -X PUT https://api.github.com/repos/${var.repository}/contents/${each.key} -d '{"message": "commit from terraform", "content": "${base64encode(each.value)}", "branch": "${var.branch}" }'
      # If necessary, create a PR
      if [ $branch_is_new == "true" ]; then
        curl -H "Authorization: token $GITHUB_TOKEN" -X POST https://api.github.com/repos/${var.repository}/pulls -d '{"title": "Updated file via terraform", "head": "${var.branch}", "base": "${var.default_branch}" }'
      fi
    EOC
  }

  triggers = {
    always_run = "${timestamp()}"
  }
}

@mcintyre321
Copy link

mcintyre321 commented Feb 23, 2022

😎 very nifty

I'm also trying to model the "i want this file on master, if it doesn't exist, raise a PR and wait for it to be merged". Which despite being a valid expression of desired state, is a bit of a square peg round hole situation given the resource types we have available.

Maybe need a custom provider here...

@toelke
Copy link

toelke commented Feb 23, 2022

Well, my curl-snippets does exactly that: Check if the file has the correct content in the default-branch and if not, create a branch, create the file and create a PR...

@mcintyre321
Copy link

mcintyre321 commented Feb 23, 2022 via email

@toelke
Copy link

toelke commented Feb 23, 2022

Yes, you are totally right about that.

@github-actions
Copy link

👋 Hey Friends, this issue has been automatically marked as stale because it has no recent activity. It will be closed if no further activity occurs. Please add the Status: Pinned label if you feel that this issue needs to remain open/active. Thank you for your contributions and help in keeping things tidy!

@github-actions github-actions bot added the Stale label Nov 30, 2022
@nickfloyd nickfloyd added Status: Stale Used by stalebot to clean house and removed Stale labels Nov 30, 2022
@kfcampbell kfcampbell added Status: Up for grabs Issues that are ready to be worked on by anyone Priority: Normal labels Dec 1, 2022
@github-actions github-actions bot removed the Status: Stale Used by stalebot to clean house label Dec 1, 2022
@merkata
Copy link

merkata commented Sep 14, 2023

FWIW here's something that works for me:

protect the branch via a branch protection rule like

resource "github_branch_protection" "templated-protect-files" {
  for_each      = toset(var.repo_names)
  repository_id = each.value
  
  pattern = "feature/template-files"
  allows_deletions = false
}

I'm doing this over multiple repos hence the for_each. When you raise a PR from this branch (I use a github actions workflow) and it gets merged, the branch just stays there. Not the most elegant thing, though it works until the issue is properly resolved.

davidforslof added a commit to davidforslof/terraform-provider-github that referenced this issue Oct 5, 2023
@nickfloyd nickfloyd added the hacktoberfest Issues for participation in Hacktoberfest label Oct 11, 2023
@nickfloyd nickfloyd changed the title github_branch does not refresh state if branch have been deleted [bug]: github_branch does not refresh state if branch have been deleted Oct 11, 2023
avidspartan1 pushed a commit to avidspartan1/terraform-provider-github that referenced this issue Feb 5, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
hacktoberfest Issues for participation in Hacktoberfest r/branch Status: Up for grabs Issues that are ready to be worked on by anyone Type: Bug Something isn't working as documented
Projects
None yet
7 participants