-
Notifications
You must be signed in to change notification settings - Fork 502
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
Support merge request level approval rules to set required approvals #2794 #3014
base: main
Are you sure you want to change the base?
Support merge request level approval rules to set required approvals #2794 #3014
Conversation
42e72d3
to
d2c7bd7
Compare
@@ -44,6 +46,21 @@ object Cli { | |||
val processTimeout = "process-timeout" | |||
} | |||
|
|||
implicit val mergeRequestApprovalsConfigArgument: Argument[MergeRequestApprovalRulesCfg] = | |||
Argument.from("approvals_rule_name=required_approvals") { s => | |||
s.split(":").toList match { |
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 split with :
but I can switch to =
like we do in env variables. I don't have any preferences.
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.
=
makes more sense I guess so I changed it already.
final case class GitLabCfg( | ||
mergeWhenPipelineSucceeds: Boolean, | ||
requiredReviewers: Option[Int], | ||
requiredApprovals: Option[Either[Int, Nel[MergeRequestApprovalRulesCfg]]], |
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.
Here is how to read this;
Left side the old flow, user just provides the old configuration via --gitlab-required-reviewers <integer>
Right side is the new flow, user provides the new configuration via --merge-request-level-approval-rule <approvals_rule_name=required_approvals>
I also renamed the name of this variable. It's not reviewers, it's actually approvals.
I can wrap left side to a value class. It might be more explanatory then just Int. WDYT?
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.
@endertunc I'd suggest a gitlab-
prefix for this new config param perhaps, for consistency?
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.
Make sense I will add the prefix 👍
setApprovalRules(repo, mrWithStatus, approvalRules) | ||
case Some(Left(requiredReviewers)) => | ||
setReviewers(repo, mrWithStatus, requiredReviewers) | ||
case None => F.unit |
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.
Here we call one flow or the other depending on the configuration provided.
Codecov ReportPatch coverage:
Additional details and impacted files@@ Coverage Diff @@
## main #3014 +/- ##
==========================================
- Coverage 91.09% 91.08% -0.02%
==========================================
Files 160 160
Lines 3336 3387 +51
Branches 303 313 +10
==========================================
+ Hits 3039 3085 +46
- Misses 297 302 +5
Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here. ☔ View full report in Codecov by Sentry. |
I will cover the missing lines reported by Codecov. |
38ec23d
to
8766c3b
Compare
I added missing test cases related to the changes in this pull request. |
@fthomas just following up on this one. Do you think this is worth merging? As described in the ticket, implementation in main depends on deprecated API. However, I am not sure if there is enough interest from your side or community to have this PR merged. I liked working on the issue. I learnt few things from the code base and I also learned few things from Gitlab API so I overall it was a nice experience for me and I wouldn't want to push forward if there is no interest. We can keep it around for a while and see if people show any interest. If you wish to close the PR now without merging it I am also fine with it :) |
@@ -80,6 +80,8 @@ Options and flags: | |||
Whether to merge a gitlab merge request when the pipeline succeeds | |||
--gitlab-required-reviewers <integer> | |||
When set, the number of required reviewers for a merge request will be set to this number (non-negative integer). Is only used in the context of gitlab-merge-when-pipeline-succeeds being enabled, and requires that the configured access token have the appropriate privileges. Also requires a Gitlab Premium subscription. | |||
--merge-request-level-approval-rule <approvals_rule_name=required_approvals> | |||
Additional repo config file (can be used multiple times) |
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.
Is this description of the flag accurate?
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 it's not :) I will update it 👍
for { | ||
_ <- logger.info( | ||
s"Setting number of required reviewers on ${mrOut.webUrl} to $requiredReviewers" | ||
private def setReviewers( |
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 worth adding a comment here reminding readers that this is retained only for Gitlab versions older than... 12.3 I think?
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 think we should diffidently mention it in the description of the flag that enable this behavior. I wouldn't mind mentioning it here as well.
val params = minimumRequiredParams ++ List( | ||
List("--gitlab-merge-when-pipeline-succeeds"), | ||
List("--gitlab-remove-source-branch"), |
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.
Is this a drive-by? Or a bad merge with main?
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 think there were some missing test cases (config flags in this case) so I think I just did a bit of improvement here if I remember correctly.
I came here to do this work so that we can have approvers set by SS on Gitlab and was happy to find your MR @endertunc - I've thrown in a few review comments, hopefully that's a help. It'd be really great to have this after that @fthomas 🙏🏻 . Happy to help in any way I can. |
Resolves #2794
Gitlab introduced what they call
Merge Request Level Approval Rules
which you can define on repo level whcih would apply to all matching merge request and can be adjusted per merge request. You can read more about it here: https://docs.gitlab.com/ee/user/project/merge_requests/approvals/rules.htmlTechnical details
Here is an example merge request approval rules defined on project level (see https://docs.gitlab.com/ee/api/merge_request_approvals.html#get-project-level-rules);
And this is how it would like on Gitlab Merge Request Settings UI;
When a merge request created in said project matching approval rules will be added to merge request level approval rules. Given the fact that two rules defined above don't target any special branch, they will be applied to all branches. Here is an example of merge request level rules with above two rules attached automatically (see https://docs.gitlab.com/ee/api/merge_request_approvals.html#get-merge-request-level-rules);
And this is how it would like on Gitlab Merge Request UI;
With the new flow, we can not say that we want only one approval in this merge request anymore. Instead, we need to specify this behavior on merge request level approval rules individually. Let's say we don't want any approvals for Scala Steward merge request, then we need to set approvals_required to 0 in all the defined merge request level approval rules.
Here is what I did to support the new flow
I added configuration option in following format
--merge-request-level-approval-rule MERGE_REQUEST_LEVEL_APPROVAL_RULE_NAME:REQUIRED_APPROVALS
. For example,--merge-request-level-approval-rule scala-steward:0 --merge-request-level-approval-rule All Members:0
.Query to merge request level rules to list all the active merge request level rules attached to this merge request
Combine the configuration provided by user with the information retrieved from the API to decide what merge request level rules to update and then update the merge request level rules with configuration given by user.
Notes
As you might already realize, we match/find merge request level rules by it's name. This is due to the fact that merge request level approval rules doesn't reference to original rule by it's id. The only connection is the name therefore we request name of the approval rule from user. I guess this is somewhat user-friendly since they don't need to deal with ids.
There is one default-can-not-be-deleted approval rule which is called - hmm I don't know actually, because in UI it's called
All eligible users
however in API it's calledAll Members
. Users who wish to update this rule has to configureAll Members
rather thanAll eligible users
. I guess we need to document it somewhere.I am still trying to test this manually on our company Gitlab but I am having some permissions on our Gitlab instance. I will let you know once I manage to test this manually as well.