Commit c628b6c7 authored by Grzegorz Bizon's avatar Grzegorz Bizon

Merge branch 'support-project-security-dashboard' into 'master'

Support project security dashboard

See merge request gitlab-org/gitlab-ee!8222
parents ad19f51a 604dbc21
......@@ -194,22 +194,31 @@ module Ci
#
# ref - The name (or names) of the branch(es)/tag(s) to limit the list of
# pipelines to.
def self.newest_first(ref = nil)
# limit - This limits a backlog search, default to 100.
def self.newest_first(ref: nil, limit: 100)
relation = order(id: :desc)
relation = relation.where(ref: ref) if ref
if limit
ids = relation.limit(limit).select(:id)
# MySQL does not support limit in subquery
ids = ids.pluck(:id) if Gitlab::Database.mysql?
relation = relation.where(id: ids)
end
ref ? relation.where(ref: ref) : relation
relation
end
def self.latest_status(ref = nil)
newest_first(ref).pluck(:status).first
newest_first(ref: ref).pluck(:status).first
end
def self.latest_successful_for(ref)
newest_first(ref).success.take
newest_first(ref: ref).success.take
end
def self.latest_successful_for_refs(refs)
relation = newest_first(refs).success
relation = newest_first(ref: refs).success
relation.each_with_object({}) do |pipeline, hash|
hash[pipeline.ref] ||= pipeline
......
......@@ -5,7 +5,7 @@ module Projects
before_action :authorize_read_project_security_dashboard!
def show
@pipeline = @project.latest_pipeline_with_legacy_security_reports
@pipeline = @project.latest_pipeline_with_security_reports
&.present(current_user: current_user)
end
......
......@@ -16,9 +16,14 @@ module EE
has_many :vulnerabilities, source: :occurrence, through: :vulnerabilities_occurrence_pipelines, class_name: 'Vulnerabilities::Occurrence'
# Legacy way to fetch security reports based on job name. This has been replaced by the reports feature.
scope :with_legacy_security_reports, -> {
scope :with_legacy_security_reports, -> do
joins(:artifacts).where(ci_builds: { name: %w[sast dependency_scanning sast:container container_scanning dast] })
}
end
# The new `reports:` syntax reports
scope :with_security_reports, -> do
where('EXISTS (?)', ::Ci::Build.latest.with_security_reports.where('ci_pipelines.id=ci_builds.commit_id').select(1))
end
# This structure describes feature levels
# to access the file types for given reports
......
......@@ -109,8 +109,9 @@ module EE
end
end
def latest_pipeline_with_legacy_security_reports
pipelines.newest_first(default_branch).with_legacy_security_reports.first
def latest_pipeline_with_security_reports
pipelines.newest_first(ref: default_branch).with_security_reports.first ||
pipelines.newest_first(ref: default_branch).with_legacy_security_reports.first
end
def environments_for_scope(scope)
......
---
title: 'Support reports: for project security dashboard'
merge_request:
author:
type: added
......@@ -48,7 +48,7 @@ describe Projects::Security::DashboardController do
expect(response).to have_gitlab_http_status(200)
expect(response).to render_template(:show)
expect(response.body).to have_css("div#js-security-report-app[data-has-pipeline-data=false]")
expect(response.body).to have_css("div#js-security-report-app[data-has-pipeline-data=true]")
end
end
......
......@@ -1496,19 +1496,44 @@ describe Project do
end
end
describe '#latest_pipeline_with_legacy_security_reports' do
describe '#latest_pipeline_with_security_reports' do
let(:project) { create(:project) }
let(:pipeline_1) { create(:ci_pipeline_without_jobs, project: project) }
let(:pipeline_2) { create(:ci_pipeline_without_jobs, project: project) }
let(:pipeline_3) { create(:ci_pipeline_without_jobs, project: project) }
let!(:pipeline_1) { create(:ci_pipeline_without_jobs, project: project) }
let!(:pipeline_2) { create(:ci_pipeline_without_jobs, project: project) }
let!(:pipeline_3) { create(:ci_pipeline_without_jobs, project: project) }
before do
create(:ee_ci_build, :legacy_sast, pipeline: pipeline_1)
create(:ee_ci_build, :legacy_sast, pipeline: pipeline_2)
subject { project.latest_pipeline_with_security_reports }
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
it "returns the latest pipeline with security reports" do
expect(project.latest_pipeline_with_legacy_security_reports).to eq(pipeline_2)
context 'when new reports are used' do
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
......
......@@ -1052,6 +1052,11 @@ describe Ci::Pipeline, :mailer do
expect(described_class.newest_first.pluck(:status))
.to eq(%w[skipped failed success canceled])
end
it 'searches limited backlog' do
expect(described_class.newest_first(limit: 1).pluck(:status))
.to eq(%w[skipped])
end
end
describe '.latest_status' 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