diff options
author | Valery Sizov <vsv2711@gmail.com> | 2015-05-29 16:25:04 +0300 |
---|---|---|
committer | Valery Sizov <vsv2711@gmail.com> | 2015-06-03 16:36:54 +0300 |
commit | 85cd3463d6c023aea4441ecbd086c53e93a600cb (patch) | |
tree | fb8f7b3dc1e382c16278156c4cf3a390576aa8c2 | |
parent | 2999c8b41f8272b239e4364867012c9e3d4a997a (diff) | |
download | gitlab-ci-85cd3463d6c023aea4441ecbd086c53e93a600cb.tar.gz |
Implementation of configuration CI with gitlab-ci.yml
-rw-r--r-- | app/controllers/projects_controller.rb | 2 | ||||
-rw-r--r-- | app/models/build.rb | 8 | ||||
-rw-r--r-- | app/models/commit.rb | 25 | ||||
-rw-r--r-- | app/models/project.rb | 17 | ||||
-rw-r--r-- | app/services/create_commit_service.rb | 14 | ||||
-rw-r--r-- | app/views/builds/_build.html.haml | 2 | ||||
-rw-r--r-- | app/views/builds/show.html.haml | 2 | ||||
-rw-r--r-- | app/views/projects/_form.html.haml | 8 | ||||
-rw-r--r-- | db/migrate/20150528011012_remove_unused_fields.rb | 5 | ||||
-rw-r--r-- | db/migrate/20150529012113_add_tag_to_commits.rb | 5 | ||||
-rw-r--r-- | db/schema.rb | 6 | ||||
-rw-r--r-- | lib/gitlab_ci_yaml_parser.rb | 31 | ||||
-rw-r--r-- | lib/gitlab_ci_yaml_processor.rb | 96 |
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 · #{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 |