Commit 34cc7a01 authored by Vladimir Shushlin's avatar Vladimir Shushlin Committed by Oswaldo Ferreira

Add build artifact entity for release evidence

And add build artifacts to release evidence json schema
parent ab5cf3d9
......@@ -11,3 +11,5 @@ module Evidences
expose :milestones, using: Evidences::MilestoneEntity
end
end
Evidences::ReleaseEntity.prepend_if_ee('EE::Evidences::ReleaseEntity')
......@@ -10,7 +10,7 @@ module Releases
def execute
evidence = release.evidences.build
summary = Evidences::EvidenceSerializer.new.represent(evidence) # rubocop: disable CodeReuse/Serializer
summary = ::Evidences::EvidenceSerializer.new.represent(evidence, evidence_options) # rubocop: disable CodeReuse/Serializer
evidence.summary = summary
# TODO: fix the sha generating https://gitlab.com/gitlab-org/gitlab/-/issues/209000
evidence.summary_sha = Gitlab::CryptoHelper.sha256(summary)
......@@ -20,6 +20,12 @@ module Releases
private
attr_reader :release
attr_reader :release, :pipeline
def evidence_options
{}
end
end
end
Releases::CreateEvidenceService.prepend_if_ee('EE::Releases::CreateEvidenceService')
......@@ -124,6 +124,7 @@ class License < ApplicationRecord
enforce_pat_expiration
prometheus_alerts
pseudonymizer
release_evidence_test_artifacts
report_approver_rules
requirements
sast
......
# frozen_string_literal: true
module EE
module Evidences
module ReleaseEntity
extend ActiveSupport::Concern
prepended do
expose :report_artifacts, using: ::Evidences::BuildArtifactEntity,
if: -> (release) { release.project.feature_available?(:release_evidence_test_artifacts) } do |_, options|
options[:report_artifacts]
end
end
end
end
end
# frozen_string_literal: true
module Evidences
class BuildArtifactEntity < Grape::Entity
include RequestAwareEntity
expose :url do |job|
download_project_job_artifacts_url(project, job)
end
private
def project
object.project
end
end
end
# frozen_string_literal: true
module EE
module Releases
module CreateEvidenceService
extend ::Gitlab::Utils::Override
override :evidence_options
def evidence_options
options = super.dup
if release.project.feature_available?(:release_evidence_test_artifacts)
options[:report_artifacts] = report_artifacts
end
options
end
def report_artifacts
pipeline&.latest_report_builds || []
end
end
end
end
---
title: Add report artifacts' links to release evidence
merge_request: 34058
author:
type: added
# frozen_string_literal: true
require 'spec_helper'
describe Evidences::ReleaseEntity do
let(:project) { create(:project, :repository) }
let(:release) { build(:release, project: project) }
context 'when report artifacts are passed' do
let(:pipeline) { create(:ci_empty_pipeline, sha: release.sha, project: project) }
let(:build_test_report) { create(:ci_build, :test_reports, pipeline: pipeline) }
let(:build_coverage_report) { create(:ci_build, :coverage_reports, pipeline: pipeline) }
subject { described_class.new(release, report_artifacts: [build_test_report, build_coverage_report]).as_json }
it 'has no report_artifacts if feature is unlicenced' do
stub_licensed_features(release_evidence_test_artifacts: false)
expect(subject).not_to have_key(:report_artifacts)
end
it 'exposes build artifacts if feature is licenced' do
stub_licensed_features(release_evidence_test_artifacts: true)
expect(subject[:report_artifacts]).to(
contain_exactly(
Evidences::BuildArtifactEntity.new(build_test_report).as_json,
Evidences::BuildArtifactEntity.new(build_coverage_report).as_json
)
)
end
end
end
# frozen_string_literal: true
require 'spec_helper'
describe Evidences::BuildArtifactEntity do
include Gitlab::Routing
let(:build) { create(:ci_build, :artifacts) }
let(:entity) { described_class.new(build) }
subject { entity.as_json }
it 'exposes the artifacts url' do
expect(subject[:url]).to eq(download_project_job_artifacts_url(build.project, build))
end
end
# frozen_string_literal: true
require 'spec_helper'
describe Evidences::EvidenceEntity do
let(:project) { create(:project, :repository) }
let(:release) { create(:release, project: project) }
let(:evidence) { build(:evidence, release: release) }
let(:schema_file) { 'evidences/evidence' }
it 'matches the schema when evidence has report artifacts' do
stub_licensed_features(release_evidence_test_artifacts: true)
pipeline = create(:ci_empty_pipeline, sha: release.sha, project: project)
build = create(:ci_build, :test_reports, pipeline: pipeline)
evidence_hash = described_class.represent(evidence, report_artifacts: [build]).as_json
expect(evidence_hash[:release][:report_artifacts]).not_to be_empty
expect(evidence_hash.to_json).to match_schema(schema_file)
end
end
# frozen_string_literal: true
require 'spec_helper'
describe Releases::CreateEvidenceService do
include Gitlab::Routing
let(:project) { create(:project) }
let(:release) { create(:release, project: project) }
context 'when pipeline with artifacts is passed' do
let(:pipeline) { create(:ci_empty_pipeline, sha: release.sha, project: project) }
let!(:build_with_artifacts) { create(:ci_build, :artifacts, pipeline: pipeline) }
let!(:build_test_report) { create(:ci_build, :test_reports, pipeline: pipeline) }
let!(:build_coverage_report) { create(:ci_build, :coverage_reports, pipeline: pipeline) }
let(:service) { described_class.new(release, pipeline: pipeline) }
it 'includes test reports in evidence if feature is licenced' do
stub_licensed_features(release_evidence_test_artifacts: true)
service.execute
evidence = Releases::Evidence.last
evidence_reports = evidence.summary.dig('release', 'report_artifacts')
.map { |artifact| artifact['url'] }
expect(evidence_reports).to(
contain_exactly(
download_project_job_artifacts_url(project, build_test_report),
download_project_job_artifacts_url(project, build_coverage_report)
)
)
end
it 'includes test reports in evidence if feature is unlincenced' do
stub_licensed_features(release_evidence_test_artifacts: false)
service.execute
expect(Releases::Evidence.last.summary['release']).not_to have_key('report_artifacts')
end
end
end
{
"type": "object",
"required": [
"url"
],
"properties": {
"url": { "type": "string" }
},
"additionalProperties": false
}
......@@ -19,6 +19,10 @@
"milestones": {
"type": "array",
"items": { "$ref": "milestone.json" }
},
"report_artifacts": {
"type": "array",
"items": { "$ref": "build_artifact.json" }
}
},
"additionalProperties": false
......
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