From be039d22d71afa7c8b2635cd8820b8b4566d15b8 Mon Sep 17 00:00:00 2001 From: Kamil Trzcinski Date: Tue, 28 Feb 2017 16:48:39 +0100 Subject: [PATCH] Make manual actions blocking --- app/models/ci/build.rb | 14 +++++++++----- app/models/commit_status.rb | 10 +++++----- app/models/concerns/has_status.rb | 10 +++++++--- app/serializers/build_entity.rb | 2 +- app/services/ci/process_pipeline_service.rb | 3 +++ lib/gitlab/ci/config/entry/job.rb | 4 ++++ lib/gitlab/ci/status/manual.rb | 19 +++++++++++++++++++ 7 files changed, 48 insertions(+), 14 deletions(-) create mode 100644 lib/gitlab/ci/status/manual.rb diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb index f2989eff22d..4086417eb78 100644 --- a/app/models/ci/build.rb +++ b/app/models/ci/build.rb @@ -63,6 +63,10 @@ module Ci end state_machine :status do + event :block do + transition :created => :manual, if: () -> { self.when == 'manual' } + end + after_transition any => [:pending] do |build| build.run_after_commit do BuildQueueWorker.perform_async(id) @@ -94,16 +98,16 @@ module Ci .fabricate! end - def manual? - self.when == 'manual' - end - def other_actions pipeline.manual_actions.where.not(name: name) end def playable? - project.builds_enabled? && commands.present? && manual? && skipped? + project.builds_enabled? && commands.present? && manual? + end + + def is_blocking? + playable? && !allow_failure? end def play(current_user) diff --git a/app/models/commit_status.rb b/app/models/commit_status.rb index fc750a3e5e9..bca61151eff 100644 --- a/app/models/commit_status.rb +++ b/app/models/commit_status.rb @@ -25,13 +25,13 @@ class CommitStatus < ActiveRecord::Base end scope :failed_but_allowed, -> do - where(allow_failure: true, status: [:failed, :canceled]) + where(allow_failure: true, status: [:failed, :canceled, :manual]) end scope :exclude_ignored, -> do # We want to ignore failed_but_allowed jobs where("allow_failure = ? OR status IN (?)", - false, all_state_names - [:failed, :canceled]) + false, all_state_names - [:failed, :canceled, :manual]) end scope :retried, -> { where.not(id: latest) } @@ -42,11 +42,11 @@ class CommitStatus < ActiveRecord::Base state_machine :status do event :enqueue do - transition [:created, :skipped] => :pending + transition [:created, :skipped, :manual] => :pending end event :process do - transition skipped: :created + transition [:skipped, :manual] => :created end event :run do @@ -66,7 +66,7 @@ class CommitStatus < ActiveRecord::Base end event :cancel do - transition [:created, :pending, :running] => :canceled + transition [:created, :pending, :running, :manual] => :canceled end before_transition created: [:pending, :running] do |commit_status| diff --git a/app/models/concerns/has_status.rb b/app/models/concerns/has_status.rb index aea359e70bb..62a7e9c0b7f 100644 --- a/app/models/concerns/has_status.rb +++ b/app/models/concerns/has_status.rb @@ -2,9 +2,9 @@ module HasStatus extend ActiveSupport::Concern DEFAULT_STATUS = 'created'.freeze - AVAILABLE_STATUSES = %w[created pending running success failed canceled skipped].freeze + AVAILABLE_STATUSES = %w[created pending running success failed canceled skipped manual].freeze STARTED_STATUSES = %w[running success failed skipped].freeze - ACTIVE_STATUSES = %w[pending running].freeze + ACTIVE_STATUSES = %w[pending running manual].freeze COMPLETED_STATUSES = %w[success failed canceled skipped].freeze ORDERED_STATUSES = %w[failed pending running canceled success skipped].freeze @@ -18,6 +18,7 @@ module HasStatus builds = scope.select('count(*)').to_sql created = scope.created.select('count(*)').to_sql success = scope.success.select('count(*)').to_sql + manual = scope.manual.select('count(*)').to_sql pending = scope.pending.select('count(*)').to_sql running = scope.running.select('count(*)').to_sql skipped = scope.skipped.select('count(*)').to_sql @@ -31,6 +32,7 @@ module HasStatus WHEN (#{builds})=(#{success})+(#{skipped})+(#{canceled}) THEN 'canceled' WHEN (#{builds})=(#{created})+(#{skipped})+(#{pending}) THEN 'pending' WHEN (#{running})+(#{pending})+(#{created})>0 THEN 'running' + WHEN (#{manual})>0 THEN 'manual' ELSE 'failed' END)" end @@ -63,6 +65,7 @@ module HasStatus state :success, value: 'success' state :canceled, value: 'canceled' state :skipped, value: 'skipped' + state :manual, value: 'manual' end scope :created, -> { where(status: 'created') } @@ -73,12 +76,13 @@ module HasStatus scope :failed, -> { where(status: 'failed') } scope :canceled, -> { where(status: 'canceled') } scope :skipped, -> { where(status: 'skipped') } + scope :manual, -> { where(status: 'manual') } scope :running_or_pending, -> { where(status: [:running, :pending]) } scope :finished, -> { where(status: [:success, :failed, :canceled]) } scope :failed_or_canceled, -> { where(status: [:failed, :canceled]) } scope :cancelable, -> do - where(status: [:running, :pending, :created]) + where(status: [:running, :pending, :created, :manual]) end end diff --git a/app/serializers/build_entity.rb b/app/serializers/build_entity.rb index b5384e6462b..5bcbe285052 100644 --- a/app/serializers/build_entity.rb +++ b/app/serializers/build_entity.rb @@ -12,7 +12,7 @@ class BuildEntity < Grape::Entity path_to(:retry_namespace_project_build, build) end - expose :play_path, if: ->(build, _) { build.manual? } do |build| + expose :play_path, if: ->(build, _) { build.playable? } do |build| path_to(:play_namespace_project_build, build) end diff --git a/app/services/ci/process_pipeline_service.rb b/app/services/ci/process_pipeline_service.rb index 79eb97b7b55..0a478f91214 100644 --- a/app/services/ci/process_pipeline_service.rb +++ b/app/services/ci/process_pipeline_service.rb @@ -35,6 +35,9 @@ module Ci if valid_statuses_for_when(build.when).include?(current_status) build.enqueue true + elsif build.can_block? + build.block + build.is_blocking? else build.skip false diff --git a/lib/gitlab/ci/config/entry/job.rb b/lib/gitlab/ci/config/entry/job.rb index 7f7662f2776..69e2a8a2563 100644 --- a/lib/gitlab/ci/config/entry/job.rb +++ b/lib/gitlab/ci/config/entry/job.rb @@ -104,6 +104,10 @@ module Gitlab (before_script_value.to_a + script_value.to_a).join("\n") end + def allow_failure + super || self.when == 'manual' + end + private def inherit!(deps) diff --git a/lib/gitlab/ci/status/manual.rb b/lib/gitlab/ci/status/manual.rb new file mode 100644 index 00000000000..741b3dd96e9 --- /dev/null +++ b/lib/gitlab/ci/status/manual.rb @@ -0,0 +1,19 @@ +module Gitlab + module Ci + module Status + class Manual < Status::Core + def text + 'manual' + end + + def label + 'manual' + end + + def icon + 'icon_status_manual' + end + end + end + end +end