Commit f408300e authored by Bryce Johnson's avatar Bryce Johnson

Merge branch 'master' into issues-filters-reset-btn

parents c7f74256 a83c5ff4
......@@ -92,6 +92,7 @@ v 8.12.0 (unreleased)
- Refactor the triggers page and documentation !6217
- Show values of CI trigger variables only when clicked (Katarzyna Kobierska Ula Budziszewska)
- Use default clone protocol on "check out, review, and merge locally" help page URL
- API for Ci Lint !5953 (Katarzyna Kobierska Urszula Budziszewska)
v 8.11.5 (unreleased)
- Optimize branch lookups and force a repository reload for Repository#find_branch
......
......@@ -490,6 +490,6 @@
.ci-status-icon-created {
svg {
fill: $table-text-gray;
fill: $gray-darkest;
}
}
......@@ -7,19 +7,14 @@ module Ci
def create
@content = params[:content]
@error = Ci::GitlabCiYamlProcessor.validation_message(@content)
@status = @error.blank?
if @content.blank?
@status = false
@error = "Please provide content of .gitlab-ci.yml"
else
if @error.blank?
@config_processor = Ci::GitlabCiYamlProcessor.new(@content)
@stages = @config_processor.stages
@builds = @config_processor.builds
@status = true
end
rescue Ci::GitlabCiYamlProcessor::ValidationError, Psych::SyntaxError => e
@error = e.message
@status = false
rescue
@error = 'Undefined error'
@status = false
......
......@@ -41,8 +41,9 @@ following locations:
- [Sidekiq metrics](sidekiq_metrics.md)
- [System Hooks](system_hooks.md)
- [Tags](tags.md)
- [Users](users.md)
- [Todos](todos.md)
- [Users](users.md)
- [Validate CI configuration](ci/lint.md)
### Internal CI API
......
# Validate the .gitlab-ci.yml
> [Introduced][ce-5953] in GitLab 8.12.
Checks if your .gitlab-ci.yml file is valid.
```
POST ci/lint
```
| Attribute | Type | Required | Description |
| ---------- | ------- | -------- | -------- |
| `content` | string | yes | the .gitlab-ci.yaml content|
```bash
curl --header "Content-Type: application/json" https://gitlab.example.com/api/v3/ci/lint --data '{"content": "{ \"image\": \"ruby:2.1\", \"services\": [\"postgres\"], \"before_script\": [\"gem install bundler\", \"bundle install\", \"bundle exec rake db:create\"], \"variables\": {\"DB_NAME\": \"postgres\"}, \"types\": [\"test\", \"deploy\", \"notify\"], \"rspec\": { \"script\": \"rake spec\", \"tags\": [\"ruby\", \"postgres\"], \"only\": [\"branches\"]}}"}'
```
Be sure to copy paste the exact contents of `.gitlab-ci.yml` as YAML is very picky about indentation and spaces.
Example responses:
* Valid content:
```json
{
"status": "valid",
"errors": []
}
```
* Invalid content:
```json
{
"status": "invalid",
"errors": [
"variables config should be a hash of key value pairs"
]
}
```
* Without the content attribute:
```json
{
"error": "content is missing"
}
```
......@@ -110,8 +110,8 @@ POST /projects/:id/members
| `expires_at` | string | no | A date string in the format YEAR-MONTH-DAY |
```bash
curl --request POST --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v3/groups/:id/members/:user_id?access_level=30
curl --request POST --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v3/projects/:id/members/:user_id?access_level=30
curl --request POST --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" --data "user_id=1&access_level=30" https://gitlab.example.com/api/v3/groups/:id/members
curl --request POST --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" --data "user_id=1&access_level=30" https://gitlab.example.com/api/v3/projects/:id/members
```
Example response:
......
......@@ -86,7 +86,7 @@ if your available memory changes.
Notice: The 25 workers of Sidekiq will show up as separate processes in your process overview (such as top or htop) but they share the same RAM allocation since Sidekiq is a multithreaded application. Please see the section below about Unicorn workers for information about many you need of those.
## Gitlab Runner
## GitLab Runner
We strongly advise against installing GitLab Runner on the same machine you plan
to install GitLab on. Depending on how you decide to configure GitLab Runner and
......
......@@ -45,6 +45,7 @@ module API
mount ::API::Keys
mount ::API::Labels
mount ::API::LicenseTemplates
mount ::API::Lint
mount ::API::Members
mount ::API::MergeRequests
mount ::API::Milestones
......
module API
class Lint < Grape::API
namespace :ci do
desc 'Validation of .gitlab-ci.yml content'
params do
requires :content, type: String, desc: 'Content of .gitlab-ci.yml'
end
post '/lint' do
error = Ci::GitlabCiYamlProcessor.validation_message(params[:content])
status 200
if error.blank?
{ status: 'valid', errors: [] }
else
{ status: 'invalid', errors: [error] }
end
end
end
end
end
......@@ -78,6 +78,17 @@ module Ci
}
end
def self.validation_message(content)
return 'Please provide content of .gitlab-ci.yml' if content.blank?
begin
Ci::GitlabCiYamlProcessor.new(content)
nil
rescue ValidationError, Psych::SyntaxError => e
e.message
end
end
private
def initial_parsing
......
......@@ -1250,5 +1250,40 @@ EOT
end
end
end
describe "#validation_message" do
context "when the YAML could not be parsed" do
it "returns an error about invalid configutaion" do
content = YAML.dump("invalid: yaml: test")
expect(GitlabCiYamlProcessor.validation_message(content))
.to eq "Invalid configuration format"
end
end
context "when the tags parameter is invalid" do
it "returns an error about invalid tags" do
content = YAML.dump({ rspec: { script: "test", tags: "mysql" } })
expect(GitlabCiYamlProcessor.validation_message(content))
.to eq "jobs:rspec tags should be an array of strings"
end
end
context "when YAML content is empty" do
it "returns an error about missing content" do
expect(GitlabCiYamlProcessor.validation_message(''))
.to eq "Please provide content of .gitlab-ci.yml"
end
end
context "when the YAML is valid" do
it "does not return any errors" do
content = File.read(Rails.root.join('spec/support/gitlab_stubs/gitlab_ci.yml'))
expect(GitlabCiYamlProcessor.validation_message(content)).to be_nil
end
end
end
end
end
require 'spec_helper'
describe API::Lint, api: true do
include ApiHelpers
describe 'POST /ci/lint' do
context 'with valid .gitlab-ci.yaml content' do
let(:yaml_content) do
File.read(Rails.root.join('spec/support/gitlab_stubs/gitlab_ci.yml'))
end
it 'passes validation' do
post api('/ci/lint'), { content: yaml_content }
expect(response).to have_http_status(200)
expect(json_response).to be_an Hash
expect(json_response['status']).to eq('valid')
expect(json_response['errors']).to eq([])
end
end
context 'with an invalid .gitlab_ci.yml' do
it 'responds with errors about invalid syntax' do
post api('/ci/lint'), { content: 'invalid content' }
expect(response).to have_http_status(200)
expect(json_response['status']).to eq('invalid')
expect(json_response['errors']).to eq(['Invalid configuration format'])
end
it "responds with errors about invalid configuration" do
post api('/ci/lint'), { content: '{ image: "ruby:2.1", services: ["postgres"] }' }
expect(response).to have_http_status(200)
expect(json_response['status']).to eq('invalid')
expect(json_response['errors']).to eq(['jobs config should contain at least one visible job'])
end
end
context 'without the content parameter' do
it 'responds with validation error about missing content' do
post api('/ci/lint')
expect(response).to have_http_status(400)
expect(json_response['error']).to eq('content is missing')
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