Commit 791b267b authored by Albert Salim's avatar Albert Salim

Ensure coverage approval rule sync is successful

This fixes errors that occur when either the base pipeline
or the head pipeline does not have a coverage.

When either of the pipeline does not have a coverage,
the merge request is considered not approved,
and still requires manual approval.

Changelog: fixed
EE: true
parent bcdec579
...@@ -67,6 +67,8 @@ module Ci ...@@ -67,6 +67,8 @@ module Ci
return unless pipeline.complete? return unless pipeline.complete?
pipeline.update_builds_coverage pipeline.update_builds_coverage
return unless pipeline.coverage.present?
remove_required_approvals_for(ApprovalMergeRequestRule.code_coverage, merge_requests_approved_coverage) remove_required_approvals_for(ApprovalMergeRequestRule.code_coverage, merge_requests_approved_coverage)
end end
...@@ -109,13 +111,21 @@ module Ci ...@@ -109,13 +111,21 @@ module Ci
def merge_requests_approved_coverage def merge_requests_approved_coverage
pipeline.merge_requests_as_head_pipeline.reject do |merge_request| pipeline.merge_requests_as_head_pipeline.reject do |merge_request|
base_pipeline = merge_request.base_pipeline require_coverage_approval?(merge_request)
# if base pipeline is missing we just default to not require approval.
pipeline.coverage < base_pipeline.coverage if base_pipeline.present?
end end
end end
def require_coverage_approval?(merge_request)
base_pipeline = merge_request.base_pipeline
# if base pipeline is missing we just default to not require approval.
return false unless base_pipeline.present?
return true unless base_pipeline.coverage.present?
pipeline.coverage < base_pipeline.coverage
end
def merge_requests_approved_security_reports def merge_requests_approved_security_reports
pipeline.merge_requests_as_head_pipeline.reject do |merge_request| pipeline.merge_requests_as_head_pipeline.reject do |merge_request|
reports.present? && reports.violates_default_policy_against?(merge_request.base_pipeline&.security_reports, project_rule_vulnerabilities_allowed, project_rule_severity_levels, project_rule_vulnerability_states) reports.present? && reports.violates_default_policy_against?(merge_request.base_pipeline&.security_reports, project_rule_vulnerabilities_allowed, project_rule_severity_levels, project_rule_vulnerability_states)
......
...@@ -21,6 +21,12 @@ RSpec.describe Ci::SyncReportsToApprovalRulesService, '#execute' do ...@@ -21,6 +21,12 @@ RSpec.describe Ci::SyncReportsToApprovalRulesService, '#execute' do
stub_licensed_features(dependency_scanning: true, dast: true, license_scanning: true) stub_licensed_features(dependency_scanning: true, dast: true, license_scanning: true)
end end
shared_examples 'a successful execution' do
it "is successful" do
expect(sync_rules[:status]).to eq(:success)
end
end
shared_context 'security reports with vulnerabilities' do shared_context 'security reports with vulnerabilities' do
context 'when there are security reports' do context 'when there are security reports' do
context 'when pipeline passes' do context 'when pipeline passes' do
...@@ -244,6 +250,8 @@ RSpec.describe Ci::SyncReportsToApprovalRulesService, '#execute' do ...@@ -244,6 +250,8 @@ RSpec.describe Ci::SyncReportsToApprovalRulesService, '#execute' do
] ]
end end
it_behaves_like 'a successful execution'
it "won't lower approvals_required count" do it "won't lower approvals_required count" do
expect { sync_rules } expect { sync_rules }
.not_to change { report_approver_rule.reload.approvals_required } .not_to change { report_approver_rule.reload.approvals_required }
...@@ -259,6 +267,8 @@ RSpec.describe Ci::SyncReportsToApprovalRulesService, '#execute' do ...@@ -259,6 +267,8 @@ RSpec.describe Ci::SyncReportsToApprovalRulesService, '#execute' do
] ]
end end
it_behaves_like 'a successful execution'
it "lowers approvals_required count" do it "lowers approvals_required count" do
expect { sync_rules } expect { sync_rules }
.to change { report_approver_rule.reload.approvals_required }.from(2).to(0) .to change { report_approver_rule.reload.approvals_required }.from(2).to(0)
...@@ -267,6 +277,8 @@ RSpec.describe Ci::SyncReportsToApprovalRulesService, '#execute' do ...@@ -267,6 +277,8 @@ RSpec.describe Ci::SyncReportsToApprovalRulesService, '#execute' do
context 'when MR is merged' do context 'when MR is merged' do
let!(:merge_request) { create(:merge_request, :merged, source_project: project) } let!(:merge_request) { create(:merge_request, :merged, source_project: project) }
it_behaves_like 'a successful execution'
it "won't change approvals_required count" do it "won't change approvals_required count" do
expect { subject } expect { subject }
.not_to change { report_approver_rule.reload.approvals_required } .not_to change { report_approver_rule.reload.approvals_required }
...@@ -283,11 +295,34 @@ RSpec.describe Ci::SyncReportsToApprovalRulesService, '#execute' do ...@@ -283,11 +295,34 @@ RSpec.describe Ci::SyncReportsToApprovalRulesService, '#execute' do
] ]
end end
it_behaves_like 'a successful execution'
it "lowers approvals_required count" do it "lowers approvals_required count" do
expect { sync_rules } expect { sync_rules }
.to change { report_approver_rule.reload.approvals_required }.from(2).to(0) .to change { report_approver_rule.reload.approvals_required }.from(2).to(0)
end end
end end
context 'and head pipeline does not have coverage' do
let!(:head_pipeline_builds) do
[
create(:ci_build, :success, coverage: nil, pipeline: pipeline)
]
end
let!(:base_pipeline_builds) do
[
create(:ci_build, :success, coverage: 60.0, pipeline: base_pipeline)
]
end
it_behaves_like 'a successful execution'
it "does not lower approvals_required count" do
expect { sync_rules }
.not_to change { report_approver_rule.reload.approvals_required }
end
end
end end
context 'when pipeline is incomplete' do context 'when pipeline is incomplete' do
...@@ -302,6 +337,8 @@ RSpec.describe Ci::SyncReportsToApprovalRulesService, '#execute' do ...@@ -302,6 +337,8 @@ RSpec.describe Ci::SyncReportsToApprovalRulesService, '#execute' do
allow(pipeline).to receive(:complete?).and_return(false) allow(pipeline).to receive(:complete?).and_return(false)
end end
it_behaves_like 'a successful execution'
it "won't lower approvals_required count" do it "won't lower approvals_required count" do
expect { sync_rules } expect { sync_rules }
.not_to change { report_approver_rule.reload.approvals_required } .not_to change { report_approver_rule.reload.approvals_required }
...@@ -313,11 +350,32 @@ RSpec.describe Ci::SyncReportsToApprovalRulesService, '#execute' do ...@@ -313,11 +350,32 @@ RSpec.describe Ci::SyncReportsToApprovalRulesService, '#execute' do
allow(pipeline).to receive(:complete?).and_return(true) allow(pipeline).to receive(:complete?).and_return(true)
end end
it_behaves_like 'a successful execution'
it "lowers approvals_required count" do it "lowers approvals_required count" do
expect { sync_rules } expect { sync_rules }
.to change { report_approver_rule.reload.approvals_required }.from(2).to(0) .to change { report_approver_rule.reload.approvals_required }.from(2).to(0)
end end
end end
context 'when base pipeline does not have coverage' do
before do
allow(pipeline).to receive(:complete?).and_return(true)
end
let!(:base_pipeline_builds) do
[
create(:ci_build, :success, coverage: nil, pipeline: base_pipeline)
]
end
it_behaves_like 'a successful execution'
it "does not lower approvals_required count" do
expect { sync_rules }
.not_to change { report_approver_rule.reload.approvals_required }
end
end
end end
context 'with security orchestration rules' do context 'with security orchestration rules' do
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment