summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorValery Sizov <vsv2711@gmail.com>2015-05-29 16:25:04 +0300
committerValery Sizov <vsv2711@gmail.com>2015-06-03 16:36:54 +0300
commit85cd3463d6c023aea4441ecbd086c53e93a600cb (patch)
treefb8f7b3dc1e382c16278156c4cf3a390576aa8c2
parent2999c8b41f8272b239e4364867012c9e3d4a997a (diff)
downloadgitlab-ci-85cd3463d6c023aea4441ecbd086c53e93a600cb.tar.gz
Implementation of configuration CI with gitlab-ci.yml
-rw-r--r--app/controllers/projects_controller.rb2
-rw-r--r--app/models/build.rb8
-rw-r--r--app/models/commit.rb25
-rw-r--r--app/models/project.rb17
-rw-r--r--app/services/create_commit_service.rb14
-rw-r--r--app/views/builds/_build.html.haml2
-rw-r--r--app/views/builds/show.html.haml2
-rw-r--r--app/views/projects/_form.html.haml8
-rw-r--r--db/migrate/20150528011012_remove_unused_fields.rb5
-rw-r--r--db/migrate/20150529012113_add_tag_to_commits.rb5
-rw-r--r--db/schema.rb6
-rw-r--r--lib/gitlab_ci_yaml_parser.rb31
-rw-r--r--lib/gitlab_ci_yaml_processor.rb96
13 files changed, 132 insertions, 89 deletions
diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb
index bad6ed2..ddf5ccf 100644
--- a/app/controllers/projects_controller.rb
+++ b/app/controllers/projects_controller.rb
@@ -121,7 +121,7 @@ class ProjectsController < ApplicationController
def project_params
params.require(:project).permit(:path, :timeout, :timeout_in_minutes, :default_ref, :always_build,
- :polling_interval, :public, :ssh_url_to_repo, :allow_git_fetch, :skip_refs, :email_recipients,
+ :polling_interval, :public, :ssh_url_to_repo, :allow_git_fetch, :email_recipients,
:email_add_pusher, :email_only_broken_builds, :coverage_regex, :shared_runners_enabled, :token)
end
end
diff --git a/app/models/build.rb b/app/models/build.rb
index c2b75b7..7305b28 100644
--- a/app/models/build.rb
+++ b/app/models/build.rb
@@ -197,12 +197,4 @@ class Build < ActiveRecord::Base
# so we just silentrly ignore error for now
end
end
-
- def for_tag?
- if job && job.build_tags
- true
- else
- false
- end
- end
end
diff --git a/app/models/commit.rb b/app/models/commit.rb
index b9a5100..14b558f 100644
--- a/app/models/commit.rb
+++ b/app/models/commit.rb
@@ -92,8 +92,11 @@ class Commit < ActiveRecord::Base
end
def create_builds
- builds_config.builds.each do |build_attrs|
- builds.create!({project: project}.merge(build_attrs))
+ filter_param = tag? ? :tags : :branches
+ config_processor.builds.each do |build_attrs|
+ if build_attrs[filter_param]
+ builds.create!({project: project}.merge(build_attrs.extract!(:name, :commands, :tag_list)))
+ end
end
end
@@ -112,23 +115,11 @@ class Commit < ActiveRecord::Base
end
def create_deploy_builds
- builds_config.deploy_builds.each do |build_attrs|
- refs = build_attrs.delete(:refs)
- next unless refs.empty? || refs_matches?(refs, ref)
+ config_processor.deploy_builds_for_ref(ref).each do |build_attrs|
builds.create!({project: project}.merge(build_attrs))
end
end
- # refs - list of refs. Glob syntax is supported. Ex. ["feature*", "bug"]
- # ref - ref that should be checked
- def refs_matches?(refs, ref)
- refs.map(&:strip).each do |ref_pattern|
- return true if File.fnmatch(ref_pattern, ref)
- end
-
- false
- end
-
def status
if success?
'success'
@@ -189,7 +180,7 @@ class Commit < ActiveRecord::Base
builds_without_retry.size > 1
end
- def builds_config
- @builds_config ||= GitlabCiYamlParser.new(push_data[:ci_yaml_file])
+ def config_processor
+ @config_processor ||= GitlabCiYamlProcessor.new(push_data[:ci_yaml_file])
end
end
diff --git a/app/models/project.rb b/app/models/project.rb
index 2498bdb..37bceb5 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -166,23 +166,6 @@ ls -la
self.timeout = value.to_i * 60
end
- def skip_ref?(ref_name)
- if skip_refs.present?
- skip_refs.delete(" ").split(",").each do |ref|
- return true if File.fnmatch(ref, ref_name)
- end
-
- false
- else
- false
- end
- end
-
- def create_commit_for_tag?(tag)
- jobs.where(build_tags: true).active.parallel.any? ||
- jobs.active.deploy.any?{ |job| job.run_for_ref?(tag)}
- end
-
def coverage_enabled?
coverage_regex.present?
end
diff --git a/app/services/create_commit_service.rb b/app/services/create_commit_service.rb
index efe70c9..2bf81e8 100644
--- a/app/services/create_commit_service.rb
+++ b/app/services/create_commit_service.rb
@@ -3,6 +3,7 @@ class CreateCommitService
before_sha = params[:before]
sha = params[:checkout_sha] || params[:after]
origin_ref = params[:ref]
+ config_processor = build_config_processor(params[:ci_yaml_file])
unless origin_ref && sha.present?
return false
@@ -19,11 +20,11 @@ class CreateCommitService
return false
end
- if origin_ref.start_with?('refs/tags/') && !project.create_commit_for_tag?(ref)
+ if origin_ref.start_with?('refs/tags/') && !config_processor.create_commit_for_tag?(ref)
return false
end
- if project.skip_ref?(ref)
+ if config_processor.skip_ref?(ref)
return false
end
@@ -34,6 +35,7 @@ class CreateCommitService
data = {
ref: ref,
sha: sha,
+ tag: origin_ref.start_with?('refs/tags/'),
before_sha: before_sha,
push_data: {
before: before_sha,
@@ -54,9 +56,15 @@ class CreateCommitService
commit.create_builds
if commit.builds.empty?
- commit.create_deploy_builds(ref)
+ commit.create_deploy_builds
end
commit
end
+
+ private
+
+ def build_config_processor(config_data)
+ @builds_config ||= GitlabCiYamlProcessor.new(config_data)
+ end
end
diff --git a/app/views/builds/_build.html.haml b/app/views/builds/_build.html.haml
index f405e6d..405ffc0 100644
--- a/app/views/builds/_build.html.haml
+++ b/app/views/builds/_build.html.haml
@@ -7,7 +7,7 @@
%strong Build ##{build.id}
%td
- - if build.for_tag?
+ - if build.commit.tag?
Tag
&middot;
#{build.ref}
diff --git a/app/views/builds/show.html.haml b/app/views/builds/show.html.haml
index 1851fa2..26925fb 100644
--- a/app/views/builds/show.html.haml
+++ b/app/views/builds/show.html.haml
@@ -32,7 +32,7 @@
.col-md-9
.build-head.alert{class: build_status_alert_class(@build)}
%h4
- - if @build.for_tag?
+ - if @build.commit.tag?
Build for tag
%code #{@build.ref}
- else
diff --git a/app/views/projects/_form.html.haml b/app/views/projects/_form.html.haml
index af78db9..7f3cc56 100644
--- a/app/views/projects/_form.html.haml
+++ b/app/views/projects/_form.html.haml
@@ -86,13 +86,7 @@
= f.label :token, "CI token", class: 'control-label'
.col-sm-10
= f.text_field :token, class: 'form-control', placeholder: 'xEeFCaDAB89'
- .form-group
- = f.label :skip_refs, "Skip refs", class: 'control-label'
- .col-sm-10
- = f.text_field :skip_refs, class: 'form-control', placeholder: 'branch1, branch2, feature/*'
- .light
- You can specify git references to skip CI builds. Accepts strings and glob pattern syntax
-
+
.form-actions
= f.submit 'Save changes', class: 'btn btn-save'
= link_to 'Cancel', projects_path, class: 'btn'
diff --git a/db/migrate/20150528011012_remove_unused_fields.rb b/db/migrate/20150528011012_remove_unused_fields.rb
new file mode 100644
index 0000000..c8f5e89
--- /dev/null
+++ b/db/migrate/20150528011012_remove_unused_fields.rb
@@ -0,0 +1,5 @@
+class RemoveUnusedFields < ActiveRecord::Migration
+ def change
+ remove_column :builds, :job_id, :integer
+ end
+end
diff --git a/db/migrate/20150529012113_add_tag_to_commits.rb b/db/migrate/20150529012113_add_tag_to_commits.rb
new file mode 100644
index 0000000..a8f7207
--- /dev/null
+++ b/db/migrate/20150529012113_add_tag_to_commits.rb
@@ -0,0 +1,5 @@
+class AddTagToCommits < ActiveRecord::Migration
+ def change
+ add_column :commits, :tag, :boolean, default: false
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 9876a2e..5360494 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -11,8 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.
-
-ActiveRecord::Schema.define(version: 20150528011001) do
+ActiveRecord::Schema.define(version: 20150529012113) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@@ -29,7 +28,6 @@ ActiveRecord::Schema.define(version: 20150528011001) do
t.integer "commit_id"
t.float "coverage"
t.text "commands"
- t.integer "job_id"
t.string "name"
t.boolean "deploy", default: false
end
@@ -47,6 +45,8 @@ ActiveRecord::Schema.define(version: 20150528011001) do
t.text "push_data"
t.datetime "created_at"
t.datetime "updated_at"
+ t.string "origin_ref"
+ t.boolean "tag", default: false
end
add_index "commits", ["project_id", "sha"], name: "index_commits_on_project_id_and_sha", using: :btree
diff --git a/lib/gitlab_ci_yaml_parser.rb b/lib/gitlab_ci_yaml_parser.rb
deleted file mode 100644
index 51458ad..0000000
--- a/lib/gitlab_ci_yaml_parser.rb
+++ /dev/null
@@ -1,31 +0,0 @@
-# Prototype of parser
-
-class GitlabCiYamlParser
- attr_reader :before_script, :jobs, :on_success
-
- def initialize(config)
- @before_script = ["pwd"]
- @jobs = [{script: "ruby -v", runner: "", name: "Rspec"}]
- @on_success = [script: "cap deploy production", refs: [], name: "Deploy"]
- end
-
- def builds
- @jobs.map do |job|
- {
- name: job[:name],
- commands: "#{@before_script.join("\n")}\n#{job[:script]}"
- }
- end
- end
-
- def deploy_builds
- @on_success.map do |job|
- {
- name: job[:name],
- commands: "#{@before_script.join("\n")}\n#{job[:script]}",
- deploy: true,
- refs: job[:refs]
- }
- end
- end
-end \ No newline at end of file
diff --git a/lib/gitlab_ci_yaml_processor.rb b/lib/gitlab_ci_yaml_processor.rb
new file mode 100644
index 0000000..3726a09
--- /dev/null
+++ b/lib/gitlab_ci_yaml_processor.rb
@@ -0,0 +1,96 @@
+class GitlabCiYamlProcessor
+ attr_reader :before_script, :skip_refs
+
+ def initialize(config)
+ @config = YAML.load(config).deep_symbolize_keys
+ @skip_refs = @config[:skip_refs] || []
+ @before_script = @config[:before_script] || []
+ @jobs = @config[:jobs]
+ @deploy_jobs = @config[:deploy_jobs]
+ end
+
+ def normalized_jobs
+ @jobs.map do |job|
+ if job.is_a?(String)
+ {script: job, runner: "", name: job[0..10], branches: true, tags: true}
+ else
+ {
+ script: job[:script],
+ runner: job[:runner] || "",
+ name: job[:name] || job[:script][0..10],
+ branches: job[:branches] || true,
+ tags: job[:tags] || true
+ }
+ end
+ end
+ end
+
+ def normalized_deploy_jobs
+ @deploy_jobs.map do |job|
+ if job.is_a?(String)
+ {script: job, refs: [], name: job[0..10].strip}
+ else
+ {
+ script: job[:script],
+ refs: job[:refs] || [],
+ name: job[:name] || job[:script][0..10]
+ }
+ end
+ end
+ end
+
+ def builds
+ normalized_jobs.map do |job|
+ {
+ name: job[:name],
+ commands: "#{@before_script.join("\n")}\n#{job[:script]}",
+ tag_list: job[:runner],
+ branches: job[:branches],
+ tags: job[:tag]
+ }
+ end
+ end
+
+ def deploy_builds
+ normalized_deploy_jobs.map do |job|
+ {
+ name: job[:name],
+ commands: "#{@before_script.join("\n")}\n#{job[:script]}",
+ deploy: true,
+ refs: job[:refs]
+ }
+ end
+ end
+
+ def create_commit_for_tag?(ref)
+ normalized_jobs.any?{|job| job[:tags] == true} ||
+ normalized_deploy_jobs.any?{|job| job[:refs].empty? || refs_matches?(job[:refs], ref)}
+ end
+
+ def deploy_builds_for_ref(ref)
+ deploy_builds.select do |build_attrs|
+ refs = build_attrs.delete(:refs)
+ refs.empty? || refs_matches?(refs, ref)
+ end
+ end
+
+ def skip_ref?(ref_name)
+ @skip_refs.split(",").each do |ref|
+ return true if File.fnmatch(ref, ref_name)
+ end
+
+ false
+ end
+
+ private
+
+ # refs - list of refs. Glob syntax is supported. Ex. ["feature*", "bug"]
+ # ref - ref that should be checked
+ def refs_matches?(refs, ref)
+ refs.map(&:strip).each do |ref_pattern|
+ return true if File.fnmatch(ref_pattern, ref)
+ end
+
+ false
+ end
+end \ No newline at end of file