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

Allow default branch to be set to master/main on update, using a new github_branch_default resource #194

Merged
merged 3 commits into from
Nov 24, 2020

Conversation

liamg
Copy link
Contributor

@liamg liamg commented Feb 22, 2019

@ghost ghost added the size/S label Feb 22, 2019
@liamg liamg changed the title Allows default branch to be set to master on update Allow default branch to be set to master on update Feb 22, 2019
@liamg
Copy link
Contributor Author

liamg commented Mar 28, 2019

@radeksimko Apologies for the ping, but this is ready to be merged and fixes a bug that is hurting us - does it look good to you?

if branch != "master" {
repoReq.DefaultBranch = &branch
}
repoReq.DefaultBranch = &branch
Copy link
Contributor

Choose a reason for hiding this comment

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

Has something changed with the api or behavior from github? Based on my own experiences and the comments the reason its in place is because if you set the default branch and use auto_init = false[1] this will break. I agree that its probably not the right condition to check but I don't think this is a safe change. I would suggest we avoid setting it when auto_init = false as this covers the scenario better I think with fewer side effects.

[1]: a common scenario for this is to create an internal fork of a public project where you may need to diverge from the upstream.

Copy link
Contributor Author

@liamg liamg Apr 1, 2019

Choose a reason for hiding this comment

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

This is true, though only on creation. You may want to update a repo that was initially created with auto_init set to false, but that now has a valid ref for the default branch.

I guess the only way to do this safely would be to check if the ref actually exists on the repo and fail early if not.

WDYT?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The specific check for master isn't really correct, because setting the default to any ref that doesn't exist will result in the same error.

Copy link
Contributor

Choose a reason for hiding this comment

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

I agree the check for master is not really correct, that being said we need a condition to make it work for initial setup as well as future setups. I would say that if the ref does not exist and branch is master we set it to null and otherwise we set it to what was passed? I suppose we could also have a third condition of if its not master and ref does not exist we can error out there. I think this should cover both workflows.

Copy link
Contributor

Choose a reason for hiding this comment

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

Can I expect the suggested changes to be applied anytime soon?

Copy link
Contributor

Choose a reason for hiding this comment

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

I'd like to help here but am unsure if I have understood the requested fix. Does this implementation satisfy the two use cases?

type validDefaultBranchOptions struct {
	d       *schema.ResourceData
	owner   string
	repo    string
	repoReq *github.Repository
	client  *github.Client
}

func validDefaultBranch(options validDefaultBranchOptions) (string, error) {

	// A `default_branch` is valid if it is safe for initial repository setup
	// as well as future setups

	defaultBranch := ""
	if v, ok := options.d.GetOk("default_branch"); ok {
		defaultBranch = v.(string)
	}

	// Assert requested default branch exists
	ctx := context.WithValue(context.Background(), ctxId, options.d.Id())
	_, _, err := options.client.Repositories.GetBranch(ctx, options.owner, options.repo, defaultBranch)
	if err != nil {
		// TODO: Match a specific error
		return defaultBranch, errors.New("default branch does not exist")
	}

	// Assert `auto_init` is not `false` when a valid default branch is requested
	if *options.repoReq.AutoInit == false {
		// When creating an internal fork of a public project,
		// setting the default branch alongside `auto_init = false` fails
		return defaultBranch, errors.New("unsupported repository for default branch request")
	}

	return defaultBranch, nil
}

@liamg @majormoses - does checking for branch existence and refusing when auto_init is false address all concerns without raising new ones?

Copy link
Contributor

@majormoses majormoses Feb 21, 2020

Choose a reason for hiding this comment

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

@jcudit thanks for taking a look I am not too familiar with go but it looks right. It's been a long time so I am trying to remember back to the problem so apologies if I get some details wrong. The problem as I understand it is how to support:

  • creating a new repository: can fail because it does not wait for the ref to exist.
  • importing a repository and modifying it after its existence: With an import it implicitly means that the resource existed so we don't need any special handling we just do what is requested.
  • updating a resource in a state: In the cause of created or imported resources that are later updated there would have to be some branch regardless of its name. It could fail if someone tries to set it to a non existing branch, it would have to be a branch and not a generic ref (sha, tag) which we do in your proposed patch.

I believe the reason the check for master was for initial creation as the requested resource did not exist github would error out. At the time terraform did not have the concept of an exposed null input/variable type (until 0.12+) making that check for "master" something that solved the issue. Perhaps this might be a better to switch this check to null as its intent will be clearer and its behavior can entirely be controlled by the caller. Setting this to null would mean that we do not manage this setting until it is changed to a non null value and in a way is similar to ignore_changes experience. Defaulting to null will keep the existing behavior with solving our issues. The workflow for creating a new repo with a non default branch would be:

  1. create repo (omit or explicitly set to null)
  2. push/create new branch
  3. update terraform to change the default, terraform will ignore any changes to default branch unless you explicitly ask for it

I am not sure if I thought through this but the idea of terraform checking out some other repo feels odd. I view the Terraform provider responsibility in the context of github is to manage github as a service not to actually interact with git directly. It seems harmless enough but I am not sure where blurring those lines could lead to.

@shogo82148
Copy link
Contributor

ping
I have same issue with the latest releases (Terraform v0.13.0 and GitHub provider v2.9.2).
any progress?

@jacobeatsspam
Copy link

jacobeatsspam commented Aug 18, 2020

@jcudit @liamg I think I've caught up on all the comments, so here is my $0.02:

  • default_branch is supposed to only be managed on PATCH, which means it shouldn't be sent on the first GET. Therefor, the check should be based on whether the repo already exists or not.

  • This creates a fundamental workflow issue: One must define the repo, apply, update to point at a new branch, apply again. This creates a dependency cycle if the new branch is created with github_branch.

My suggestion is to create a new resource, github_branch_default, to track this attribute, and stop managing it in github_repository.

@majormoses
Copy link
Contributor

  • default_branch is supposed to only be managed on PATCH, which means it shouldn't be sent on the first GET. Therefor, the check should be based on whether the repo already exists or not.
  • This creates a fundamental workflow issue: One must define the repo, apply, update to point at a new branch, apply again. This creates a dependency cycle if the new branch is created with github_branch.

My suggestion is to create a new resource, github_branch_default, to track this attribute, and stop managing it in github_repository.

Good find, I did not notice the patch vs get here. This actually makes a lot of sense now why I solved those problems within my module by abusing auto_init to create a workflow that does not have this issue but relies on 2 plan/apply cycles. Even with this removed I will likely need to keep those "hacks" as there are similar but different issues with branch protection. There is still a part of me that dislikes forcing it as another resource for a number of reasons that mostly boil down to user experience; mostly manifesting in migration/upgrade and breaking changes. I would think we may want to keep the current behavior (with deprecation warnings) and add the new resource this will help consumers identify the issues and how to resolve them.

@ghost ghost added size/L Type: Documentation Improvements or additions to documentation and removed size/S labels Oct 9, 2020
@liamg
Copy link
Contributor Author

liamg commented Oct 9, 2020

@majormoses @jacobisaliveandwell Thanks for the discussion! I've run with the idea above and added a github_branch_default resource. This is my first full new resource so all criticism/ideas will be gratefully received! Hopefully my documentation change is also sufficient...

@liamg liamg changed the title Allow default branch to be set to master on update Allow default branch to be set to master/main on update, using a new github_branch_default resource Oct 9, 2020
@liamg
Copy link
Contributor Author

liamg commented Oct 9, 2020

This could potentially help with the situation in #513 too

@jcudit jcudit added this to the v3.2.0 milestone Oct 9, 2020
Copy link
Contributor

@majormoses majormoses left a comment

Choose a reason for hiding this comment

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

LGTM

website/docs/r/branch_default.html.markdown Outdated Show resolved Hide resolved
website/docs/r/branch_default.html.markdown Outdated Show resolved Hide resolved
website/docs/r/branch_default.html.markdown Show resolved Hide resolved
@ghost ghost added size/XL and removed size/L labels Oct 11, 2020
Copy link
Contributor

@majormoses majormoses left a comment

Choose a reason for hiding this comment

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

LGTM

@jacobeatsspam
Copy link

jacobeatsspam commented Oct 12, 2020

:shipit: Looks good!

@jacobeatsspam
Copy link

@jcudit this is ready for review

Copy link
Contributor

@jcudit jcudit left a comment

Choose a reason for hiding this comment

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

This diff looks great, thanks for putting it together @liamg 🙇

@jcudit jcudit removed this from the v3.2.0 milestone Oct 17, 2020
@jcudit jcudit added this to the v3.1.1 milestone Oct 17, 2020
@jcudit jcudit modified the milestones: v4.0.1, v4.0.2 Nov 11, 2020
@dwilliams782
Copy link

Any idea on timelines for this to be released? This would be extremely useful to restore "master" on new repositories given the recent changes...

@jcudit jcudit modified the milestones: v4.1.1, v4.1.0 Nov 24, 2020
@jcudit
Copy link
Contributor

jcudit commented Nov 24, 2020

@dwilliams782 thanks for the ping. Lets get this into the next release.

@liamg are you around to address the outstanding conflict?

@liamg
Copy link
Contributor Author

liamg commented Nov 24, 2020

@jcudit Yep, conflicts resolved :)

@jcudit jcudit merged commit cfaf4d0 into integrations:master Nov 24, 2020
kfcampbell pushed a commit to kfcampbell/terraform-provider-github that referenced this pull request Jul 26, 2022
…github_branch_default resource (integrations#194)

* Added github_branch_default resource

* Fix branch_default example in docs
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
size/XL Type: Documentation Improvements or additions to documentation
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[BUG] Cannot switch default branch back to master
7 participants