Commit 633a509e authored by Jarka Košanová's avatar Jarka Košanová

Merge branch '218012-rewrite-query-to-fetch-reports' into 'master'

Rewrite query to check resolved_on_default_branch

See merge request gitlab-org/gitlab!38452
parents 7b67520a be53ef4b
...@@ -233,9 +233,12 @@ module EE ...@@ -233,9 +233,12 @@ module EE
self.tracing_setting.try(:external_url) self.tracing_setting.try(:external_url)
end end
def latest_pipeline_with_security_reports def latest_pipeline_with_security_reports(only_successful: false)
all_pipelines.newest_first(ref: default_branch).with_reports(::Ci::JobArtifact.security_reports).first || pipeline_scope = all_pipelines.newest_first(ref: default_branch)
all_pipelines.newest_first(ref: default_branch).with_legacy_security_reports.first pipeline_scope = pipeline_scope.success if only_successful
pipeline_scope.with_reports(::Ci::JobArtifact.security_reports).first ||
pipeline_scope.with_legacy_security_reports.first
end end
def latest_pipeline_with_reports(reports) def latest_pipeline_with_reports(reports)
......
...@@ -141,9 +141,18 @@ class Vulnerability < ApplicationRecord ...@@ -141,9 +141,18 @@ class Vulnerability < ApplicationRecord
def resolved_on_default_branch def resolved_on_default_branch
return false unless findings.any? return false unless findings.any?
latest_successful_pipeline_for_default_branch = project.latest_successful_pipeline_for_default_branch # We can't just use project.latest_successful_pipeline_for_default_branch
latest_pipeline_with_vulnerability = finding.pipelines.order(created_at: :desc).first # because there's no guarantee that it actually ran the security jobs
latest_pipeline_with_vulnerability != latest_successful_pipeline_for_default_branch # See https://gitlab.com/gitlab-org/gitlab/-/issues/218012
latest_successful_pipeline = project
.latest_pipeline_with_security_reports(only_successful: true)
# Technically this shouldn't ever happen.
# If an vulnerability was discovered, then we must have ran a scan of the
# appropriate type at least once.
return false unless latest_successful_pipeline
finding.pipelines.exclude?(latest_successful_pipeline)
end end
def user_notes_count def user_notes_count
......
---
title: Fetch latest successful pipeline with security jobs to check if vulnerability
was resolved
merge_request: 38452
author:
type: changed
...@@ -1513,41 +1513,81 @@ RSpec.describe Project do ...@@ -1513,41 +1513,81 @@ RSpec.describe Project do
end end
describe '#latest_pipeline_with_security_reports' do describe '#latest_pipeline_with_security_reports' do
let(:project) { create(:project) } let(:only_successful) { false }
let!(:pipeline_1) { create(:ci_pipeline, project: project) }
let!(:pipeline_2) { create(:ci_pipeline, project: project) }
let!(:pipeline_3) { create(:ci_pipeline, project: project) }
subject { project.latest_pipeline_with_security_reports } let_it_be(:project) { create(:project) }
let_it_be(:pipeline_1) { create(:ci_pipeline, :success, project: project) }
let_it_be(:pipeline_2) { create(:ci_pipeline, project: project) }
let_it_be(:pipeline_3) { create(:ci_pipeline, :success, project: project) }
context 'when legacy reports are used' do subject { project.latest_pipeline_with_security_reports(only_successful: only_successful) }
before do
create(:ee_ci_build, :legacy_sast, pipeline: pipeline_1) context 'when all pipelines are used' do
create(:ee_ci_build, :legacy_sast, pipeline: pipeline_2) context 'when legacy reports are used' do
before do
create(:ee_ci_build, :legacy_sast, pipeline: pipeline_1)
create(:ee_ci_build, :legacy_sast, pipeline: pipeline_2)
end
it 'returns the latest pipeline with security reports' do
is_expected.to eq(pipeline_2)
end
end end
it "returns the latest pipeline with security reports" do context 'when new reports are used' do
is_expected.to eq(pipeline_2) before do
create(:ee_ci_build, :sast, pipeline: pipeline_1)
create(:ee_ci_build, :sast, pipeline: pipeline_2)
end
it 'returns the latest pipeline with security reports' do
is_expected.to eq(pipeline_2)
end
context 'when legacy used' do
before do
create(:ee_ci_build, :legacy_sast, pipeline: pipeline_3)
end
it 'prefers the new reports' do
is_expected.to eq(pipeline_2)
end
end
end end
end end
context 'when new reports are used' do context 'when only successful pipelines are used' do
before do let(:only_successful) { true }
create(:ee_ci_build, :sast, pipeline: pipeline_1)
create(:ee_ci_build, :sast, pipeline: pipeline_2)
end
it "returns the latest pipeline with security reports" do context 'when legacy reports are used' do
is_expected.to eq(pipeline_2) before do
create(:ee_ci_build, :legacy_sast, pipeline: pipeline_1)
create(:ee_ci_build, :legacy_sast, pipeline: pipeline_2)
end
it "returns the latest succesful pipeline with security reports" do
is_expected.to eq(pipeline_1)
end
end end
context 'when legacy used' do context 'when new reports are used' do
before do before do
create(:ee_ci_build, :legacy_sast, pipeline: pipeline_3) create(:ee_ci_build, :sast, pipeline: pipeline_1)
create(:ee_ci_build, :sast, pipeline: pipeline_2)
end end
it "prefers the new reports" do it 'returns the latest successful pipeline with security reports' do
is_expected.to eq(pipeline_2) is_expected.to eq(pipeline_1)
end
context 'when legacy used' do
before do
create(:ee_ci_build, :legacy_sast, pipeline: pipeline_3)
end
it 'prefers the new reports' do
is_expected.to eq(pipeline_1)
end
end end
end end
end end
......
...@@ -250,7 +250,7 @@ RSpec.describe Vulnerability do ...@@ -250,7 +250,7 @@ RSpec.describe Vulnerability do
describe '#resolved_on_default_branch' do describe '#resolved_on_default_branch' do
let_it_be(:project) { create(:project, :repository, :with_vulnerability) } let_it_be(:project) { create(:project, :repository, :with_vulnerability) }
let_it_be(:pipeline_with_vulnerability) { create(:ci_pipeline, :success, project: project, sha: project.commit.id) } let_it_be(:pipeline_with_vulnerability) { create(:ee_ci_pipeline, :success, :with_sast_report, project: project, sha: project.commit.id) }
let_it_be(:vulnerability) { project.vulnerabilities.first } let_it_be(:vulnerability) { project.vulnerabilities.first }
let_it_be(:finding1) { create(:vulnerabilities_occurrence, vulnerability: vulnerability, pipelines: [pipeline_with_vulnerability]) } let_it_be(:finding1) { create(:vulnerabilities_occurrence, vulnerability: vulnerability, pipelines: [pipeline_with_vulnerability]) }
let_it_be(:finding2) { create(:vulnerabilities_occurrence, vulnerability: vulnerability, pipelines: [pipeline_with_vulnerability]) } let_it_be(:finding2) { create(:vulnerabilities_occurrence, vulnerability: vulnerability, pipelines: [pipeline_with_vulnerability]) }
...@@ -259,14 +259,22 @@ RSpec.describe Vulnerability do ...@@ -259,14 +259,22 @@ RSpec.describe Vulnerability do
context 'Vulnerability::Finding is present on the pipeline for default branch' do context 'Vulnerability::Finding is present on the pipeline for default branch' do
it { is_expected.to eq(false) } it { is_expected.to eq(false) }
end
context 'Vulnerability::Finding is not present on the pipeline for default branch' do context 'but pipeline is failed' do
before do let!(:unsucessful_pipeline_with_vulnerability) { create(:ee_ci_pipeline, :with_sast_report, :failed, project: project, sha: project.commit.id) }
project.instance_variable_set(:@latest_successful_pipeline_for_default_branch, pipeline_without_vulnerability)
it { is_expected.to eq(false) }
end end
end
let_it_be(:pipeline_without_vulnerability) { create(:ci_pipeline, :success, project: project, sha: project.commit.id) } context 'Vulnerability::Finding is not present on the latest pipeline without security job' do
let!(:pipeline_without_security_job) { create(:ee_ci_pipeline, :success, project: project, sha: project.commit.id) }
it { is_expected.to eq(false) }
end
context 'Vulnerability::Finding is not present on the pipeline for default branch' do
let!(:pipeline_without_vulnerability) { create(:ee_ci_pipeline, :success, :with_sast_report, project: project, sha: project.commit.id) }
it { is_expected.to eq(true) } it { is_expected.to eq(true) }
end end
......
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