Merge request approval policy applies to all branches if a target protected branch does not exist in a project
Summary
Merge request approval policy applies to all branches if a target protected branch does not exist.
Steps to reproduce
- Create a group
- Create a group level protected branch (
feature
) from Group -> Settings -> Repository -> Protected Branches - Add the following policy below to that group (Secure -> Policies -> New Policy -> Merge request approval policy)
--- scan_result_policy: - name: Policy test description: '' enabled: true actions: - type: require_approval approvals_required: 2 role_approvers: - maintainer - owner rules: - type: any_merge_request commits: any branches: - feature approval_settings: block_branch_modification: true prevent_pushing_and_force_pushing: true prevent_approval_by_author: true prevent_approval_by_commit_author: true remove_approvals_with_new_commit: true require_password_to_approve: false policy_scope: compliance_frameworks: []
- Create a project within the group
- Create 2 more non-protected branches. (Let's call them
new-branch-1
andnew-branch-2
) - Make some changes on
new-branch-2
. For example, adding a new line in a README file. - Create an a MR with
new-branch-2
as the source branch, and ``new-branch-1` as the target branch. - Observe that 2 approvals is required before the MR can be merged.
What is the current bug behavior?
Merge request approval policy applies to all branches (including non-protected) if a target protected branch does not exist
What is the expected correct behavior?
Merge request approval policy should not affect non-protected branches, in any situation, as Merge request approval policies only apply to Protected Branches as this time.
Relevant logs and/or screenshots
Output of checks
Results of GitLab environment info
Expand for output related to GitLab environment info
``` # sudo gitlab-rake gitlab:env:info System information System: Ubuntu 22.04 Proxy: no Current User: git Using RVM: no Ruby Version: 3.1.4p223 Gem Version: 3.4.22 Bundler Version:2.5.4 Rake Version: 13.0.6 Redis Version: 7.0.15 Sidekiq Version:7.1.6 Go Version: unknown GitLab information Version: 16.8.2-ee Revision: e3c23d67e9c Directory: /opt/gitlab/embedded/service/gitlab-rails DB Adapter: PostgreSQL DB Version: 14.10 URL: https://1.k.git2.cyou HTTP Clone URL: https://1.k.git2.cyou/some-group/some-project.git SSH Clone URL: git@1.k.git2.cyou:some-group/some-project.git Elasticsearch: no Geo: no Using LDAP: no Using Omniauth: yes Omniauth Providers: GitLab Shell Version: 14.33.0 Repository storages: - default: unix:/var/opt/gitlab/gitaly/gitaly.socket GitLab Shell path: /opt/gitlab/embedded/service/gitlab-shell Gitaly - default Address: unix:/var/opt/gitlab/gitaly/gitaly.socket - default Version: 16.8.2 - default Git Version: 2.42.0 ```
Results of GitLab application Check
Expand for output related to the GitLab application check
# sudo gitlab-rake gitlab:check SANITIZE=true Checking GitLab subtasks ... Checking GitLab Shell ... GitLab Shell: ... GitLab Shell version >= 14.33.0 ? ... OK (14.33.0) Running /opt/gitlab/embedded/service/gitlab-shell/bin/check Internal API available: OK Redis available via internal API: OK gitlab-shell self-check successful Checking GitLab Shell ... Finished Checking Gitaly ... Gitaly: ... default ... OK Checking Gitaly ... Finished Checking Sidekiq ... Sidekiq: ... Running? ... yes Number of Sidekiq processes (cluster/worker) ... 1/1 Checking Sidekiq ... Finished Checking Incoming Email ... Incoming Email: ... Reply by email is disabled in config/gitlab.yml Checking Incoming Email ... Finished Checking LDAP ... LDAP: ... LDAP is disabled in config/gitlab.yml Checking LDAP ... Finished Checking GitLab App ... Database config exists? ... yes Tables are truncated? ... skipped All migrations up? ... yes Database contains orphaned GroupMembers? ... no GitLab config exists? ... yes GitLab config up to date? ... yes Cable config exists? ... yes Resque config exists? ... yes Log directory writable? ... yes Tmp directory writable? ... yes Uploads directory exists? ... yes Uploads directory has correct permissions? ... yes Uploads directory tmp has correct permissions? ... skipped (no tmp uploads folder yet) Systemd unit files or init script exist? ... skipped (omnibus-gitlab has neither init script nor systemd units) Systemd unit files or init script up-to-date? ... skipped (omnibus-gitlab has neither init script nor systemd units) Projects have namespace: ... 1/1 ... yes 9/2 ... yes 13/3 ... yes 1/4 ... yes 8/5 ... yes 1/6 ... yes 1/7 ... yes 1/8 ... yes 1/9 ... yes 1/10 ... yes 25/12 ... yes 25/13 ... yes 1/14 ... yes 1/15 ... yes 1/16 ... yes 1/17 ... yes 1/18 ... yes 1/19 ... yes 1/20 ... yes 36/21 ... yes 36/22 ... yes Redis version >= 6.0.0? ... yes Ruby version >= 3.0.6 ? ... yes (3.1.4) Git user has default SSH configuration? ... yes Active users: ... 4 Is authorized keys file accessible? ... yes GitLab configured to store new projects in hashed storage? ... yes All projects are in hashed storage? ... yes Elasticsearch version 7.x-8.x or OpenSearch version 1.x ... skipped (Advanced Search is disabled) All migrations must be finished before doing a major upgrade ... skipped (Advanced Search is disabled) Checking GitLab App ... Finished Checking GitLab subtasks ... Finished
Workaround
Create the Protected Branches in the project.
Possible fixes
My guess is that the buggy behaviour occurs around here in the codebase, where it expects to find a matching protected branch rule in the project, but instead we end up with an empty array, so it maybe ends up applying the rule on all branches?
Verification Steps
- Create a top level group and enable
allow_protected_branches_for_group
feature flag - Create a group level protected branch (
feature
) from Group -> Settings -> Repository -> Protected Branches - Add the following policy below to that group (Secure -> Policies -> New Policy -> Merge request approval policy)
Policy
```yaml
---
scan_result_policy:
- name: Policy test
description: ''
enabled: true
actions:
- type: require_approval
approvals_required: 2
role_approvers:
- maintainer
- owner
rules:
- type: any_merge_request
commits: any
branches:
- feature
approval_settings:
block_branch_modification: true
prevent_pushing_and_force_pushing: true
prevent_approval_by_author: true
prevent_approval_by_commit_author: true
remove_approvals_with_new_commit: true
require_password_to_approve: false
policy_scope:
compliance_frameworks: []
```
- Create a project within the group
- Create 2 more non-protected branches. (Let's call them
new-branch-1
andnew-branch-2
) - Make some changes on
new-branch-2
. For example, adding a new line in a README file. - Create an a MR with
new-branch-2
as the source branch, and ``new-branch-1` as the target branch. - Observe that approvals are not required
Edited by Sashi Kumar Kumaresan