Commit 55762622 authored by Matt Christ's avatar Matt Christ Committed by Bilal Aslam

Add optional include_jobs param for CI lint APIs

The optional param expose the jobs field and returns in the JSON response like UI the version.

Changelog: changed
parent 58b44a0e
...@@ -30,6 +30,7 @@ POST /ci/lint ...@@ -30,6 +30,7 @@ POST /ci/lint
| ---------- | ------- | -------- | -------- | | ---------- | ------- | -------- | -------- |
| `content` | string | yes | The CI/CD configuration content. | | `content` | string | yes | The CI/CD configuration content. |
| `include_merged_yaml` | boolean | no | If the [expanded CI/CD configuration](#yaml-expansion) should be included in the response. | | `include_merged_yaml` | boolean | no | If the [expanded CI/CD configuration](#yaml-expansion) should be included in the response. |
| `include_jobs` | boolean | no | If the list of jobs should be included in the response. This is false by default. |
```shell ```shell
curl --header "Content-Type: application/json" --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/ci/lint" --data '{"content": "{ \"image\": \"ruby:2.6\", \"services\": [\"postgres\"], \"before_script\": [\"bundle install\", \"bundle exec rake db:create\"], \"variables\": {\"DB_NAME\": \"postgres\"}, \"types\": [\"test\", \"deploy\", \"notify\"], \"rspec\": { \"script\": \"rake spec\", \"tags\": [\"ruby\", \"postgres\"], \"only\": [\"branches\"]}}"}' curl --header "Content-Type: application/json" --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/ci/lint" --data '{"content": "{ \"image\": \"ruby:2.6\", \"services\": [\"postgres\"], \"before_script\": [\"bundle install\", \"bundle exec rake db:create\"], \"variables\": {\"DB_NAME\": \"postgres\"}, \"types\": [\"test\", \"deploy\", \"notify\"], \"rspec\": { \"script\": \"rake spec\", \"tags\": [\"ruby\", \"postgres\"], \"only\": [\"branches\"]}}"}'
...@@ -91,7 +92,7 @@ work for CI configuration added with [`include: local`](../ci/yaml/index.md#incl ...@@ -91,7 +92,7 @@ work for CI configuration added with [`include: local`](../ci/yaml/index.md#incl
or with [`extends:`](../ci/yaml/index.md#extends). or with [`extends:`](../ci/yaml/index.md#extends).
Example contents of a `.gitlab-ci.yml` passed to the CI Lint API with Example contents of a `.gitlab-ci.yml` passed to the CI Lint API with
`include_merged_yaml` set as true: `include_merged_yaml` and `include_jobs` set as true:
```yaml ```yaml
include: include:
...@@ -118,7 +119,39 @@ Example response: ...@@ -118,7 +119,39 @@ Example response:
{ {
"status": "valid", "status": "valid",
"errors": [], "errors": [],
"merged_yaml": "---\n:another_test:\n :stage: test\n :script: echo 2\n:test:\n :stage: test\n :script: echo 1\n" "merged_yaml": "---\n:another_test:\n :stage: test\n :script: echo 2\n:test:\n :stage: test\n :script: echo 1\n",
"jobs": [
{
"name":"test",
"stage":"test",
"before_script":[],
"script":["echo 1"],
"after_script":[],
"tag_list":[],
"environment":null,
"when":"on_success",
"allow_failure":false,
"only":{
"refs":["branches","tags"]
},
"except":null
},
{
"name":"another_test",
"stage":"test",
"before_script":[],
"script":["echo 2"],
"after_script":[],
"tag_list":[],
"environment":null,
"when":"on_success",
"allow_failure":false,
"only":{
"refs":["branches","tags"]
},
"except":null
}
]
} }
``` ```
...@@ -137,6 +170,7 @@ POST /projects/:id/ci/lint ...@@ -137,6 +170,7 @@ POST /projects/:id/ci/lint
| ---------- | ------- | -------- | -------- | | ---------- | ------- | -------- | -------- |
| `content` | string | yes | The CI/CD configuration content. | | `content` | string | yes | The CI/CD configuration content. |
| `dry_run` | boolean | no | Run [pipeline creation simulation](../ci/lint.md#pipeline-simulation), or only do static check. This is false by default. | | `dry_run` | boolean | no | Run [pipeline creation simulation](../ci/lint.md#pipeline-simulation), or only do static check. This is false by default. |
| `include_jobs` | boolean | no | If the list of jobs that would exist in a static check or pipeline simulation should be included in the response. This is false by default. |
Example request: Example request:
...@@ -185,6 +219,7 @@ GET /projects/:id/ci/lint ...@@ -185,6 +219,7 @@ GET /projects/:id/ci/lint
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
| ---------- | ------- | -------- | -------- | | ---------- | ------- | -------- | -------- |
| `dry_run` | boolean | no | Run pipeline creation simulation, or only do static check. | | `dry_run` | boolean | no | Run pipeline creation simulation, or only do static check. |
| `include_jobs` | boolean | no | If the list of jobs that would exist in a static check or pipeline simulation should be included in the response. This is false by default. |
Example request: Example request:
......
...@@ -9,6 +9,7 @@ module API ...@@ -9,6 +9,7 @@ module API
expose :errors expose :errors
expose :warnings expose :warnings
expose :merged_yaml expose :merged_yaml
expose :jobs, if: -> (result, options) { options[:include_jobs] }
end end
end end
end end
......
...@@ -9,6 +9,7 @@ module API ...@@ -9,6 +9,7 @@ module API
params do params do
requires :content, type: String, desc: 'Content of .gitlab-ci.yml' requires :content, type: String, desc: 'Content of .gitlab-ci.yml'
optional :include_merged_yaml, type: Boolean, desc: 'Whether or not to include merged CI config yaml in the response' optional :include_merged_yaml, type: Boolean, desc: 'Whether or not to include merged CI config yaml in the response'
optional :include_jobs, type: Boolean, desc: 'Whether or not to include CI jobs in the response'
end end
post '/lint' do post '/lint' do
unauthorized! if (Gitlab::CurrentSettings.signup_disabled? || Gitlab::CurrentSettings.signup_limited?) && current_user.nil? unauthorized! if (Gitlab::CurrentSettings.signup_disabled? || Gitlab::CurrentSettings.signup_limited?) && current_user.nil?
...@@ -17,7 +18,7 @@ module API ...@@ -17,7 +18,7 @@ module API
.validate(params[:content], dry_run: false) .validate(params[:content], dry_run: false)
status 200 status 200
Entities::Ci::Lint::Result.represent(result, current_user: current_user).serializable_hash.tap do |presented_result| Entities::Ci::Lint::Result.represent(result, current_user: current_user, include_jobs: params[:include_jobs]).serializable_hash.tap do |presented_result|
presented_result[:status] = presented_result[:valid] ? 'valid' : 'invalid' presented_result[:status] = presented_result[:valid] ? 'valid' : 'invalid'
presented_result.delete(:merged_yaml) unless params[:include_merged_yaml] presented_result.delete(:merged_yaml) unless params[:include_merged_yaml]
end end
...@@ -30,6 +31,7 @@ module API ...@@ -30,6 +31,7 @@ module API
end end
params do params do
optional :dry_run, type: Boolean, default: false, desc: 'Run pipeline creation simulation, or only do static check.' optional :dry_run, type: Boolean, default: false, desc: 'Run pipeline creation simulation, or only do static check.'
optional :include_jobs, type: Boolean, desc: 'Whether or not to include CI jobs in the response'
end end
get ':id/ci/lint' do get ':id/ci/lint' do
authorize! :download_code, user_project authorize! :download_code, user_project
...@@ -39,7 +41,7 @@ module API ...@@ -39,7 +41,7 @@ module API
.new(project: user_project, current_user: current_user) .new(project: user_project, current_user: current_user)
.validate(content, dry_run: params[:dry_run]) .validate(content, dry_run: params[:dry_run])
present result, with: Entities::Ci::Lint::Result, current_user: current_user present result, with: Entities::Ci::Lint::Result, current_user: current_user, include_jobs: params[:include_jobs]
end end
end end
...@@ -50,6 +52,7 @@ module API ...@@ -50,6 +52,7 @@ module API
params do params do
requires :content, type: String, desc: 'Content of .gitlab-ci.yml' requires :content, type: String, desc: 'Content of .gitlab-ci.yml'
optional :dry_run, type: Boolean, default: false, desc: 'Run pipeline creation simulation, or only do static check.' optional :dry_run, type: Boolean, default: false, desc: 'Run pipeline creation simulation, or only do static check.'
optional :include_jobs, type: Boolean, desc: 'Whether or not to include CI jobs in the response'
end end
post ':id/ci/lint' do post ':id/ci/lint' do
authorize! :create_pipeline, user_project authorize! :create_pipeline, user_project
...@@ -59,7 +62,7 @@ module API ...@@ -59,7 +62,7 @@ module API
.validate(params[:content], dry_run: params[:dry_run]) .validate(params[:content], dry_run: params[:dry_run])
status 200 status 200
present result, with: Entities::Ci::Lint::Result, current_user: current_user present result, with: Entities::Ci::Lint::Result, current_user: current_user, include_jobs: params[:include_jobs]
end end
end end
end end
......
...@@ -102,6 +102,13 @@ RSpec.describe API::Lint do ...@@ -102,6 +102,13 @@ RSpec.describe API::Lint do
expect(response).to have_gitlab_http_status(:ok) expect(response).to have_gitlab_http_status(:ok)
expect(json_response).to have_key('merged_yaml') expect(json_response).to have_key('merged_yaml')
end end
it 'outputs jobs' do
post api('/ci/lint', api_user), params: { content: yaml_content, include_jobs: true }
expect(response).to have_gitlab_http_status(:ok)
expect(json_response).to have_key('jobs')
end
end end
context 'with valid .gitlab-ci.yaml with warnings' do context 'with valid .gitlab-ci.yaml with warnings' do
...@@ -136,6 +143,13 @@ RSpec.describe API::Lint do ...@@ -136,6 +143,13 @@ RSpec.describe API::Lint do
expect(response).to have_gitlab_http_status(:ok) expect(response).to have_gitlab_http_status(:ok)
expect(json_response).to have_key('merged_yaml') expect(json_response).to have_key('merged_yaml')
end end
it 'outputs jobs' do
post api('/ci/lint', api_user), params: { content: yaml_content, include_jobs: true }
expect(response).to have_gitlab_http_status(:ok)
expect(json_response).to have_key('jobs')
end
end end
context 'with invalid configuration' do context 'with invalid configuration' do
...@@ -156,6 +170,13 @@ RSpec.describe API::Lint do ...@@ -156,6 +170,13 @@ RSpec.describe API::Lint do
expect(response).to have_gitlab_http_status(:ok) expect(response).to have_gitlab_http_status(:ok)
expect(json_response).to have_key('merged_yaml') expect(json_response).to have_key('merged_yaml')
end end
it 'outputs jobs' do
post api('/ci/lint', api_user), params: { content: yaml_content, include_jobs: true }
expect(response).to have_gitlab_http_status(:ok)
expect(json_response).to have_key('jobs')
end
end end
end end
...@@ -171,10 +192,11 @@ RSpec.describe API::Lint do ...@@ -171,10 +192,11 @@ RSpec.describe API::Lint do
end end
describe 'GET /projects/:id/ci/lint' do describe 'GET /projects/:id/ci/lint' do
subject(:ci_lint) { get api("/projects/#{project.id}/ci/lint", api_user), params: { dry_run: dry_run } } subject(:ci_lint) { get api("/projects/#{project.id}/ci/lint", api_user), params: { dry_run: dry_run, include_jobs: include_jobs } }
let(:project) { create(:project, :repository) } let(:project) { create(:project, :repository) }
let(:dry_run) { nil } let(:dry_run) { nil }
let(:include_jobs) { nil }
RSpec.shared_examples 'valid config with warnings' do RSpec.shared_examples 'valid config with warnings' do
it 'passes validation with warnings' do it 'passes validation with warnings' do
...@@ -359,6 +381,30 @@ RSpec.describe API::Lint do ...@@ -359,6 +381,30 @@ RSpec.describe API::Lint do
it_behaves_like 'valid config without warnings' it_behaves_like 'valid config without warnings'
end end
context 'when running with include jobs' do
let(:include_jobs) { true }
it_behaves_like 'valid config without warnings'
it 'returns jobs key' do
ci_lint
expect(json_response).to have_key('jobs')
end
end
context 'when running without include jobs' do
let(:include_jobs) { false }
it_behaves_like 'valid config without warnings'
it 'does not return jobs key' do
ci_lint
expect(json_response).not_to have_key('jobs')
end
end
context 'With warnings' do context 'With warnings' do
let(:yaml_content) { { job: { script: 'ls', rules: [{ when: 'always' }] } }.to_yaml } let(:yaml_content) { { job: { script: 'ls', rules: [{ when: 'always' }] } }.to_yaml }
...@@ -386,15 +432,40 @@ RSpec.describe API::Lint do ...@@ -386,15 +432,40 @@ RSpec.describe API::Lint do
it_behaves_like 'invalid config' it_behaves_like 'invalid config'
end end
context 'when running with include jobs' do
let(:include_jobs) { true }
it_behaves_like 'invalid config'
it 'returns jobs key' do
ci_lint
expect(json_response).to have_key('jobs')
end
end
context 'when running without include jobs' do
let(:include_jobs) { false }
it_behaves_like 'invalid config'
it 'does not return jobs key' do
ci_lint
expect(json_response).not_to have_key('jobs')
end
end
end end
end end
end end
describe 'POST /projects/:id/ci/lint' do describe 'POST /projects/:id/ci/lint' do
subject(:ci_lint) { post api("/projects/#{project.id}/ci/lint", api_user), params: { dry_run: dry_run, content: yaml_content } } subject(:ci_lint) { post api("/projects/#{project.id}/ci/lint", api_user), params: { dry_run: dry_run, content: yaml_content, include_jobs: include_jobs } }
let(:project) { create(:project, :repository) } let(:project) { create(:project, :repository) }
let(:dry_run) { nil } let(:dry_run) { nil }
let(:include_jobs) { nil }
let_it_be(:api_user) { create(:user) } let_it_be(:api_user) { create(:user) }
...@@ -562,6 +633,30 @@ RSpec.describe API::Lint do ...@@ -562,6 +633,30 @@ RSpec.describe API::Lint do
it_behaves_like 'valid project config' it_behaves_like 'valid project config'
end end
context 'when running with include jobs param' do
let(:include_jobs) { true }
it_behaves_like 'valid project config'
it 'contains jobs key' do
ci_lint
expect(json_response).to have_key('jobs')
end
end
context 'when running without include jobs param' do
let(:include_jobs) { false }
it_behaves_like 'valid project config'
it 'does not contain jobs key' do
ci_lint
expect(json_response).not_to have_key('jobs')
end
end
end end
context 'with invalid .gitlab-ci.yml content' do context 'with invalid .gitlab-ci.yml content' do
...@@ -580,6 +675,30 @@ RSpec.describe API::Lint do ...@@ -580,6 +675,30 @@ RSpec.describe API::Lint do
it_behaves_like 'invalid project config' it_behaves_like 'invalid project config'
end end
context 'when running with include jobs set to false' do
let(:include_jobs) { false }
it_behaves_like 'invalid project config'
it 'does not contain jobs key' do
ci_lint
expect(json_response).not_to have_key('jobs')
end
end
context 'when running with param include jobs' do
let(:include_jobs) { true }
it_behaves_like 'invalid project config'
it 'contains jobs key' do
ci_lint
expect(json_response).to have_key('jobs')
end
end
end end
end end
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