-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Add gitlab_merge_request_rule, create Gitlab Merge Request Rule (Enterprise/Ultimate Only) #10077
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
base: main
Are you sure you want to change the base?
Conversation
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
9c8a4b6
to
cda37cb
Compare
cda37cb
to
3db57b4
Compare
This comment was marked as outdated.
This comment was marked as outdated.
3db57b4
to
cc4fa6c
Compare
This comment was marked as outdated.
This comment was marked as outdated.
cc4fa6c
to
e4fd556
Compare
e4fd556
to
52fec9b
Compare
This comment was marked as outdated.
This comment was marked as outdated.
52fec9b
to
8b22741
Compare
8b22741
to
0afbd0f
Compare
0afbd0f
to
491a4b2
Compare
Thanks for your contribution! As a first quick comment, please take a look at https://github.com/ansible-collections/community.general/blob/main/CONTRIBUTING.md#creating-new-modules-or-plugins if you haven't. |
DOCUMENTATION = r""" | ||
module: gitlab_merge_request_rule | ||
short_description: Manage Gitlab Project merge request rules | ||
version_added: 3.4.0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The next feature release will be:
version_added: 3.4.0 | |
version_added: 10.7.0 |
short_description: Manage Gitlab Project merge request rules | ||
version_added: 3.4.0 | ||
description: | ||
- Managing Gitlab Project merge request rules (requires Enterprise/Ultimate Edition). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Managing Gitlab Project merge request rules (requires Enterprise/Ultimate Edition). | |
- Manage Gitlab Project merge request rules. | |
- This currently requires an Enterprise/Ultimate Edition. |
description: | ||
- Managing Gitlab Project merge request rules (requires Enterprise/Ultimate Edition). | ||
author: | ||
- mil1i (!UNKNOWN) [[email protected]] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- mil1i (!UNKNOWN) [liebhaber_sgl@gwto.me] | |
- mil1i (@mil1i) <liebhaber_sgl@gwto.me> |
elements: str | ||
user_ids: | ||
description: | ||
- List of user_ids of who can approve merge requests for this rule. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- List of user_ids of who can approve merge requests for this rule. | |
- List of user ID of who can approve merge requests for this rule. |
elements: int | ||
protected_branch: | ||
description: | ||
- A protected branch name or branch id for this rule to apply to. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- A protected branch name or branch id for this rule to apply to. | |
- A protected branch name or branch ID for this rule to apply to. |
applies_to_all_protected_branches: | ||
description: | ||
- Flag to enable applying this rule to ALL protected branches. | ||
- Ignores "protected_branches" if this flag is set to True. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Ignores "protected_branches" if this flag is set to True. | |
- Ignores O(protected_branches) if this flag is set to V(true). |
Why does protected_branches
have the special value none
(unset) with the same meaning? I would remove that, and make protected_branches
required unless this parameter is set to true
. (And if this parameter is set to true
, disallow specifying protected_branches
.)
applies_to_all_protected_branches: false | ||
protected_branch: main | ||
usernames: | ||
- someonesusername |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please also adjust the other YAML indentations.
- someonesusername | |
- someonesusername |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @mil1i thanks for the cobritbution!
Some initial comments. Overall, the module is over-engineered - multiple checks, including for things that were checked before, others that could be avoided entirely. Please take a look at the comments.
from ansible_collections.community.general.plugins.module_utils.version import ( | ||
LooseVersion, | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Simpler as:
from ansible_collections.community.general.plugins.module_utils.version import ( | |
LooseVersion, | |
) | |
from ansible_collections.community.general.plugins.module_utils.version import LooseVersion |
self.rule_usernames = ( | ||
self._string_to_set(rule_usernames) if rule_usernames is not None else [] | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It might be a matter of personal preference, but I find this abundance of brackets harder to read than without them. Why not just:
self.rule_usernames = ( | |
self._string_to_set(rule_usernames) if rule_usernames is not None else [] | |
) | |
self.rule_usernames = self._string_to_set(rule_usernames) if rule_usernames is not None else [] |
if not gmmr.rule_exists: | ||
if module.params["state"] == "absent": | ||
module.exit_json( | ||
changed=False, | ||
msg="Merge Request Rule ({}) does not exist for {}, no changes made.".format( | ||
module.params["rule_name"], module.params["project_name"] | ||
), | ||
) | ||
|
||
elif module.params["state"] == "present": | ||
gmmr.create_approval_rule() | ||
gmmr.rules = gmmr.list_approval_rules() | ||
gmmr.rule_exists, new_mmr = gmmr.check_rule_exists(gmmr.rule_name) | ||
module.exit_json( | ||
changed=True, | ||
msg="Merge Request Rule ({}) has been successfully created.".format( | ||
module.params["rule_name"] | ||
), | ||
merge_request_rule=new_mmr.asdict(), | ||
) | ||
|
||
elif gmmr.rule_exists: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need for this to be an elif
, it could be a plain else
. That being said, I would place the if gmmr.rule_exists
block first, then the "not exists", as else
second, for the sake of readability.
project_name=dict(type="str", required=True), | ||
rule_name=dict(type="str", required=True), | ||
approvals_required=dict(type="int", required=True), | ||
usernames=dict(type="list", elements="str", default=None, required=False), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The required=false
is redundant, here and in other parameters below.
As of the default, None
is redundant (is already going to be None
if not passed). However, the first thing the code does with that value, inside the GitlabMergeRequestRule
is to check whether it is None
and then transform it to a list. Therefore, I would recommend making default=[]
here and removing those verifications from the class. That might apply to other parameters as well.
usernames=dict(type="list", elements="str", default=None, required=False), | |
usernames=dict(type="list", elements="str", default=[]), |
else [] | ||
) | ||
self.rule_usernames = ( | ||
self._string_to_set(rule_usernames) if rule_usernames is not None else [] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I understand it is going to work as-is, but... the fact that this can be either a set or a list does not help the readability of this code.
self._string_to_set(rule_usernames) if rule_usernames is not None else [] | |
self._string_to_set(rule_usernames) if rule_usernames is not None else set() |
rule_approvals_required=0, | ||
rule_groups=None, | ||
rule_user_ids=None, | ||
rule_usernames=None, | ||
rule_branches=None, | ||
rule_all_protected_branches=False, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This class is not used outside this module, and the only one place that creates a new instance provides all the parameters. The default values in this constructor are redundant.
rule_approvals_required=0, | |
rule_groups=None, | |
rule_user_ids=None, | |
rule_usernames=None, | |
rule_branches=None, | |
rule_all_protected_branches=False, | |
rule_approvals_required, | |
rule_groups, | |
rule_user_ids, | |
rule_usernames, | |
rule_branches, | |
rule_all_protected_branches, |
_protected_branch_ids = ( | ||
list(self.rule_branches) if self.rule_branches is not None else [] | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This (probably the lines below as well) are overkill: the code already guarantees that self.rule_branches
is not going to be None
, in lines 167-171.
Hey thank you. I will take a look over the comments and adjust when I get a moment. At least with the comment on the extra brackets, I had wrote it the way you suggested. However my editors formatter altered it to the way it is. Assuming due to line length. |
You probably have some auto-formatting enabled in your editor (the extra brackets are something that black or ruff tend to insert to shorten long lines). It's probably best to disable the formatter. |
PIng @mil1i |
SUMMARY
Adding a new Gitlab module named
gitlab_merge_request_rule
. This is for managing (creating, updating and deleting) merge request rules for those with Gitlab Enterprise/Ultimate.It can take in a group name or id, as well as usernames or user id, perform the lookup (assumes the authenticated token/user has the proper access) to properly generate the request.
Has failure messages builtin for unable to find a user or a group. If the specified protected branch is not found, it defaults back to "All Branches".
If
applies_to_all_protected_branches
option is set totrue
it ignoresprotected_branch
if set.This should idempotently detect changes (additions or removals) for all settings.
Could probably use some additional tweaking to reduce complexity ;d but threw this together quickly for work, thought I should share it back.
ISSUE TYPE
COMPONENT NAME
gitlab_merge_request_rule
ADDITIONAL INFORMATION
Example task: