terraform-provider-github: Error when creating a new branch for an empty repository

Hello,

We are facing this error while trying to create a new branch for a new repository :

github_branch.branch: Creating...

Error: Error querying GitHub branch reference my-organization/first-repository (refs/heads/master): GET https://api.github.com/repos/my-organization/first-repository/git/refs/heads/master: 409 Git Repository is empty. []

  on main.tf line 15, in resource "github_branch" "branch":
  15: resource "github_branch" "branch" {

Terraform Version

Terraform v0.12.29
+ provider.github v2.9.2

Affected Resource(s)

  • github_branch

Terraform Configuration Files

provider "github" {
  version = "~> 2.9"
  token        = "***"
  organization = "my-organization"
}

resource "github_repository" "repository" {
  name        = "first-repository"
  description = "This is the first repository"
  private     = true

  delete_branch_on_merge = true
}

resource "github_branch" "branch" {
  repository = github_repository.repository.name
  branch     = "main"
}

Expected Behavior

Create the repository and the branch

Actual Behavior

The branch is not created because the repository is empty

Regards

About this issue

  • Original URL
  • State: open
  • Created 4 years ago
  • Reactions: 6
  • Comments: 19 (5 by maintainers)

Most upvoted comments

I have found that the compromise for creating brand-new repos looks like this:

locals {
  default_branch = "main"
}

resource "github_repository" "test" {
  name                   = "test"
  description            = "test"
  visibility             = "private"
  // Creates the 'main' branch with a small 'README.md'
  auto_init              = true
  has_issues             = true
  has_downloads          = true
  vulnerability_alerts   = true
  allow_merge_commit     = false
  delete_branch_on_merge = true
}

// auto-init in the repo gets us this branch already.
// We could import this, but having this in here will breaks the run and
// it doesn't really do anything super useful at this point.
//
//resource "github_branch" "test_default" {
//  repository = github_repository.test.name
//  branch     = "main"
//}

resource "github_branch_default" "test_default" {
  repository = github_repository.test.name
  branch     = local.default_branch
}

resource "github_branch_protection" "test" {
  repository_id           = github_repository.test.node_id
  pattern                 = local.default_branch
  push_restrictions       = []
  required_linear_history = true
  required_pull_request_reviews {
    dismiss_stale_reviews           = true
    dismissal_restrictions          = []
    require_code_owner_reviews      = false
    required_approving_review_count = 1
    restrict_dismissals             = false
  }
}

resource "github_team_repository" "test" {
  repository = github_repository.test.name
  team_id    = github_team.All.id
  permission = "push"
}

The main thing is to use auto_init = true for the repo creation and then avoid using github_branch for the main branch.

The branch is not created because the repository is not “initialized” - unfortunately we hit the same behavior but this is something coming from the github api - when the repo is created first, you need to initialize it to be able to create a branch.

it’s a feature, not a bug 😕

Yes, you need to look up the organization default.

Also, you have a further impact/problem. If you try to create a branch for what would be the default branch (which makes sense), then it will fail, forcing you to do an import (which is a nightmare). This should be smarter, perhaps always looking up if the branch exists or not and not holding state–just declaring the branch SHOULD exist if it doesn’t.

And then an end of life problem. We now have archive_on_destroy but no equivalent for branches. So when the repo is neatly archived, all the branches will be gone (or at least all the non-default branches depending on the above implementation).

Then there’s the problem of changing default branches. If you don’t track your default branch, then it won’t create a new one, it’ll just destroy the old one. If you do track it, then it will destroy the old one and create a new one, moving the HEAD of that branch. Nasty problem. (Edge case, but nasty.)

It seems like adding the new branch and default branch resources was not thought out terribly well. They’re of very limited, and largely dangerous use, when all they do is prevent an error upon creation of a new repo and branch protection of a branch not existing. That is easily solved by creating the branch and then re-applying.

The auto_init parameter may be helpful for creating a branch when the repository is created. We also have a new default_branch resource that may be helpful?

Hi got the same issue , Added source_branch = organization_default_branch to resource “github_branch” , hope it helps !

I think that source_branch argument should default to main

Hi friends, Give this a try; it worked for me when creating a new branch for an empty repository

terraform { required_providers { github = { source = “hashicorp/github” version = “5.42.0” } } }

provider “github” { token = “Your_Github_Token” }

locals { default_branch = “main” }

resource “github_repository” “repository” { name = “Your_name” description = “automation” visibility = “private” auto_init = true }

resource “time_sleep” “wait_for_repository” { depends_on = [github_repository.repository]

create_duration = “30s” # Adjust the duration as needed }

resource “github_branch” “default” { repository = github_repository.repository.name branch = local.default_branch source_branch = “main” depends_on = [time_sleep.wait_for_repository] }

resource “github_branch” “production” { repository = github_repository.repository.name branch = “prod” depends_on = [time_sleep.wait_for_repository] }

resource “github_branch” “development” { repository = github_repository.repository.name branch = “dev” depends_on = [time_sleep.wait_for_repository] }

resource “github_branch” “testing” { repository = github_repository.repository.name branch = “uat” depends_on = [time_sleep.wait_for_repository] }

Still an issue.

Hi there, any update on this?

Perhaps a partially better solution would be for the default branch resource to track and create a branch, and perhaps the github API supports the renaming like it does in the UI? At the least renaming it would know which branch to rename and retain the existing SHA.

I think that source_branch argument should default to main

Perhaps we should remove the default or make it look that up (if not specified) since that is a per repository setting. While I think switching to match githubs new defaults are a good thing. That said because of the wide impact of all these changes many orgs have opted to still keep using “master” until all the tooling better supports it (not just terraform). Either way making any change to a default behavior should be considered a “breaking change” and only made in a major version.