@@ -2,10 +2,9 @@ package provider
2
2
3
3
import (
4
4
"context"
5
- "errors"
6
5
"fmt"
7
6
"log"
8
- "net/http "
7
+ "strconv "
9
8
"time"
10
9
11
10
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
@@ -564,12 +563,11 @@ func resourceGitlabProjectCreate(ctx context.Context, d *schema.ResourceData, me
564
563
565
564
if _ , ok := d .GetOk ("push_rules" ); ok {
566
565
err := editOrAddPushRules (ctx , client , d .Id (), d )
567
- var httpError * gitlab.ErrorResponse
568
- if errors .As (err , & httpError ) && httpError .Response .StatusCode == http .StatusNotFound {
569
- log .Printf ("[DEBUG] Failed to edit push rules for project %q: %v" , d .Id (), err )
570
- return diag .Errorf ("Project push rules are not supported in your version of GitLab" )
571
- }
572
566
if err != nil {
567
+ if is404 (err ) {
568
+ log .Printf ("[DEBUG] Failed to edit push rules for project %q: %v" , d .Id (), err )
569
+ return diag .Errorf ("Project push rules are not supported in your version of GitLab" )
570
+ }
573
571
return diag .Errorf ("Failed to edit push rules for project %q: %s" , d .Id (), err )
574
572
}
575
573
}
@@ -629,6 +627,35 @@ func resourceGitlabProjectCreate(ctx context.Context, d *schema.ResourceData, me
629
627
}
630
628
}
631
629
630
+ // Branch protection for a newly created branch is an async action, so use WaitForState to ensure it's protected
631
+ // before we continue. Note this check should only be required when there is a custom default branch set
632
+ // See issue 800: https://github.com/gitlabhq/terraform-provider-gitlab/issues/800
633
+ stateConf := & resource.StateChangeConf {
634
+ Pending : []string {"false" },
635
+ Target : []string {"true" },
636
+ Timeout : 2 * time .Minute , //The async action usually completes very quickly, within seconds. Don't wait too long.
637
+ Refresh : func () (interface {}, string , error ) {
638
+ branch , _ , err := client .Branches .GetBranch (project .ID , project .DefaultBranch , gitlab .WithContext (ctx ))
639
+ if err != nil {
640
+ if is404 (err ) {
641
+ // When we hit a 404 here, it means the default branch wasn't created at all as part of the project
642
+ // this will happen when "default_branch" isn't set, or "initialize_with_readme" is set to false.
643
+ // We don't need to wait anymore, so return "true" to exist the wait loop.
644
+ return branch , "true" , nil
645
+ }
646
+
647
+ //This is legit error, return the error.
648
+ return nil , "" , err
649
+ }
650
+
651
+ return branch , strconv .FormatBool (branch .Protected ), nil
652
+ },
653
+ }
654
+
655
+ if _ , err := stateConf .WaitForStateContext (ctx ); err != nil {
656
+ return diag .Errorf ("error while waiting for branch %s to reach 'protected' status, %s" , project .DefaultBranch , err )
657
+ }
658
+
632
659
var editProjectOptions gitlab.EditProjectOptions
633
660
634
661
if v , ok := d .GetOk ("mirror_overwrites_diverged_branches" ); ok {
@@ -679,8 +706,7 @@ func resourceGitlabProjectRead(ctx context.Context, d *schema.ResourceData, meta
679
706
log .Printf ("[DEBUG] read gitlab project %q push rules" , d .Id ())
680
707
681
708
pushRules , _ , err := client .Projects .GetProjectPushRules (d .Id (), gitlab .WithContext (ctx ))
682
- var httpError * gitlab.ErrorResponse
683
- if errors .As (err , & httpError ) && httpError .Response .StatusCode == http .StatusNotFound {
709
+ if is404 (err ) {
684
710
log .Printf ("[DEBUG] Failed to get push rules for project %q: %v" , d .Id (), err )
685
711
} else if err != nil {
686
712
return diag .Errorf ("Failed to get push rules for project %q: %s" , d .Id (), err )
@@ -868,12 +894,11 @@ func resourceGitlabProjectUpdate(ctx context.Context, d *schema.ResourceData, me
868
894
869
895
if d .HasChange ("push_rules" ) {
870
896
err := editOrAddPushRules (ctx , client , d .Id (), d )
871
- var httpError * gitlab.ErrorResponse
872
- if errors .As (err , & httpError ) && httpError .Response .StatusCode == http .StatusNotFound {
873
- log .Printf ("[DEBUG] Failed to get push rules for project %q: %v" , d .Id (), err )
874
- return diag .Errorf ("Project push rules are not supported in your version of GitLab" )
875
- }
876
897
if err != nil {
898
+ if is404 (err ) {
899
+ log .Printf ("[DEBUG] Failed to get push rules for project %q: %v" , d .Id (), err )
900
+ return diag .Errorf ("Project push rules are not supported in your version of GitLab" )
901
+ }
877
902
return diag .Errorf ("Failed to edit push rules for project %q: %s" , d .Id (), err )
878
903
}
879
904
}
@@ -897,9 +922,9 @@ func resourceGitlabProjectDelete(ctx context.Context, d *schema.ResourceData, me
897
922
Pending : []string {"Deleting" },
898
923
Target : []string {"Deleted" },
899
924
Refresh : func () (interface {}, string , error ) {
900
- out , response , err := client .Projects .GetProject (d .Id (), nil , gitlab .WithContext (ctx ))
925
+ out , _ , err := client .Projects .GetProject (d .Id (), nil , gitlab .WithContext (ctx ))
901
926
if err != nil {
902
- if response . StatusCode == 404 {
927
+ if is404 ( err ) {
903
928
return out , "Deleted" , nil
904
929
}
905
930
log .Printf ("[ERROR] Received error: %#v" , err )
0 commit comments