Commit 328740c6 authored by Grzegorz Bizon's avatar Grzegorz Bizon

Merge branch 'mc/feature/reports-download' into 'master'

Allow downloading report artifacts

Closes #49265

See merge request gitlab-org/gitlab-ce!27974
parents f139ce9d 1542b160
......@@ -765,6 +765,10 @@ module Ci
end
end
def report_artifacts
job_artifacts.with_reports
end
# Virtual deployment status depending on the environment status.
def deployment_status
return unless starts_environment?
......
......@@ -26,10 +26,13 @@ module Ci
metrics: 'metrics.txt'
}.freeze
TYPE_AND_FORMAT_PAIRS = {
INTERNAL_TYPES = {
archive: :zip,
metadata: :gzip,
trace: :raw,
trace: :raw
}.freeze
REPORT_TYPES = {
junit: :gzip,
metrics: :gzip,
......@@ -45,6 +48,8 @@ module Ci
performance: :raw
}.freeze
TYPE_AND_FORMAT_PAIRS = INTERNAL_TYPES.merge(REPORT_TYPES).freeze
belongs_to :project
belongs_to :job, class_name: "Ci::Build", foreign_key: :job_id
......@@ -66,6 +71,10 @@ module Ci
where(file_type: types)
end
scope :with_reports, -> do
with_file_types(REPORT_TYPES.keys.map(&:to_s))
end
scope :test_reports, -> do
with_file_types(TEST_REPORT_FILE_TYPES)
end
......
......@@ -42,6 +42,11 @@ class BuildDetailsEntity < JobEntity
end
end
expose :report_artifacts,
as: :reports,
using: JobArtifactReportEntity,
if: -> (*) { can?(current_user, :read_build, build) }
expose :erased_by, if: -> (*) { build.erased? }, using: UserEntity
expose :erase_path, if: -> (*) { build.erasable? && can?(current_user, :erase_build, build) } do |build|
erase_project_job_path(project, build)
......
# frozen_string_literal: true
class JobArtifactReportEntity < Grape::Entity
include RequestAwareEntity
expose :file_type
expose :file_format
expose :size
expose :download_path do |artifact|
download_project_job_artifacts_path(artifact.job.project, artifact.job, file_type: artifact.file_format)
end
end
......@@ -3490,6 +3490,18 @@ describe Ci::Build do
end
end
describe '#report_artifacts' do
subject { build.report_artifacts }
context 'when the build has reports' do
let!(:report) { create(:ci_job_artifact, :codequality, job: build) }
it 'returns the artifacts with reports' do
expect(subject).to contain_exactly(report)
end
end
end
describe '#artifacts_metadata_entry' do
set(:build) { create(:ci_build, project: project) }
let(:path) { 'other_artifacts_0.1.2/another-subdirectory/banana_sample.gif' }
......
......@@ -23,6 +23,21 @@ describe Ci::JobArtifact do
it_behaves_like 'having unique enum values'
describe '.with_reports' do
let!(:artifact) { create(:ci_job_artifact, :archive) }
subject { described_class.with_reports }
it { is_expected.to be_empty }
context 'when there are reports' do
let!(:metrics_report) { create(:ci_job_artifact, :junit) }
let!(:codequality_report) { create(:ci_job_artifact, :codequality) }
it { is_expected.to eq([metrics_report, codequality_report]) }
end
end
describe '.test_reports' do
subject { described_class.test_reports }
......
......@@ -146,5 +146,14 @@ describe BuildDetailsEntity do
end
end
end
context 'when the build has reports' do
let!(:report) { create(:ci_job_artifact, :codequality, job: build) }
it 'exposes the report artifacts' do
expect(subject[:reports].count).to eq(1)
expect(subject[:reports].first[:file_type]).to eq('codequality')
end
end
end
end
# frozen_string_literal: true
require 'spec_helper'
describe JobArtifactReportEntity do
let(:report) { create(:ci_job_artifact, :codequality) }
let(:entity) { described_class.new(report, request: double) }
describe '#as_json' do
subject { entity.as_json }
it 'exposes file_type' do
expect(subject[:file_type]).to eq(report.file_type)
end
it 'exposes file_format' do
expect(subject[:file_format]).to eq(report.file_format)
end
it 'exposes size' do
expect(subject[:size]).to eq(report.size)
end
it 'exposes download path' do
expect(subject[:download_path]).to include("jobs/#{report.job.id}/artifacts/download")
end
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