diff --git a/doc/api/job_artifacts.md b/doc/api/job_artifacts.md index 6d8c256d5aa26fdbcf0ee235acc292fb08f930f9..7c7847bf36885887a6141975a11585ff58d1131a 100644 --- a/doc/api/job_artifacts.md +++ b/doc/api/job_artifacts.md @@ -252,6 +252,7 @@ Example response: "finished_at": "2016-01-11T10:15:10.506Z", "duration": 97.0, "status": "failed", + "failure_reason": "script_failure", "tag": false, "web_url": "https://example.com/foo/bar/-/jobs/42", "user": null diff --git a/doc/api/jobs.md b/doc/api/jobs.md index 2a07e2d92c5abe0ddd0f870af4eb592372ea78ab..f3971fb57325229d308fab432ae09228ae1dc57f 100644 --- a/doc/api/jobs.md +++ b/doc/api/jobs.md @@ -71,6 +71,7 @@ Example of response "runner": null, "stage": "test", "status": "failed", + "failure_reason": "script_failure", "tag": false, "web_url": "https://example.com/foo/bar/-/jobs/7", "user": { @@ -126,6 +127,7 @@ Example of response "runner": null, "stage": "test", "status": "failed", + "failure_reason": "stuck_or_timeout_failure", "tag": false, "web_url": "https://example.com/foo/bar/-/jobs/6", "user": { @@ -207,6 +209,7 @@ Example of response "runner": null, "stage": "test", "status": "failed", + "failure_reason": "stuck_or_timeout_failure", "tag": false, "web_url": "https://example.com/foo/bar/-/jobs/6", "user": { @@ -271,6 +274,7 @@ Example of response "runner": null, "stage": "test", "status": "failed", + "failure_reason": "script_failure", "tag": false, "web_url": "https://example.com/foo/bar/-/jobs/7", "user": { @@ -443,6 +447,7 @@ Example of response "runner": null, "stage": "test", "status": "failed", + "failure_reason": "script_failure", "tag": false, "web_url": "https://example.com/foo/bar/-/jobs/8", "user": { diff --git a/lib/api/entities/ci/job_basic.rb b/lib/api/entities/ci/job_basic.rb index c31340f1ff079c8f3ce971d53a60d5657d5b786c..0badde4089ee0307ffabb49a057631a1ffd2c7d3 100644 --- a/lib/api/entities/ci/job_basic.rb +++ b/lib/api/entities/ci/job_basic.rb @@ -13,6 +13,7 @@ class JobBasic < Grape::Entity expose :user, with: ::API::Entities::User expose :commit, with: ::API::Entities::Commit expose :pipeline, with: ::API::Entities::Ci::PipelineBasic + expose :failure_reason, if: -> (job) { job.failed? } expose :web_url do |job, _options| Gitlab::Routing.url_helpers.project_job_url(job.project, job) diff --git a/spec/requests/api/ci/jobs_spec.rb b/spec/requests/api/ci/jobs_spec.rb index 4978630b5effc40486acddd52c0c9f332ed055b2..7c85cbc31a5bf3f25a8be38fdac283a886b7f736 100644 --- a/spec/requests/api/ci/jobs_spec.rb +++ b/spec/requests/api/ci/jobs_spec.rb @@ -428,6 +428,26 @@ def go end end + context 'when job succeeded' do + it 'does not return failure_reason' do + get api("/projects/#{project.id}/jobs/#{job.id}", api_user) + + expect(json_response).not_to include('failure_reason') + end + end + + context 'when job failed' do + let(:job) do + create(:ci_build, :failed, :tags, pipeline: pipeline) + end + + it 'returns failure_reason' do + get api("/projects/#{project.id}/jobs/#{job.id}", api_user) + + expect(json_response).to include('failure_reason') + end + end + context 'when trace artifact record exists with no stored file', :skip_before_request do before do create(:ci_job_artifact, :unarchived_trace_artifact, job: job, project: job.project)