diff options
author | Kamil Trzcinski <ayufan@ayufan.eu> | 2015-08-06 16:44:45 +0200 |
---|---|---|
committer | Kamil Trzcinski <ayufan@ayufan.eu> | 2015-08-21 14:49:36 +0100 |
commit | ae8f755fc81160b695e44bbfb00b1225527bf5f9 (patch) | |
tree | 755e60bad6f63014e3ae7eea8cd0ad018a611956 /app | |
parent | 1ba150e1cf346239eafec3d530b3de3325501893 (diff) | |
download | gitlab-ci-ae8f755fc81160b695e44bbfb00b1225527bf5f9.tar.gz |
Initial support for build triggers
Diffstat (limited to 'app')
-rw-r--r-- | app/controllers/triggers_controller.rb | 41 | ||||
-rw-r--r-- | app/helpers/triggers_helper.rb | 5 | ||||
-rw-r--r-- | app/models/build.rb | 52 | ||||
-rw-r--r-- | app/models/commit.rb | 37 | ||||
-rw-r--r-- | app/models/project.rb | 1 | ||||
-rw-r--r-- | app/models/trigger.rb | 35 | ||||
-rw-r--r-- | app/models/trigger_request.rb | 19 | ||||
-rw-r--r-- | app/services/create_trigger_request_service.rb | 15 | ||||
-rw-r--r-- | app/views/builds/_build.html.haml | 2 | ||||
-rw-r--r-- | app/views/builds/show.html.haml | 17 | ||||
-rw-r--r-- | app/views/layouts/_nav_project.html.haml | 4 | ||||
-rw-r--r-- | app/views/triggers/_trigger.html.haml | 14 | ||||
-rw-r--r-- | app/views/triggers/index.html.haml | 67 |
13 files changed, 273 insertions, 36 deletions
diff --git a/app/controllers/triggers_controller.rb b/app/controllers/triggers_controller.rb new file mode 100644 index 0000000..b942051 --- /dev/null +++ b/app/controllers/triggers_controller.rb @@ -0,0 +1,41 @@ +class TriggersController < ApplicationController + before_filter :authenticate_user! + before_filter :project + before_filter :authorize_access_project! + before_filter :authorize_manage_project! + + layout 'project' + + def index + @triggers = @project.triggers + @trigger = Trigger.new + end + + def create + @trigger = @project.triggers.new + @trigger.save + + if @trigger.valid? + redirect_to project_triggers_path(@project) + else + @triggers = @project.triggers.select(&:persisted?) + render :index + end + end + + def destroy + trigger.destroy + + redirect_to project_triggers_path(@project) + end + + private + + def trigger + @trigger ||= @project.triggers.find(params[:id]) + end + + def project + @project = Project.find(params[:project_id]) + end +end diff --git a/app/helpers/triggers_helper.rb b/app/helpers/triggers_helper.rb new file mode 100644 index 0000000..ac93bf6 --- /dev/null +++ b/app/helpers/triggers_helper.rb @@ -0,0 +1,5 @@ +module TriggersHelper + def build_trigger_url(project_id, ref_name) + "#{Settings.gitlab_ci.url}/api/v1/projects/#{project_id}/refs/#{ref_name}/trigger" + end +end diff --git a/app/models/build.rb b/app/models/build.rb index da52f0a..913a47c 100644 --- a/app/models/build.rb +++ b/app/models/build.rb @@ -2,23 +2,25 @@ # # Table name: builds # -# id :integer not null, primary key -# project_id :integer -# status :string(255) -# finished_at :datetime -# trace :text -# created_at :datetime -# updated_at :datetime -# started_at :datetime -# runner_id :integer -# commit_id :integer -# coverage :float -# commands :text -# job_id :integer -# name :string(255) -# deploy :boolean default(FALSE) -# options :text -# allow_failure :boolean default(FALSE), not null +# id :integer not null, primary key +# project_id :integer +# status :string(255) +# finished_at :datetime +# trace :text +# created_at :datetime +# updated_at :datetime +# started_at :datetime +# runner_id :integer +# commit_id :integer +# coverage :float +# commands :text +# job_id :integer +# name :string(255) +# options :text +# allow_failure :boolean default(FALSE), not null +# stage :string(255) +# deploy :boolean default(FALSE) +# trigger_request_id :integer # class Build < ActiveRecord::Base @@ -27,6 +29,7 @@ class Build < ActiveRecord::Base belongs_to :commit belongs_to :project belongs_to :runner + belongs_to :trigger_request serialize :options @@ -78,6 +81,7 @@ class Build < ActiveRecord::Base new_build.name = build.name new_build.allow_failure = build.allow_failure new_build.stage = build.stage + new_build.trigger_request = build.trigger_request new_build.save new_build end @@ -113,7 +117,7 @@ class Build < ActiveRecord::Base end if build.commit.success? - build.commit.create_next_builds + build.commit.create_next_builds(build.trigger_request) end project.execute_services(build) @@ -165,7 +169,7 @@ class Build < ActiveRecord::Base end def variables - yaml_variables + project_variables + yaml_variables + project_variables + trigger_variables end def duration @@ -264,4 +268,14 @@ class Build < ActiveRecord::Base { key: variable.key, value: variable.value, public: false } end end + + def trigger_variables + if trigger_request && trigger_request.variables + trigger_request.variables.map do |key, value| + { key: key, value: value, public: false } + end + else + [] + end + end end diff --git a/app/models/commit.rb b/app/models/commit.rb index a27c86b..6195090 100644 --- a/app/models/commit.rb +++ b/app/models/commit.rb @@ -2,21 +2,23 @@ # # Table name: commits # -# id :integer not null, primary key -# project_id :integer -# ref :string(255) -# sha :string(255) -# before_sha :string(255) -# push_data :text -# created_at :datetime -# updated_at :datetime -# tag :boolean default(FALSE) -# yaml_errors :text +# id :integer not null, primary key +# project_id :integer +# ref :string(255) +# sha :string(255) +# before_sha :string(255) +# push_data :text +# created_at :datetime +# updated_at :datetime +# tag :boolean default(FALSE) +# yaml_errors :text +# committed_at :datetime # class Commit < ActiveRecord::Base belongs_to :project has_many :builds, dependent: :destroy + has_many :trigger_requests, dependent: :destroy serialize :push_data @@ -99,7 +101,7 @@ class Commit < ActiveRecord::Base config_processor.stages.find { |stage| stages.include? stage } end - def create_builds_for_stage(stage) + def create_builds_for_stage(stage, trigger_request) return if skip_ci? return unless config_processor @@ -112,28 +114,29 @@ class Commit < ActiveRecord::Base tag_list: build_attrs[:tags], options: build_attrs[:options], allow_failure: build_attrs[:allow_failure], - stage: build_attrs[:stage] + stage: build_attrs[:stage], + trigger_request: trigger_request, }) end end - def create_next_builds + def create_next_builds(trigger_request) return if skip_ci? return unless config_processor - stages = builds.group_by(&:stage) + stages = builds.where(trigger_request: trigger_request).group_by(&:stage) config_processor.stages.any? do |stage| - !stages.include?(stage) && create_builds_for_stage(stage).present? + !stages.include?(stage) && create_builds_for_stage(stage, trigger_request).present? end end - def create_builds + def create_builds(trigger_request = nil) return if skip_ci? return unless config_processor config_processor.stages.any? do |stage| - create_builds_for_stage(stage).present? + create_builds_for_stage(stage, trigger_request).present? end end diff --git a/app/models/project.rb b/app/models/project.rb index 9cc3678..4879f24 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -35,6 +35,7 @@ class Project < ActiveRecord::Base has_many :web_hooks, dependent: :destroy has_many :events, dependent: :destroy has_many :variables, dependent: :destroy + has_many :triggers, dependent: :destroy # Project services has_many :services, dependent: :destroy diff --git a/app/models/trigger.rb b/app/models/trigger.rb new file mode 100644 index 0000000..26d9893 --- /dev/null +++ b/app/models/trigger.rb @@ -0,0 +1,35 @@ +# == Schema Information +# +# Table name: triggers +# +# id :integer not null, primary key +# token :string(255) +# project_id :integer not null +# deleted_at :datetime +# created_at :datetime +# updated_at :datetime +# + +class Trigger < ActiveRecord::Base + acts_as_paranoid + + belongs_to :project + has_many :trigger_requests, dependent: :destroy + + validates_presence_of :token + validates_uniqueness_of :token + + before_validation :set_default_values + + def set_default_values + self.token = SecureRandom.hex(15) if self.token.blank? + end + + def last_trigger_request + trigger_requests.last + end + + def short_token + token[0...10] + end +end diff --git a/app/models/trigger_request.rb b/app/models/trigger_request.rb new file mode 100644 index 0000000..180c23f --- /dev/null +++ b/app/models/trigger_request.rb @@ -0,0 +1,19 @@ +# == Schema Information +# +# Table name: trigger_requests +# +# id :integer not null, primary key +# trigger_id :integer not null +# variables :text +# created_at :datetime +# updated_at :datetime +# commit_id :integer +# + +class TriggerRequest < ActiveRecord::Base + belongs_to :trigger + belongs_to :commit + has_many :builds + + serialize :variables +end diff --git a/app/services/create_trigger_request_service.rb b/app/services/create_trigger_request_service.rb new file mode 100644 index 0000000..8ab34d2 --- /dev/null +++ b/app/services/create_trigger_request_service.rb @@ -0,0 +1,15 @@ +class CreateTriggerRequestService + def execute(project, trigger, ref, variables) + commit = project.commits.find_by_ref(ref) + return unless commit + + trigger_request = trigger.trigger_requests.create!( + commit: commit, + variables: variables + ) + + if commit.create_builds(trigger_request) + trigger_request + end + end +end diff --git a/app/views/builds/_build.html.haml b/app/views/builds/_build.html.haml index 4fa90c1..58a8727 100644 --- a/app/views/builds/_build.html.haml +++ b/app/views/builds/_build.html.haml @@ -16,6 +16,8 @@ - build.tag_list.each do |tag| %span.label.label-primary = tag + - if build.trigger_request + %span.label.label-info triggered - if build.allow_failure %span.label.label-danger allowed to fail diff --git a/app/views/builds/show.html.haml b/app/views/builds/show.html.haml index 55ac8af..95f5992 100644 --- a/app/views/builds/show.html.haml +++ b/app/views/builds/show.html.haml @@ -109,6 +109,23 @@ - elsif @build.runner \##{@build.runner.id} + - if @build.trigger_request + .build-widget + %h4.title + Trigger + + %p + %span.attr-name Token: + #{@build.trigger_request.trigger.short_token} + + - if @build.trigger_request.variables + %p + %span.attr-name Variables: + + %code + - @build.trigger_request.variables.each do |key, value| + #{key}=#{value} + .build-widget %h4.title Commit diff --git a/app/views/layouts/_nav_project.html.haml b/app/views/layouts/_nav_project.html.haml index 103b1c8..5bacd95 100644 --- a/app/views/layouts/_nav_project.html.haml +++ b/app/views/layouts/_nav_project.html.haml @@ -20,6 +20,10 @@ = link_to project_web_hooks_path(@project) do %i.icon-link Web Hooks + = nav_link path: 'triggers#index' do + = link_to project_triggers_path(@project) do + %i.icon-link + Triggers = nav_link path: 'services#index' do = link_to project_services_path(@project) do %i.icon-gear diff --git a/app/views/triggers/_trigger.html.haml b/app/views/triggers/_trigger.html.haml new file mode 100644 index 0000000..72f7a17 --- /dev/null +++ b/app/views/triggers/_trigger.html.haml @@ -0,0 +1,14 @@ +%tr + %td + .clearfix + %span.monospace= trigger.token + + %td + - if trigger.last_trigger_request + #{time_ago_in_words(trigger.last_trigger_request.created_at)} ago + - else + Never + + %td + .pull-right + = link_to 'Revoke', project_trigger_path(@project, trigger), data: { confirm: 'Are you sure?'}, method: :delete, class: "btn btn-danger btn-sm btn-grouped" diff --git a/app/views/triggers/index.html.haml b/app/views/triggers/index.html.haml new file mode 100644 index 0000000..3401ef3 --- /dev/null +++ b/app/views/triggers/index.html.haml @@ -0,0 +1,67 @@ +%h3 + Triggers + +%p.light + Triggers can be used to force a rebuild of a specific branch or tag with an API call. + +%hr.clearfix + +-if @triggers.any? + %table.table + %thead + %th Token + %th Last used + %th + = render @triggers +- else + %h4 No triggers + += form_for [@project, @trigger], html: { class: 'form-horizontal' } do |f| + .clearfix + = f.submit "Add Trigger", class: 'btn btn-success pull-right' + +%hr.clearfix + +-if @triggers.any? + %h3 + Use CURL + + %p.light + Copy the token above and set your branch or tag name. This is the reference that will be rebuild. + + + %pre + :plain + curl -X POST \ + -F token=TOKEN \ + #{build_trigger_url(@project.id, 'REF_NAME')} + %h3 + Use .gitlab-ci.yml + + %p.light + Copy the snippet to + %i .gitlab-ci.yml + of dependent project. + At the end of your build it will trigger this project to rebuilt. + + %pre + :plain + trigger: + type: deploy + script: + - "curl -X POST -F token=TOKEN #{build_trigger_url(@project.id, 'REF_NAME')}" + %h3 + Pass build variables + + %p.light + Add + %strong variables[VARIABLE]=VALUE + to API request. + The value of variable could then be used to distinguish triggered build from normal one. + + %pre + :plain + curl -X POST \ + -F token=TOKEN \ + -F "variables[RUN_NIGHTLY_BUILD]=true" \ + #{build_trigger_url(@project.id, 'REF_NAME')} |