Filter approval rule approvers individually

What does this MR do and why?

Merge request approval policies support enforcing stricter approval settings through their approval_settings.prevent_approval_by_{commit_}author properties. A merge request approval rule originating from an approval policy that sets one of these attributes hence permits less approvers, because it excludes the author or committers. Likewise, a merge request approval rule originating from a policy that doesn't set these attributes should permit more approvers (assuming the target project permits author/committer approval).

Currently, approvers are filtered for author and committers globally for all rules in ApprovalState#filter_approvers. However this means that if there are two policy approval rules, and only one of them sets eg. prevent_approval_by_author, then the author gets filtered out as eligible approver for both rules, despite only one of the rules setting the property.

This merge request moves the filtering logic from ApprovalState into ApprovalWrappedRule, so that approvers are filtered depending on individual approval rules, not their aggregate.

References

Screenshots or screen recordings

Before After
approvals_before approvals_after

How to set up and validate locally

  1. Enable the feature flag: echo "Feature.enable(:approval_policy_rules_individual_approvers_filtering)" | rails c

  2. Create a new project (as Owner user)

  3. Add two Maintainers to the project: Author, Committer

  4. Navigate to Secure > Policies and create the following Merge request approval policies:

    approval_policy:
      - name: Committer approval prevented
        enabled: true
        rules:
          - type: any_merge_request
            branch_type: protected
            commits: any
        actions:
          - type: require_approval
            approvals_required: 1
            role_approvers:
              - maintainer
              - owner
          - type: send_bot_message
            enabled: true
        approval_settings:
          prevent_approval_by_commit_author: true
    approval_policy:
      - name: Author approval prevented
        enabled: true
        rules:
          - type: any_merge_request
            branch_type: protected
            commits: any
        actions:
          - type: require_approval
            approvals_required: 1
            role_approvers:
              - maintainer
              - owner
          - type: send_bot_message
            enabled: true
        approval_settings:
          prevent_approval_by_author: true
    approval_policy:
      - name: Any Owner or Maintainer
        enabled: true
        rules:
          - type: any_merge_request
            branch_type: protected
            commits: any
        actions:
          - type: require_approval
            approvals_required: 1
            role_approvers:
              - maintainer
              - owner
          - type: send_bot_message
            enabled: true
  5. Open an MR using Author targeting the default branch

  6. Add a commit to the MR source branch with Committer

  7. Verify that the following rule/users combinations are approvable:

    Owner Committer Author
    Committer approval prevented yes
    Author approval prevented yes yes
    Any Owner or Maintainer yes yes
  8. Navigate to Settings > Merge requests, uncheck Prevent approval by merge request creator and Save changes

  9. Verify that the following rule/users combinations are approvable:

    Owner Committer Author
    Committer approval prevented yes
    Author approval prevented yes yes
    Any Owner or Maintainer yes yes yes
  10. Navigate to Settings > Merge requests, check Prevent approvals by users who add commits and Save changes

  11. Verify that the following rule/users combinations are approvable:

    Owner Committer Author
    Committer approval prevented yes
    Author approval prevented yes
    Any Owner or Maintainer yes
  12. Navigate to Settings > Merge requests, uncheck Prevent approvals by users who add commits and Save changes

  13. As administrator, navigate to Admin > Push rules and under Merge request approvals, check Prevent approval by merge request creators and Save changes

  14. Verify that the following rule/users combinations are approvable:

    Owner Committer Author
    Committer approval prevented yes
    Author approval prevented yes yes
    Any Owner or Maintainer yes yes
  15. As administrator, navigate to Admin > Push rules and under Merge request approvals, uncheck Prevent approval by merge request creators and Save changes

  16. Approve as Committer and verify the MR approval state:

    • Committer approval prevented: unapproved
    • Author approval prevented: approved
    • Any Owner or Maintainer: approved
    • Mergeable: no
  17. Revoke the prior approval, then approve as Author and verify the MR approval state:

    • Committer approval prevented: unapproved
    • Author approval prevented: unapproved
    • Any Owner or Maintainer: approved
    • Mergeable: no
  18. Revoke the prior approval, then approve as Owner and verify the MR approval state:

    • Committer approval prevented: approved
    • Author approval prevented: approved
    • Any Owner or Maintainer: approved
    • Mergeable: yes

MR acceptance checklist

Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.

Related to #574854 (closed)

Edited by Dominic Bauer

Merge request reports

Loading