5858 default: maintainer
5959 type: str
6060 choices: ["maintainer", "developer", "nobody"]
61+ allow_force_push:
62+ description:
63+ - Whether or not to allow force pushes to the protected branch.
64+ type: bool
65+ version_added: '11.3.0'
66+ code_owner_approval_required:
67+ description:
68+ - Whether or not to require code owner approval to push.
69+ type: bool
70+ version_added: '11.3.0'
6171"""
6272
6373
@@ -106,27 +116,43 @@ def protected_branch_exist(self, name):
106116 except Exception as e :
107117 return False
108118
109- def create_protected_branch (self , name , merge_access_levels , push_access_level ):
110- if self ._module .check_mode :
111- return True
112- merge = self .ACCESS_LEVEL [merge_access_levels ]
113- push = self .ACCESS_LEVEL [push_access_level ]
114- self .project .protectedbranches .create ({
119+ def create_or_update_protected_branch (self , name , options ):
120+ protected_branch_options = {
115121 'name' : name ,
116- 'merge_access_level' : merge ,
117- 'push_access_level' : push
118- })
119-
120- def compare_protected_branch (self , name , merge_access_levels , push_access_level ):
121- configured_merge = self .ACCESS_LEVEL [merge_access_levels ]
122- configured_push = self .ACCESS_LEVEL [push_access_level ]
123- current = self .protected_branch_exist (name = name )
124- current_merge = current .merge_access_levels [0 ]['access_level' ]
125- current_push = current .push_access_levels [0 ]['access_level' ]
126- if current :
127- if current .name == name and current_merge == configured_merge and current_push == configured_push :
128- return True
129- return False
122+ 'allow_force_push' : options ['allow_force_push' ],
123+ 'code_owner_approval_required' : options ['code_owner_approval_required' ],
124+ }
125+ protected_branch = self .protected_branch_exist (name = name )
126+ changed = False
127+ if protected_branch and self .can_update (protected_branch , options ):
128+ for arg_key , arg_value in protected_branch_options .items ():
129+ if arg_value is not None :
130+ if getattr (protected_branch , arg_key ) != arg_value :
131+ setattr (protected_branch , arg_key , arg_value )
132+ changed = True
133+ if changed and not self ._module .check_mode :
134+ protected_branch .save ()
135+ else :
136+ # Set immutable options only on (re)creation
137+ protected_branch_options ['merge_access_level' ] = options ['merge_access_levels' ]
138+ protected_branch_options ['push_access_level' ] = options ['push_access_level' ]
139+ if protected_branch :
140+ # Exists, but couldn't update. So, delete first
141+ self .delete_protected_branch (name )
142+ if not self ._module .check_mode :
143+ self .project .protectedbranches .create (protected_branch_options )
144+ changed = True
145+
146+ return changed
147+
148+ def can_update (self , protected_branch , options ):
149+ # these keys are not set on update the same way they are on creation
150+ configured_merge = options ['merge_access_levels' ]
151+ configured_push = options ['push_access_level' ]
152+ current_merge = protected_branch .merge_access_levels [0 ]['access_level' ]
153+ current_push = protected_branch .push_access_levels [0 ]['access_level' ]
154+ return ((configured_merge is None or current_merge == configured_merge ) and
155+ (configured_push is None or current_push == configured_push ))
130156
131157 def delete_protected_branch (self , name ):
132158 if self ._module .check_mode :
@@ -142,6 +168,8 @@ def main():
142168 name = dict (type = 'str' , required = True ),
143169 merge_access_levels = dict (type = 'str' , default = "maintainer" , choices = ["maintainer" , "developer" , "nobody" ]),
144170 push_access_level = dict (type = 'str' , default = "maintainer" , choices = ["maintainer" , "developer" , "nobody" ]),
171+ allow_force_push = dict (type = 'bool' ),
172+ code_owner_approval_required = dict (type = 'bool' ),
145173 state = dict (type = 'str' , default = "present" , choices = ["absent" , "present" ]),
146174 )
147175
@@ -174,23 +202,24 @@ def main():
174202
175203 gitlab_version = gitlab .__version__
176204 if LooseVersion (gitlab_version ) < LooseVersion ('2.3.0' ):
177- module .fail_json (msg = "community.general.gitlab_proteched_branch requires python-gitlab Python module >= 2.3.0 (installed version: [%s])."
205+ module .fail_json (msg = "community.general.gitlab_protected_branch requires python-gitlab Python module >= 2.3.0 (installed version: [%s])."
178206 " Please upgrade python-gitlab to version 2.3.0 or above." % gitlab_version )
179207
180208 this_gitlab = GitlabProtectedBranch (module = module , project = project , gitlab_instance = gitlab_instance )
181209
182210 p_branch = this_gitlab .protected_branch_exist (name = name )
183- if not p_branch and state == "present" :
184- this_gitlab .create_protected_branch (name = name , merge_access_levels = merge_access_levels , push_access_level = push_access_level )
185- module .exit_json (changed = True , msg = "Created the proteched branch." )
186- elif p_branch and state == "present" :
187- if not this_gitlab .compare_protected_branch (name , merge_access_levels , push_access_level ):
188- this_gitlab .delete_protected_branch (name = name )
189- this_gitlab .create_protected_branch (name = name , merge_access_levels = merge_access_levels , push_access_level = push_access_level )
190- module .exit_json (changed = True , msg = "Recreated the proteched branch." )
211+ options = {
212+ "merge_access_levels" : this_gitlab .ACCESS_LEVEL [merge_access_levels ],
213+ "push_access_level" : this_gitlab .ACCESS_LEVEL [push_access_level ],
214+ "allow_force_push" : module .params ["allow_force_push" ],
215+ "code_owner_approval_required" : module .params ["code_owner_approval_required" ],
216+ }
217+ if state == "present" :
218+ changed = this_gitlab .create_or_update_protected_branch (name , options )
219+ module .exit_json (changed = changed , msg = "Created or updated the protected branch." )
191220 elif p_branch and state == "absent" :
192221 this_gitlab .delete_protected_branch (name = name )
193- module .exit_json (changed = True , msg = "Deleted the proteched branch." )
222+ module .exit_json (changed = True , msg = "Deleted the protected branch." )
194223 module .exit_json (changed = False , msg = "No changes are needed." )
195224
196225
0 commit comments