summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/models/commit.rb39
-rw-r--r--app/views/commits/show.html.haml8
-rw-r--r--db/migrate/20150616001155_add_errors_to_commit.rb5
-rw-r--r--db/schema.rb5
-rw-r--r--lib/gitlab_ci_yaml_processor.rb46
-rw-r--r--spec/lib/gitlab_ci_yaml_processor_spec.rb10
6 files changed, 102 insertions, 11 deletions
diff --git a/app/models/commit.rb b/app/models/commit.rb
index 1dc3e15..da755bc 100644
--- a/app/models/commit.rb
+++ b/app/models/commit.rb
@@ -93,9 +93,19 @@ class Commit < ActiveRecord::Base
def create_builds
return if skip_ci?
- return unless config_processor.valid?
- config_processor.builds_for_ref(ref, tag).each do |build_attrs|
+ unless config_processor.valid?
+ save_yaml_error(config_processor.errors.join(",")) and return
+ end
+
+ begin
+ builds_for_ref = config_processor.builds_for_ref(ref, tag)
+ rescue Exception => e
+ logger.error e.message + "\n" + e.backtrace.join("\n")
+ save_yaml_error("Undefined yaml error") and return
+ end
+
+ builds_for_ref.each do |build_attrs|
builds.create!({
project: project,
name: build_attrs[:name],
@@ -121,9 +131,19 @@ class Commit < ActiveRecord::Base
def create_deploy_builds
return if skip_ci?
- return unless config_processor.valid?
- config_processor.deploy_builds_for_ref(ref, tag).each do |build_attrs|
+ unless config_processor.valid?
+ save_yaml_error(config_processor.errors.join(",")) and return
+ end
+
+ begin
+ deploy_builds_for_ref = config_processor.deploy_builds_for_ref(ref, tag)
+ rescue Exception => e
+ logger.error e.message + "\n" + e.backtrace.join("\n")
+ save_yaml_error("Undefined yaml error") and return
+ end
+
+ deploy_builds_for_ref.each do |build_attrs|
builds.create!({
project: project,
name: build_attrs[:name],
@@ -135,6 +155,10 @@ class Commit < ActiveRecord::Base
end
def status
+ if yaml_errors.present?
+ return 'failed'
+ end
+
if success?
'success'
elsif pending?
@@ -207,4 +231,11 @@ class Commit < ActiveRecord::Base
false
end
end
+
+ private
+
+ def save_yaml_error(error)
+ self.yaml_errors = error
+ save
+ end
end
diff --git a/app/views/commits/show.html.haml b/app/views/commits/show.html.haml
index 3353f78..9ca6222 100644
--- a/app/views/commits/show.html.haml
+++ b/app/views/commits/show.html.haml
@@ -33,7 +33,13 @@
%span.attr-name Created at:
#{@commit.created_at.to_s(:short)}
-
+- if @commit.yaml_errors.present?
+ .bs-callout.bs-callout-danger
+ %h4 Found errors in your .gitlab-ci.yml:
+ %ul
+ - @commit.yaml_errors.split(",").each do |error|
+ %li= error
+
%h3 Status
.build.alert{class: commit_status_alert_class(@commit)}
diff --git a/db/migrate/20150616001155_add_errors_to_commit.rb b/db/migrate/20150616001155_add_errors_to_commit.rb
new file mode 100644
index 0000000..fe9f7b9
--- /dev/null
+++ b/db/migrate/20150616001155_add_errors_to_commit.rb
@@ -0,0 +1,5 @@
+class AddErrorsToCommit < ActiveRecord::Migration
+ def change
+ add_column :commits, :yaml_errors, :text
+ end
+end \ No newline at end of file
diff --git a/db/schema.rb b/db/schema.rb
index 9e1a0df..2046dcc 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -11,7 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema.define(version: 20150605002131) do
+ActiveRecord::Schema.define(version: 20150616001155) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@@ -45,7 +45,8 @@ ActiveRecord::Schema.define(version: 20150605002131) do
t.text "push_data"
t.datetime "created_at"
t.datetime "updated_at"
- t.boolean "tag", default: false
+ t.boolean "tag", default: false
+ t.text "yaml_errors"
end
add_index "commits", ["project_id", "sha"], name: "index_commits_on_project_id_and_sha", using: :btree
diff --git a/lib/gitlab_ci_yaml_processor.rb b/lib/gitlab_ci_yaml_processor.rb
index 67903d5..51f412a 100644
--- a/lib/gitlab_ci_yaml_processor.rb
+++ b/lib/gitlab_ci_yaml_processor.rb
@@ -2,7 +2,7 @@ class GitlabCiYamlProcessor
attr_reader :before_script, :skip_refs, :errors
def initialize(config)
- @valid = true
+ @errors = []
@config = YAML.load(config).deep_symbolize_keys
@before_script = @config[:before_script] || []
@@ -14,11 +14,12 @@ class GitlabCiYamlProcessor
@deploy_jobs = @config.select{|key, value| value[:type] == "deploy"}
rescue Exception => e
- @valid = false
+ @errors << "Yaml file is invalid"
end
def valid?
- @valid
+ validate!
+ !@errors.any?
end
def deploy_builds_for_ref(ref, tag = false)
@@ -94,4 +95,43 @@ class GitlabCiYamlProcessor
script
end
end
+
+ def validate!
+ unless @config.is_a? Hash
+ @errors << "should be a hash"
+ return false
+ end
+
+ @jobs.each do |name, job|
+ if job[:tags] && !job[:tags].is_a?(Array)
+ @errors << "#{name} job: tags parameter should be an array"
+ end
+
+ if job[:only] && !job[:only].is_a?(Array)
+ @errors << "#{name} job: only parameter should be an array"
+ end
+
+ if job[:except] && !job[:except].is_a?(Array)
+ @errors << "#{name} job: except parameter should be an array"
+ end
+ end
+
+ @deploy_jobs.each do |name, job|
+ if job[:tags] && !job[:tags].is_a?(Array)
+ @errors << "#{name} deploy job: tags parameter should be an array"
+ end
+
+ if job[:only] && !job[:only].is_a?(Array)
+ @errors << "#{name} deploy job: only parameter should be an array"
+ end
+
+ if job[:except] && !job[:except].is_a?(Array)
+ @errors << "#{name} deploy job: except parameter should be an array"
+ end
+ end
+
+ true
+ rescue
+ @errors << "Undefined error"
+ end
end
diff --git a/spec/lib/gitlab_ci_yaml_processor_spec.rb b/spec/lib/gitlab_ci_yaml_processor_spec.rb
index 14d273a..b101e33 100644
--- a/spec/lib/gitlab_ci_yaml_processor_spec.rb
+++ b/spec/lib/gitlab_ci_yaml_processor_spec.rb
@@ -120,10 +120,18 @@ describe GitlabCiYamlProcessor do
end
describe "Error handling" do
- it "indicated that object is invalid" do
+ it "indicates that object is invalid" do
config_processor = GitlabCiYamlProcessor.new("invalid_yaml\n!ccdvlf%612334@@@@")
config_processor.valid?.should be_false
end
+
+ it "returns errors" do
+ config = YAML.dump({rspec: {tags: "mysql"}})
+ config_processor = GitlabCiYamlProcessor.new(config)
+
+ config_processor.valid?.should be_false
+ config_processor.errors.should == ["rspec job: tags parameter should be an array"]
+ end
end
end \ No newline at end of file