From 6f8c9c76ff96a34f978a213e7622c26b12a19f6a Mon Sep 17 00:00:00 2001 From: Sashi Kumar Kumaresan Date: Thu, 12 Jun 2025 00:05:14 +0200 Subject: [PATCH 1/7] Add bypass_settings to MR approval policy This change adds bypass_settings to security policy schema and updates the branch exceptions to be configured at the policy level. EE: true Changelog: added --- .../models/security/approval_policy_rule.rb | 14 +- .../json_schemas/approval_policy_content.json | 37 +- .../security_orchestration_policy.json | 354 ++++++++++-------- 3 files changed, 237 insertions(+), 168 deletions(-) diff --git a/ee/app/models/security/approval_policy_rule.rb b/ee/app/models/security/approval_policy_rule.rb index 0f442ccd9b8192..a8a82ff48db68c 100644 --- a/ee/app/models/security/approval_policy_rule.rb +++ b/ee/app/models/security/approval_policy_rule.rb @@ -46,12 +46,12 @@ def license_types def branches_exempted_by_policy?(source_branch, target_branch) return false unless Feature.enabled?(:approval_policy_branch_exceptions, security_policy_management_project) - branch_exceptions = typed_content['branch_exceptions'] + branch_exceptions = security_policy.policy_content.dig(:bypass_settings, :branches) return false if branch_exceptions.blank? branch_exceptions.any? do |branch_exception| - source_branch_exception = branch_exception['source'] - target_branch_exception = branch_exception['target'] + source_branch_exception = branch_exception[:source] + target_branch_exception = branch_exception[:target] branch_matches_exception?(source_branch, source_branch_exception) && branch_matches_exception?(target_branch, target_branch_exception) @@ -61,10 +61,10 @@ def branches_exempted_by_policy?(source_branch, target_branch) private def branch_matches_exception?(branch, exception) - if exception['name'].present? - branch == exception['name'] - elsif exception['pattern'].present? - RefMatcher.new(exception['pattern']).matches?(branch) + if exception[:name].present? + branch == exception[:name] + elsif exception[:pattern].present? + RefMatcher.new(exception[:pattern]).matches?(branch) end end end diff --git a/ee/app/validators/json_schemas/approval_policy_content.json b/ee/app/validators/json_schemas/approval_policy_content.json index cdf74e6b8a4a99..6ef5c8e204926f 100644 --- a/ee/app/validators/json_schemas/approval_policy_content.json +++ b/ee/app/validators/json_schemas/approval_policy_content.json @@ -230,7 +230,42 @@ ] } } + }, + "bypass_settings": { + "type": "object", + "properties": { + "branches": { + "type": "array", + "items": { + "type": "object", + "properties": { + "source": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "pattern": { + "type": "string" + } + } + }, + "target": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "pattern": { + "type": "string" + } + } + } + } + } + } + } } }, "additionalProperties": false -} +} \ No newline at end of file diff --git a/ee/app/validators/json_schemas/security_orchestration_policy.json b/ee/app/validators/json_schemas/security_orchestration_policy.json index 42e56724433858..d67ffb3294c0b4 100644 --- a/ee/app/validators/json_schemas/security_orchestration_policy.json +++ b/ee/app/validators/json_schemas/security_orchestration_policy.json @@ -1628,192 +1628,226 @@ ] } } - } - }, - "additionalProperties": false - } - } - }, - "additionalProperties": false, - "$defs": { - "policy_scope": { - "type": "object", - "properties": { - "compliance_frameworks": { - "description": "Specifies for which compliance frameworks this policy should be applied to.", - "type": "array", - "items": { + }, + "bypass_settings": { "type": "object", "properties": { - "id": { - "type": "integer" - } - } - } - }, - "projects": { - "type": "object", - "description": "Specifies for which projects this policy should be applied to.", - "properties": { - "including": { - "type": "array", - "description": "Specifies projects where this policy should be applied to.", - "items": { - "type": "object", - "properties": { - "id": { - "type": "integer", - "description": "Specifies the ID of the project." + "branches": { + "type": "array", + "items": { + "type": "object", + "properties": { + "source": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "pattern": { + "type": "string" + } + } + }, + "target": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "pattern": { + "type": "string" + } + } + } } } } - }, - "excluding": { - "type": "array", - "description": "Specifies projects where this policy should not be applied to.", - "items": { - "type": "object", - "properties": { - "id": { - "type": "integer", - "description": "Specifies the ID of the project." - } + } + }, + "additionalProperties": false + } + } + }, + "additionalProperties": false, + "$defs": { + "policy_scope": { + "type": "object", + "properties": { + "compliance_frameworks": { + "description": "Specifies for which compliance frameworks this policy should be applied to.", + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "integer" } } } - } - }, - "groups": { - "type": "object", - "description": "Specifies for which groups this policy should be applied to.", - "properties": { - "including": { - "type": "array", - "description": "Specifies groups where this policy should be applied to.", - "items": { - "type": "object", - "properties": { - "id": { - "type": "integer", - "description": "Specifies the ID of the group." + }, + "projects": { + "type": "object", + "description": "Specifies for which projects this policy should be applied to.", + "properties": { + "including": { + "type": "array", + "description": "Specifies projects where this policy should be applied to.", + "items": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "description": "Specifies the ID of the project." + } } } - } - }, - "excluding": { - "type": "array", - "description": "Specifies groups where this policy should not be applied to.", - "items": { - "type": "object", - "properties": { - "id": { - "type": "integer", - "description": "Specifies the ID of the group." + }, + "excluding": { + "type": "array", + "description": "Specifies projects where this policy should not be applied to.", + "items": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "description": "Specifies the ID of the project." + } } } } } - } - } - } - }, - "pipeline_execution_content": { - "description": "Specifies the content of custom configuration.", - "type": "object", - "properties": { - "include": { - "type": "array", - "maxItems": 1, - "minItems": 1, - "items": { + }, + "groups": { "type": "object", + "description": "Specifies for which groups this policy should be applied to.", "properties": { - "project": { - "type": "string" - }, - "file": { - "type": "string" + "including": { + "type": "array", + "description": "Specifies groups where this policy should be applied to.", + "items": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "description": "Specifies the ID of the group." + } + } + } }, - "ref": { - "type": "string" + "excluding": { + "type": "array", + "description": "Specifies groups where this policy should not be applied to.", + "items": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "description": "Specifies the ID of the group." + } + } + } } - }, - "required": [ - "project", - "file" - ], - "additionalProperties": false + } } } }, - "required": [ - "include" - ], - "additionalProperties": false - }, - "metadata": { - "description": "Specifies custom annotations in a form of key-value pairs.", - "type": "object", - "patternProperties": { - "^[a-zA-Z$][\\w$]*$": { - "type": [ - "string", - "number", - "boolean" - ] - } - }, - "additionalProperties": false - }, - "licenses_with_package_exclusions": { - "type": "array", - "minItems": 1, - "maxItems": 1000, - "uniqueItems": true, - "additionalItems": false, - "items": { + "pipeline_execution_content": { + "description": "Specifies the content of custom configuration.", "type": "object", "properties": { - "name": { - "type": "string", - "minLength": 1, - "maxLength": 255 - }, - "packages": { - "type": "object", - "additionalProperties": false, - "properties": { - "excluding": { - "type": "object", - "additionalProperties": false, - "properties": { - "purls": { - "type": "array", - "minItems": 1, - "maxItems": 1000, - "additionalItems": false, - "items": { - "minLength": 1, - "maxLength": 1024, - "type": "string", - "format": "uri" - } - } + "include": { + "type": "array", + "maxItems": 1, + "minItems": 1, + "items": { + "type": "object", + "properties": { + "project": { + "type": "string" }, - "required": [ - "purls" - ] - } - }, - "required": [ - "excluding" - ] + "file": { + "type": "string" + }, + "ref": { + "type": "string" + } + }, + "required": [ + "project", + "file" + ], + "additionalProperties": false + } } }, "required": [ - "name" - ] + "include" + ], + "additionalProperties": false + }, + "metadata": { + "description": "Specifies custom annotations in a form of key-value pairs.", + "type": "object", + "patternProperties": { + "^[a-zA-Z$][\\w$]*$": { + "type": [ + "string", + "number", + "boolean" + ] + } + }, + "additionalProperties": false + }, + "licenses_with_package_exclusions": { + "type": "array", + "minItems": 1, + "maxItems": 1000, + "uniqueItems": true, + "additionalItems": false, + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "minLength": 1, + "maxLength": 255 + }, + "packages": { + "type": "object", + "additionalProperties": false, + "properties": { + "excluding": { + "type": "object", + "additionalProperties": false, + "properties": { + "purls": { + "type": "array", + "minItems": 1, + "maxItems": 1000, + "additionalItems": false, + "items": { + "minLength": 1, + "maxLength": 1024, + "type": "string", + "format": "uri" + } + } + }, + "required": [ + "purls" + ] + } + }, + "required": [ + "excluding" + ] + } + }, + "required": [ + "name" + ] + } } } - } -} + } \ No newline at end of file -- GitLab From 6d1ea4a9efcf3b94fb7595f6a5d04738ceb8c15a Mon Sep 17 00:00:00 2001 From: Sashi Kumar Kumaresan Date: Thu, 12 Jun 2025 00:08:42 +0200 Subject: [PATCH 2/7] Fix json schemas --- ee/app/validators/json_schemas/approval_policy_content.json | 2 +- .../validators/json_schemas/security_orchestration_policy.json | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/ee/app/validators/json_schemas/approval_policy_content.json b/ee/app/validators/json_schemas/approval_policy_content.json index 6ef5c8e204926f..ff268bdf6a9486 100644 --- a/ee/app/validators/json_schemas/approval_policy_content.json +++ b/ee/app/validators/json_schemas/approval_policy_content.json @@ -268,4 +268,4 @@ } }, "additionalProperties": false -} \ No newline at end of file +} diff --git a/ee/app/validators/json_schemas/security_orchestration_policy.json b/ee/app/validators/json_schemas/security_orchestration_policy.json index d67ffb3294c0b4..82b6696a96bdc1 100644 --- a/ee/app/validators/json_schemas/security_orchestration_policy.json +++ b/ee/app/validators/json_schemas/security_orchestration_policy.json @@ -1850,4 +1850,5 @@ } } } - } \ No newline at end of file + } +} -- GitLab From 221dfb3d986b118a16c07852034bdd9f4378549f Mon Sep 17 00:00:00 2001 From: Sashi Kumar Kumaresan Date: Wed, 18 Jun 2025 21:38:04 +0200 Subject: [PATCH 3/7] Update policy schema JSON --- .../approval_policy_rule_content.json | 38 +- .../security_orchestration_policy.json | 388 +++++++++--------- 2 files changed, 193 insertions(+), 233 deletions(-) diff --git a/ee/app/validators/json_schemas/approval_policy_rule_content.json b/ee/app/validators/json_schemas/approval_policy_rule_content.json index 7eaed3cb79843d..42e8f22f22f9cf 100644 --- a/ee/app/validators/json_schemas/approval_policy_rule_content.json +++ b/ee/app/validators/json_schemas/approval_policy_rule_content.json @@ -49,43 +49,11 @@ "full_path": { "type": "string", "minLength": 1 - }, - "source": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "pattern": { - "type": "string" - } - } - }, - "target": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "pattern": { - "type": "string" - } - } } }, - "oneOf": [ - { - "required": [ - "name", - "full_path" - ] - }, - { - "required": [ - "source", - "target" - ] - } + "required": [ + "name", + "full_path" ] } ] diff --git a/ee/app/validators/json_schemas/security_orchestration_policy.json b/ee/app/validators/json_schemas/security_orchestration_policy.json index 82b6696a96bdc1..25dadd9e09a33b 100644 --- a/ee/app/validators/json_schemas/security_orchestration_policy.json +++ b/ee/app/validators/json_schemas/security_orchestration_policy.json @@ -1145,43 +1145,11 @@ "full_path": { "type": "string", "minLength": 1 - }, - "source": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "pattern": { - "type": "string" - } - } - }, - "target": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "pattern": { - "type": "string" - } - } } }, - "oneOf": [ - { - "required": [ - "name", - "full_path" - ] - }, - { - "required": [ - "source", - "target" - ] - } + "required": [ + "name", + "full_path" ] } ] @@ -1646,7 +1614,19 @@ "pattern": { "type": "string" } - } + }, + "oneOf": [ + { + "required": [ + "name" + ] + }, + { + "required": [ + "pattern" + ] + } + ] }, "target": { "type": "object", @@ -1657,197 +1637,209 @@ "pattern": { "type": "string" } - } + }, + "oneOf": [ + { + "required": [ + "name" + ] + }, + { + "required": [ + "pattern" + ] + } + ] } } } } } - }, - "additionalProperties": false - } + } + }, + "additionalProperties": false } - }, - "additionalProperties": false, - "$defs": { - "policy_scope": { - "type": "object", - "properties": { - "compliance_frameworks": { - "description": "Specifies for which compliance frameworks this policy should be applied to.", - "type": "array", - "items": { - "type": "object", - "properties": { - "id": { - "type": "integer" - } - } - } - }, - "projects": { + } + }, + "additionalProperties": false, + "$defs": { + "policy_scope": { + "type": "object", + "properties": { + "compliance_frameworks": { + "description": "Specifies for which compliance frameworks this policy should be applied to.", + "type": "array", + "items": { "type": "object", - "description": "Specifies for which projects this policy should be applied to.", "properties": { - "including": { - "type": "array", - "description": "Specifies projects where this policy should be applied to.", - "items": { - "type": "object", - "properties": { - "id": { - "type": "integer", - "description": "Specifies the ID of the project." - } + "id": { + "type": "integer" + } + } + } + }, + "projects": { + "type": "object", + "description": "Specifies for which projects this policy should be applied to.", + "properties": { + "including": { + "type": "array", + "description": "Specifies projects where this policy should be applied to.", + "items": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "description": "Specifies the ID of the project." } } - }, - "excluding": { - "type": "array", - "description": "Specifies projects where this policy should not be applied to.", - "items": { - "type": "object", - "properties": { - "id": { - "type": "integer", - "description": "Specifies the ID of the project." - } + } + }, + "excluding": { + "type": "array", + "description": "Specifies projects where this policy should not be applied to.", + "items": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "description": "Specifies the ID of the project." } } } } - }, - "groups": { - "type": "object", - "description": "Specifies for which groups this policy should be applied to.", - "properties": { - "including": { - "type": "array", - "description": "Specifies groups where this policy should be applied to.", - "items": { - "type": "object", - "properties": { - "id": { - "type": "integer", - "description": "Specifies the ID of the group." - } + } + }, + "groups": { + "type": "object", + "description": "Specifies for which groups this policy should be applied to.", + "properties": { + "including": { + "type": "array", + "description": "Specifies groups where this policy should be applied to.", + "items": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "description": "Specifies the ID of the group." } } - }, - "excluding": { - "type": "array", - "description": "Specifies groups where this policy should not be applied to.", - "items": { - "type": "object", - "properties": { - "id": { - "type": "integer", - "description": "Specifies the ID of the group." - } + } + }, + "excluding": { + "type": "array", + "description": "Specifies groups where this policy should not be applied to.", + "items": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "description": "Specifies the ID of the group." } } } } } } - }, - "pipeline_execution_content": { - "description": "Specifies the content of custom configuration.", - "type": "object", - "properties": { - "include": { - "type": "array", - "maxItems": 1, - "minItems": 1, - "items": { - "type": "object", - "properties": { - "project": { - "type": "string" - }, - "file": { - "type": "string" - }, - "ref": { - "type": "string" - } + } + }, + "pipeline_execution_content": { + "description": "Specifies the content of custom configuration.", + "type": "object", + "properties": { + "include": { + "type": "array", + "maxItems": 1, + "minItems": 1, + "items": { + "type": "object", + "properties": { + "project": { + "type": "string" }, - "required": [ - "project", - "file" - ], - "additionalProperties": false - } + "file": { + "type": "string" + }, + "ref": { + "type": "string" + } + }, + "required": [ + "project", + "file" + ], + "additionalProperties": false } - }, - "required": [ - "include" - ], - "additionalProperties": false + } }, - "metadata": { - "description": "Specifies custom annotations in a form of key-value pairs.", + "required": [ + "include" + ], + "additionalProperties": false + }, + "metadata": { + "description": "Specifies custom annotations in a form of key-value pairs.", + "type": "object", + "patternProperties": { + "^[a-zA-Z$][\\w$]*$": { + "type": [ + "string", + "number", + "boolean" + ] + } + }, + "additionalProperties": false + }, + "licenses_with_package_exclusions": { + "type": "array", + "minItems": 1, + "maxItems": 1000, + "uniqueItems": true, + "additionalItems": false, + "items": { "type": "object", - "patternProperties": { - "^[a-zA-Z$][\\w$]*$": { - "type": [ - "string", - "number", - "boolean" + "properties": { + "name": { + "type": "string", + "minLength": 1, + "maxLength": 255 + }, + "packages": { + "type": "object", + "additionalProperties": false, + "properties": { + "excluding": { + "type": "object", + "additionalProperties": false, + "properties": { + "purls": { + "type": "array", + "minItems": 1, + "maxItems": 1000, + "additionalItems": false, + "items": { + "minLength": 1, + "maxLength": 1024, + "type": "string", + "format": "uri" + } + } + }, + "required": [ + "purls" + ] + } + }, + "required": [ + "excluding" ] } }, - "additionalProperties": false - }, - "licenses_with_package_exclusions": { - "type": "array", - "minItems": 1, - "maxItems": 1000, - "uniqueItems": true, - "additionalItems": false, - "items": { - "type": "object", - "properties": { - "name": { - "type": "string", - "minLength": 1, - "maxLength": 255 - }, - "packages": { - "type": "object", - "additionalProperties": false, - "properties": { - "excluding": { - "type": "object", - "additionalProperties": false, - "properties": { - "purls": { - "type": "array", - "minItems": 1, - "maxItems": 1000, - "additionalItems": false, - "items": { - "minLength": 1, - "maxLength": 1024, - "type": "string", - "format": "uri" - } - } - }, - "required": [ - "purls" - ] - } - }, - "required": [ - "excluding" - ] - } - }, - "required": [ - "name" - ] - } + "required": [ + "name" + ] } } } -- GitLab From e5e0f57071a9ac1fc4c9b9a61bcb7f0aecc1689c Mon Sep 17 00:00:00 2001 From: Sashi Kumar Kumaresan Date: Wed, 18 Jun 2025 22:59:27 +0200 Subject: [PATCH 4/7] Fix failing spec --- .../security/approval_policy_rule_spec.rb | 46 ++++++++++--------- 1 file changed, 25 insertions(+), 21 deletions(-) diff --git a/ee/spec/models/security/approval_policy_rule_spec.rb b/ee/spec/models/security/approval_policy_rule_spec.rb index 99aabb71a7df24..d2fe4d031141c9 100644 --- a/ee/spec/models/security/approval_policy_rule_spec.rb +++ b/ee/spec/models/security/approval_policy_rule_spec.rb @@ -204,8 +204,17 @@ let_it_be(:source_branch) { 'feature' } let_it_be(:target_branch) { 'main' } - let_it_be(:approval_policy_rule) do - create(:approval_policy_rule, :scan_finding, security_policy_management_project: project) + let!(:security_policy) do + create(:security_policy, content: { + bypass_settings: { + branches: [{ source: { name: source_branch }, target: { name: target_branch } }] + } + }) + end + + let!(:approval_policy_rule) do + create(:approval_policy_rule, :scan_finding, security_policy: security_policy, + security_policy_management_project: project) end subject(:branches_exempted_by_policy) do @@ -219,7 +228,8 @@ context 'when branch_exceptions is nil' do before do - approval_policy_rule.content.delete(:branch_exceptions) + security_policy.content = {} + security_policy.save! end it { is_expected.to be false } @@ -227,27 +237,21 @@ context 'when branch_exceptions is blank' do before do - approval_policy_rule.content[:branch_exceptions] = [] + security_policy.content[:bypass_settings] = { branches: [] } end it { is_expected.to be false } end context 'when branch_exceptions has a matching source and target' do - before do - approval_policy_rule.content[:branch_exceptions] = [ - { 'source' => { 'name' => 'feature' }, 'target' => { 'name' => 'main' } } - ] - end - it { is_expected.to be true } end context 'when branch_exceptions uses a pattern for source and target' do before do - approval_policy_rule.content[:branch_exceptions] = [ - { 'source' => { 'pattern' => 'feat*' }, 'target' => { 'pattern' => 'ma*' } } - ] + security_policy.content[:bypass_settings] = { branches: + [{ 'source' => { 'pattern' => 'feat*' }, 'target' => { 'pattern' => 'ma*' } }] } + security_policy.save! end it { is_expected.to be true } @@ -267,10 +271,10 @@ context 'when branch_exceptions does not match source or target' do before do - approval_policy_rule.content[:branch_exceptions] = [ - { 'source' => { 'name' => 'other' }, 'target' => { 'name' => 'main' } }, - { 'source' => { 'name' => 'feature' }, 'target' => { 'name' => 'develop' } } - ] + security_policy.content[:bypass_settings] = { branches: + [{ 'source' => { 'name' => 'other' }, 'target' => { 'name' => 'main' } }, + { 'source' => { 'name' => 'feature' }, 'target' => { 'name' => 'develop' } }] } + security_policy.save! end it { is_expected.to be false } @@ -278,10 +282,10 @@ context 'when branch_exceptions partially matches (only source or only target)' do before do - approval_policy_rule.content[:branch_exceptions] = [ - { 'source' => { 'name' => 'feature' }, 'target' => { 'name' => 'develop' } }, - { 'source' => { 'name' => 'other' }, 'target' => { 'name' => 'main' } } - ] + security_policy.content[:bypass_settings] = { branches: + [{ 'source' => { 'name' => 'feature' }, 'target' => { 'name' => 'develop' } }, + { 'source' => { 'name' => 'other' }, 'target' => { 'name' => 'main' } }] } + security_policy.save! end it { is_expected.to be false } -- GitLab From 3bc51cfa09a98cbc003fcdd41bbf35c94b772052 Mon Sep 17 00:00:00 2001 From: Sashi Kumar Kumaresan Date: Wed, 18 Jun 2025 23:19:11 +0200 Subject: [PATCH 5/7] Fix policy schema --- .../json_schemas/approval_policy_content.json | 28 +++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/ee/app/validators/json_schemas/approval_policy_content.json b/ee/app/validators/json_schemas/approval_policy_content.json index ff268bdf6a9486..deea21b722095c 100644 --- a/ee/app/validators/json_schemas/approval_policy_content.json +++ b/ee/app/validators/json_schemas/approval_policy_content.json @@ -248,7 +248,19 @@ "pattern": { "type": "string" } - } + }, + "oneOf": [ + { + "required": [ + "name" + ] + }, + { + "required": [ + "pattern" + ] + } + ] }, "target": { "type": "object", @@ -259,7 +271,19 @@ "pattern": { "type": "string" } - } + }, + "oneOf": [ + { + "required": [ + "name" + ] + }, + { + "required": [ + "pattern" + ] + } + ] } } } -- GitLab From ffac4463a1ffc41954e85e45f0511e4eea2b156f Mon Sep 17 00:00:00 2001 From: Sashi Kumar Kumaresan Date: Thu, 26 Jun 2025 10:42:29 +0200 Subject: [PATCH 6/7] Fix failing spec --- ee/app/models/security/policy.rb | 2 +- ee/spec/models/approval_merge_request_rule_spec.rb | 11 +++++++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/ee/app/models/security/policy.rb b/ee/app/models/security/policy.rb index a4783c1f12cf89..6a9c1499e5c194 100644 --- a/ee/app/models/security/policy.rb +++ b/ee/app/models/security/policy.rb @@ -10,7 +10,7 @@ class Policy < ApplicationRecord self.inheritance_column = :_type_disabled POLICY_CONTENT_FIELDS = { - approval_policy: %i[actions approval_settings fallback_behavior policy_tuning], + approval_policy: %i[actions approval_settings fallback_behavior policy_tuning bypass_settings], scan_execution_policy: %i[actions skip_ci], pipeline_execution_policy: %i[content pipeline_config_strategy suffix skip_ci variables_override], vulnerability_management_policy: %i[actions], diff --git a/ee/spec/models/approval_merge_request_rule_spec.rb b/ee/spec/models/approval_merge_request_rule_spec.rb index d015c071f3baef..6c50b563d149df 100644 --- a/ee/spec/models/approval_merge_request_rule_spec.rb +++ b/ee/spec/models/approval_merge_request_rule_spec.rb @@ -684,8 +684,9 @@ end context 'with approval policy branch exceptions' do + let_it_be(:security_policy) { create(:security_policy) } let_it_be(:approval_policy_rule) do - create(:approval_policy_rule, :scan_finding) + create(:approval_policy_rule, :scan_finding, security_policy: security_policy) end let_it_be(:rule) do @@ -693,9 +694,11 @@ end before do - approval_policy_rule.content[:branch_exceptions] = [{ - source: { name: merge_request.source_branch }, target: { name: merge_request.target_branch } - }] + security_policy.content[:bypass_settings] = { + branches: [{ + source: { name: merge_request.source_branch }, target: { name: merge_request.target_branch } + }] + } end it 'returns false' do -- GitLab From f45b4e95103377fe3d36b9b772de1d50cd62e2e3 Mon Sep 17 00:00:00 2001 From: Sashi Kumar Kumaresan Date: Thu, 26 Jun 2025 11:49:06 +0200 Subject: [PATCH 7/7] Fix failing spec --- ...orchestration_policy_configuration_spec.rb | 26 ------------------- 1 file changed, 26 deletions(-) diff --git a/ee/spec/models/security/orchestration_policy_configuration_spec.rb b/ee/spec/models/security/orchestration_policy_configuration_spec.rb index 49b65d71e03f04..a90258ac1297ae 100644 --- a/ee/spec/models/security/orchestration_policy_configuration_spec.rb +++ b/ee/spec/models/security/orchestration_policy_configuration_spec.rb @@ -1738,32 +1738,6 @@ "property '/approval_policy/0/rules/0' is missing required keys: branches") end end - - context "with branch_exceptions" do - before do - rule[:branch_exceptions] = [ - { 'source' => { 'pattern' => 'feat*' }, 'target' => { 'pattern' => 'ma*' } } - ] - end - - specify { expect(errors).to be_empty } - - context "with invalid branch_exceptions" do - before do - rule[:branch_exceptions] = [ - { 'source' => 'feature', 'target' => 'main' } - ] - end - - specify do - expect(errors).to contain_exactly( - "property '/approval_policy/0/rules/0/branch_exceptions/0' is not of type: string", - "property '/approval_policy/0/rules/0/branch_exceptions/0/source' is not of type: object", - "property '/approval_policy/0/rules/0/branch_exceptions/0/target' is not of type: object" - ) - end - end - end end context "with scan_finding type" do -- GitLab