@@ -667,33 +667,42 @@ func resourceGitlabProjectCreate(ctx context.Context, d *schema.ResourceData, me
667667 }
668668 }
669669
670- // Branch protection for a newly created branch is an async action, so use WaitForState to ensure it's protected
671- // before we continue. Note this check should only be required when there is a custom default branch set
672- // See issue 800: https://github.com/gitlabhq/terraform-provider-gitlab/issues/800
673- stateConf := & resource.StateChangeConf {
674- Pending : []string {"false" },
675- Target : []string {"true" },
676- Timeout : 2 * time .Minute , //The async action usually completes very quickly, within seconds. Don't wait too long.
677- Refresh : func () (interface {}, string , error ) {
678- branch , _ , err := client .Branches .GetBranch (project .ID , project .DefaultBranch , gitlab .WithContext (ctx ))
679- if err != nil {
680- if is404 (err ) {
681- // When we hit a 404 here, it means the default branch wasn't created at all as part of the project
682- // this will happen when "default_branch" isn't set, or "initialize_with_readme" is set to false.
683- // We don't need to wait anymore, so return "true" to exist the wait loop.
684- return branch , "true" , nil
685- }
670+ // If the project is assigned to a group namespace and the group has *default branch protection*
671+ // disabled (`default_branch_protection = 0`) then we don't have to wait for one.
672+ waitForDefaultBranchProtection , err := expectDefaultBranchProtection (ctx , client , project )
673+ if err != nil {
674+ return diag .Errorf ("Failed to fetch group the project %d is owned by: %+v" , project .ID , err )
675+ }
686676
687- //This is legit error, return the error.
688- return nil , "" , err
689- }
677+ if waitForDefaultBranchProtection {
678+ // Branch protection for a newly created branch is an async action, so use WaitForState to ensure it's protected
679+ // before we continue. Note this check should only be required when there is a custom default branch set
680+ // See issue 800: https://github.com/gitlabhq/terraform-provider-gitlab/issues/800
681+ stateConf := & resource.StateChangeConf {
682+ Pending : []string {"false" },
683+ Target : []string {"true" },
684+ Timeout : 2 * time .Minute , //The async action usually completes very quickly, within seconds. Don't wait too long.
685+ Refresh : func () (interface {}, string , error ) {
686+ branch , _ , err := client .Branches .GetBranch (project .ID , project .DefaultBranch , gitlab .WithContext (ctx ))
687+ if err != nil {
688+ if is404 (err ) {
689+ // When we hit a 404 here, it means the default branch wasn't created at all as part of the project
690+ // this will happen when "default_branch" isn't set, or "initialize_with_readme" is set to false.
691+ // We don't need to wait anymore, so return "true" to exist the wait loop.
692+ return branch , "true" , nil
693+ }
690694
691- return branch , strconv .FormatBool (branch .Protected ), nil
692- },
693- }
695+ //This is legit error, return the error.
696+ return nil , "" , err
697+ }
698+
699+ return branch , strconv .FormatBool (branch .Protected ), nil
700+ },
701+ }
694702
695- if _ , err := stateConf .WaitForStateContext (ctx ); err != nil {
696- return diag .Errorf ("error while waiting for branch %s to reach 'protected' status, %s" , project .DefaultBranch , err )
703+ if _ , err := stateConf .WaitForStateContext (ctx ); err != nil {
704+ return diag .Errorf ("error while waiting for branch %s to reach 'protected' status, %s" , project .DefaultBranch , err )
705+ }
697706 }
698707
699708 var editProjectOptions gitlab.EditProjectOptions
@@ -1178,3 +1187,18 @@ func flattenProjectPushRules(pushRules *gitlab.ProjectPushRules) (values []map[s
11781187func namespaceOrPathChanged (ctx context.Context , d * schema.ResourceDiff , meta interface {}) bool {
11791188 return d .HasChange ("namespace_id" ) || d .HasChange ("path" )
11801189}
1190+
1191+ func expectDefaultBranchProtection (ctx context.Context , client * gitlab.Client , project * gitlab.Project ) (bool , error ) {
1192+ if project .Namespace .Kind == "group" {
1193+ group , _ , err := client .Groups .GetGroup (project .Namespace .ID , nil , gitlab .WithContext (ctx ))
1194+ if err != nil {
1195+ return false , err
1196+ }
1197+
1198+ return group .DefaultBranchProtection != 0 , nil
1199+ }
1200+
1201+ // projects which are not assigned to a group can't have a "no branch protection" default,
1202+ // thus, we always expect a default branch protection.
1203+ return true , nil
1204+ }
0 commit comments