Commit f99ad907 authored by Maxime Orefice's avatar Maxime Orefice Committed by Shinya Maeda

Add pipeline artifact uploader

This new uploader will be used to upload reports
persisted in a pipeline context consumable by gitlab
frontend.
parent 6d0fe4ba
......@@ -22,8 +22,22 @@ module Ci
validates :size, presence: true, numericality: { less_than_or_equal_to: FILE_SIZE_LIMIT }
validates :file_type, presence: true
mount_uploader :file, Ci::PipelineArtifactUploader
before_save :set_size, if: :file_changed?
after_save :update_file_store, if: :saved_change_to_file?
enum file_type: {
code_coverage: 1
}
def set_size
self.size = file.size
end
def update_file_store
# The file.object_store is set during `uploader.store!`
# which happens after object is inserted/updated
self.update_column(:file_store, file.object_store)
end
end
end
# frozen_string_literal: true
module Ci
class PipelineArtifactUploader < GitlabUploader
include ObjectStorage::Concern
storage_options Gitlab.config.artifacts
alias_method :upload, :model
def store_dir
dynamic_segment
end
private
def dynamic_segment
Gitlab::HashedPath.new('pipelines', model.pipeline_id, 'artifacts', model.id, root_hash: model.project_id)
end
end
end
......@@ -43,4 +43,34 @@ RSpec.describe Ci::PipelineArtifact, type: :model do
end
end
end
describe '#set_size' do
subject { create(:ci_pipeline_artifact) }
context 'when file is being created' do
it 'sets the size' do
expect(subject.size).to eq(85)
end
end
context 'when file is being updated' do
it 'updates the size' do
subject.update!(file: fixture_file_upload('spec/fixtures/dk.png'))
expect(subject.size).to eq(1062)
end
end
end
describe 'file is being stored' do
subject { create(:ci_pipeline_artifact) }
context 'when existing object has local store' do
it 'is stored locally' do
expect(subject.file_store).to be(ObjectStorage::Store::LOCAL)
expect(subject.file).to be_file_storage
expect(subject.file.object_store).to eq(ObjectStorage::Store::LOCAL)
end
end
end
end
......@@ -47,9 +47,9 @@ module StubObjectStorage
end
end
def stub_artifacts_object_storage(**params)
def stub_artifacts_object_storage(uploader = JobArtifactUploader, **params)
stub_object_storage_uploader(config: Gitlab.config.artifacts.object_store,
uploader: JobArtifactUploader,
uploader: uploader,
remote_directory: 'artifacts',
**params)
end
......
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Ci::PipelineArtifactUploader do
let(:pipeline_artifact) { create(:ci_pipeline_artifact) }
let(:uploader) { described_class.new(pipeline_artifact, :file) }
subject { uploader }
it_behaves_like "builds correct paths",
store_dir: %r[\h{2}/\h{2}/\h{64}/pipelines/\d+/artifacts/\d+],
cache_dir: %r[artifacts/tmp/cache],
work_dir: %r[artifacts/tmp/work]
context 'when object store is REMOTE' do
before do
stub_artifacts_object_storage(described_class)
end
include_context 'with storage', described_class::Store::REMOTE
it_behaves_like 'builds correct paths', store_dir: %r[\h{2}/\h{2}/\h{64}/pipelines/\d+/artifacts/\d+]
end
context 'when file is stored in valid local_path' do
let(:file) do
fixture_file_upload('spec/fixtures/pipeline_artifacts/code_coverage.json', 'application/json')
end
before do
uploader.store!(file)
end
subject { uploader.file.path }
it { is_expected.to match(%r[#{uploader.root}/#{uploader.class.base_dir}\h{2}/\h{2}/\h{64}/pipelines/#{pipeline_artifact.pipeline_id}/artifacts/#{pipeline_artifact.id}/code_coverage.json]) }
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