Commit 05ee94be authored by Kamil Trzciński's avatar Kamil Trzciński

Merge branch '50101-add-artifact-information-to-job-api' into 'master'

Add artifact information in job API

See merge request gitlab-org/gitlab-ce!21328
parents 8ff02cf7 71433c55
...@@ -9,6 +9,28 @@ class BuildDetailsEntity < JobEntity ...@@ -9,6 +9,28 @@ class BuildDetailsEntity < JobEntity
expose :metadata, using: BuildMetadataEntity expose :metadata, using: BuildMetadataEntity
expose :artifact, if: -> (*) { can?(current_user, :read_build, build) } do
expose :download_path, if: -> (*) { build.artifacts? } do |build|
download_project_job_artifacts_path(project, build)
end
expose :browse_path, if: -> (*) { build.browsable_artifacts? } do |build|
browse_project_job_artifacts_path(project, build)
end
expose :keep_path, if: -> (*) { build.has_expiring_artifacts? && can?(current_user, :update_build, build) } do |build|
keep_project_job_artifacts_path(project, build)
end
expose :expire_at, if: -> (*) { build.artifacts_expire_at.present? } do |build|
build.artifacts_expire_at
end
expose :expired, if: -> (*) { build.artifacts_expire_at.present? } do |build|
build.artifacts_expired?
end
end
expose :erased_by, if: -> (*) { build.erased? }, using: UserEntity expose :erased_by, if: -> (*) { build.erased? }, using: UserEntity
expose :erase_path, if: -> (*) { build.erasable? && can?(current_user, :erase_build, build) } do |build| expose :erase_path, if: -> (*) { build.erasable? && can?(current_user, :erase_build, build) } do |build|
erase_project_job_path(project, build) erase_project_job_path(project, build)
......
---
title: Send artifact information in job API
merge_request: 50460
author:
type: other
...@@ -135,7 +135,7 @@ describe Projects::JobsController, :clean_gitlab_redis_shared_state do ...@@ -135,7 +135,7 @@ describe Projects::JobsController, :clean_gitlab_redis_shared_state do
end end
end end
context 'when requesting JSON' do context 'when requesting JSON with failed job' do
let(:merge_request) { create(:merge_request, source_project: project) } let(:merge_request) { create(:merge_request, source_project: project) }
before do before do
...@@ -149,10 +149,60 @@ describe Projects::JobsController, :clean_gitlab_redis_shared_state do ...@@ -149,10 +149,60 @@ describe Projects::JobsController, :clean_gitlab_redis_shared_state do
it 'exposes needed information' do it 'exposes needed information' do
expect(response).to have_gitlab_http_status(:ok) expect(response).to have_gitlab_http_status(:ok)
expect(response).to match_response_schema('job/job_details')
expect(json_response['raw_path']).to match(%r{jobs/\d+/raw\z})
expect(json_response['merge_request']['path']).to match(%r{merge_requests/\d+\z})
expect(json_response['new_issue_path']).to include('/issues/new')
end
end
context 'when request JSON for successful job' do
let(:merge_request) { create(:merge_request, source_project: project) }
let(:job) { create(:ci_build, :success, :artifacts, pipeline: pipeline) }
before do
project.add_developer(user)
sign_in(user)
allow_any_instance_of(Ci::Build).to receive(:merge_request).and_return(merge_request)
get_show(id: job.id, format: :json)
end
it 'exposes needed information' do
expect(response).to have_gitlab_http_status(:ok)
expect(response).to match_response_schema('job/job_details')
expect(json_response['artifact']['download_path']).to match(%r{artifacts/download})
expect(json_response['artifact']['browse_path']).to match(%r{artifacts/browse})
expect(json_response['artifact']).not_to have_key(:expired)
expect(json_response['artifact']).not_to have_key(:expired_at)
expect(json_response['raw_path']).to match(%r{jobs/\d+/raw\z}) expect(json_response['raw_path']).to match(%r{jobs/\d+/raw\z})
expect(json_response.dig('merge_request', 'path')).to match(%r{merge_requests/\d+\z}) expect(json_response.dig('merge_request', 'path')).to match(%r{merge_requests/\d+\z})
expect(json_response['new_issue_path']) end
.to include('/issues/new')
context 'when request JSON for successful job with expired artifacts' do
let(:merge_request) { create(:merge_request, source_project: project) }
let(:job) { create(:ci_build, :success, :artifacts, :expired, pipeline: pipeline) }
before do
project.add_developer(user)
sign_in(user)
allow_any_instance_of(Ci::Build).to receive(:merge_request).and_return(merge_request)
get_show(id: job.id, format: :json)
end
it 'exposes needed information' do
expect(response).to have_gitlab_http_status(:ok)
expect(response).to match_response_schema('job/job_details')
expect(json_response['artifact']).not_to have_key(:download_path)
expect(json_response['artifact']).not_to have_key(:browse_path)
expect(json_response['artifact']['expired']).to eq(true)
expect(json_response['artifact']['expire_at']).not_to be_empty
expect(json_response['raw_path']).to match(%r{jobs/\d+/raw\z})
expect(json_response.dig('merge_request', 'path')).to match(%r{merge_requests/\d+\z})
end
end end
end end
......
...@@ -18,7 +18,29 @@ ...@@ -18,7 +18,29 @@
"tooltip": { "type": "string" }, "tooltip": { "type": "string" },
"has_details": { "type": "boolean" }, "has_details": { "type": "boolean" },
"details_path": { "type": "string" }, "details_path": { "type": "string" },
"favicon": { "type": "string" } "favicon": { "type": "string" },
"action": {
"type": "object",
"required": [
"icon",
"title",
"path",
"method"
],
"properties": {
"icon": {
"type": "string",
"enum": [
"retry",
"play",
"cancel"
]
},
"title": { "type": "string" },
"path": { "type": "string" },
"method": { "$ref": "http_method.json" }
}
}
}, },
"additionalProperties": false "additionalProperties": false
} }
{
"type": "string",
"description": "HTTP methods that the API can specify to send.",
"enum": [ "post", "get", "put", "patch" ]
}
{
"type": "object",
"properties": {
"download_path": { "type": "string"},
"browse_path": { "type": "string"},
"keep_path": { "type": "string"},
"expired": { "type": "boolean" },
"expire_at": { "type": "string", "format": "date-time" }
},
"additionalProperties": false
}
{ {
"description": "Basic job information",
"type": "object", "type": "object",
"required": [ "required": [
"id", "id",
...@@ -13,12 +14,18 @@ ...@@ -13,12 +14,18 @@
"properties": { "properties": {
"id": { "type": "integer" }, "id": { "type": "integer" },
"name": { "type": "string" }, "name": { "type": "string" },
"started": { "type": "boolean" } , "started": {
"oneOf": [
{ "type": "string", "format": "date-time" },
{ "type": "boolean" }
]
},
"build_path": { "type": "string" }, "build_path": { "type": "string" },
"retry_path": { "type": "string" },
"playable": { "type": "boolean" }, "playable": { "type": "boolean" },
"created_at": { "type": "string" }, "created_at": { "type": "string" },
"updated_at": { "type": "string" }, "updated_at": { "type": "string" },
"status": { "$ref": "ci_detailed_status.json" } "status": { "$ref": "../ci_detailed_status.json" }
}, },
"additionalProperties": false "additionalProperties": true
} }
{
"allOf": [{ "$ref": "job.json" }],
"description": "An extension of job.json with more detailed information",
"properties": {
"artifact": { "$ref": "artifact.json" }
}
}
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
"groups": { "optional": true }, "groups": { "optional": true },
"latest_statuses": { "latest_statuses": {
"type": "array", "type": "array",
"items": { "$ref": "job.json" }, "items": { "$ref": "job/job.json" },
"optional": true "optional": true
}, },
"status": { "$ref": "ci_detailed_status.json" }, "status": { "$ref": "ci_detailed_status.json" },
......
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