Commit f3f1ad39 authored by Grzegorz Bizon's avatar Grzegorz Bizon

Add API endpoint for downloading single job artifact

parent ebbbc7ef
...@@ -85,6 +85,25 @@ module API ...@@ -85,6 +85,25 @@ module API
present_artifacts!(build.artifacts_file) present_artifacts!(build.artifacts_file)
end end
desc 'Download a specific file from artifacts archive' do
detail 'This feature was introduced in GitLab 10.0'
end
params do
requires :job_id, type: Integer, desc: 'The ID of a job'
requires :artifact_path, type: String, desc: 'Artifact path'
end
get ':id/jobs/:job_id/artifacts/*artifact_path', format: false do
authorize_read_builds!
build = get_build!(params[:job_id])
not_found! unless build.artifacts?
entry = build.artifacts_metadata_entry(params[:artifact_path])
not_found! unless entry.exists?
Gitlab::Workhorse.send_artifacts_entry(build, entry)
end
desc 'Download the artifacts file from a job' do desc 'Download the artifacts file from a job' do
detail 'This feature was introduced in GitLab 8.10' detail 'This feature was introduced in GitLab 8.10'
end end
......
...@@ -188,6 +188,63 @@ describe API::Jobs do ...@@ -188,6 +188,63 @@ describe API::Jobs do
end end
end end
describe 'GET /projects/:id/jobs/:job_id/artifacts/:artifact_path' do
context 'when job has artifacts' do
let(:job) { create(:ci_build, :artifacts, pipeline: pipeline) }
let(:artifact) do
'other_artifacts_0.1.2/another-subdirectory/banana_sample.gif'
end
context 'when user is not unauthorized' do
let(:api_user) { nil }
it 'does not return specific job artifacts' do
get_artifact_file(artifact)
expect(response).to have_http_status(401)
end
end
context 'when user is authorized' do
it 'returns a specific artifact file for a valid path' do
expect(Gitlab::Workhorse)
.to receive(:send_artifacts_entry)
.and_call_original
get_artifact_file(artifact)
expect(response).to have_http_status(200)
expect(response.body)
.to include 'Gitlab-Workhorse-Send-Data', 'artifacts-entry'
expect(response.headers)
.to include('Content-Type' => 'application/json')
end
end
context 'when request path is invalid' do
it 'does not find artifact file' do
get_artifact_file('invalid/path')
expect(response).to have_http_status(404)
end
end
end
context 'when job does not have artifacts' do
it 'does not return job artifact file' do
get_artifact_file('some/artifact')
expect(response).to have_http_status(404)
end
end
def get_artifact_file(artifact_path)
get api("/projects/#{project.id}/jobs/#{job.id}/" \
"artifacts/#{artifact_path}", api_user)
end
end
describe 'GET /projects/:id/jobs/:job_id/artifacts' do describe 'GET /projects/:id/jobs/:job_id/artifacts' do
before do before do
get api("/projects/#{project.id}/jobs/#{job.id}/artifacts", api_user) get api("/projects/#{project.id}/jobs/#{job.id}/artifacts", api_user)
......
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