diff options
author | Kamil Trzciński <ayufan@ayufan.eu> | 2018-10-05 16:30:33 +0000 |
---|---|---|
committer | Kamil Trzciński <ayufan@ayufan.eu> | 2018-10-05 16:30:33 +0000 |
commit | 059da9bc8eb9355a760031ef8e73b0aa6285012f (patch) | |
tree | b6057c99d0c53951a650122d624dc37405194551 /lib | |
parent | 7f86172f806558d2b614abcb06cef0ea516c5900 (diff) | |
parent | 7542a5d102bc48f5f7b8104fda22f0975b2dd931 (diff) | |
download | gitlab-ce-059da9bc8eb9355a760031ef8e73b0aa6285012f.tar.gz |
Merge branch 'scheduled-manual-jobs' into 'master'
Delayed jobs
Closes #51352
See merge request gitlab-org/gitlab-ce!21767
Diffstat (limited to 'lib')
-rw-r--r-- | lib/api/jobs.rb | 2 | ||||
-rw-r--r-- | lib/gitlab/ci/config/entry/job.rb | 15 | ||||
-rw-r--r-- | lib/gitlab/ci/config/entry/legacy_validation_helpers.rb | 9 | ||||
-rw-r--r-- | lib/gitlab/ci/config/entry/validators.rb | 6 | ||||
-rw-r--r-- | lib/gitlab/ci/status/build/factory.rb | 2 | ||||
-rw-r--r-- | lib/gitlab/ci/status/build/failed.rb | 3 | ||||
-rw-r--r-- | lib/gitlab/ci/status/build/scheduled.rb | 38 | ||||
-rw-r--r-- | lib/gitlab/ci/status/build/unschedule.rb | 41 | ||||
-rw-r--r-- | lib/gitlab/ci/status/pipeline/factory.rb | 1 | ||||
-rw-r--r-- | lib/gitlab/ci/status/pipeline/scheduled.rb | 21 | ||||
-rw-r--r-- | lib/gitlab/ci/status/scheduled.rb | 23 | ||||
-rw-r--r-- | lib/gitlab/ci/yaml_processor.rb | 3 |
12 files changed, 157 insertions, 7 deletions
diff --git a/lib/api/jobs.rb b/lib/api/jobs.rb index 63fab6b0abb..fa992b9a440 100644 --- a/lib/api/jobs.rb +++ b/lib/api/jobs.rb @@ -151,7 +151,7 @@ module API present build, with: Entities::Job end - desc 'Trigger a manual job' do + desc 'Trigger a actionable job (manual, scheduled, etc)' do success Entities::Job detail 'This feature was added in GitLab 8.11' end diff --git a/lib/gitlab/ci/config/entry/job.rb b/lib/gitlab/ci/config/entry/job.rb index 016a896bde5..f290ff3a565 100644 --- a/lib/gitlab/ci/config/entry/job.rb +++ b/lib/gitlab/ci/config/entry/job.rb @@ -10,7 +10,7 @@ module Gitlab include Attributable ALLOWED_KEYS = %i[tags script only except type image services - allow_failure type stage when artifacts cache + allow_failure type stage when start_in artifacts cache dependencies before_script after_script variables environment coverage retry extends].freeze @@ -28,13 +28,16 @@ module Gitlab greater_than_or_equal_to: 0, less_than_or_equal_to: 2 } validates :when, - inclusion: { in: %w[on_success on_failure always manual], + inclusion: { in: %w[on_success on_failure always manual delayed], message: 'should be on_success, on_failure, ' \ - 'always or manual' } + 'always, manual or delayed' } validates :dependencies, array_of_strings: true validates :extends, type: String end + + validates :start_in, duration: { limit: '1 day' }, if: :delayed? + validates :start_in, absence: true, unless: :delayed? end entry :before_script, Entry::Script, @@ -84,7 +87,7 @@ module Gitlab :artifacts, :commands, :environment, :coverage, :retry attributes :script, :tags, :allow_failure, :when, :dependencies, - :retry, :extends + :retry, :extends, :start_in def compose!(deps = nil) super do @@ -114,6 +117,10 @@ module Gitlab self.when == 'manual' end + def delayed? + self.when == 'delayed' + end + def ignored? allow_failure.nil? ? manual_action? : allow_failure end diff --git a/lib/gitlab/ci/config/entry/legacy_validation_helpers.rb b/lib/gitlab/ci/config/entry/legacy_validation_helpers.rb index a78a85397bd..a3d4432be82 100644 --- a/lib/gitlab/ci/config/entry/legacy_validation_helpers.rb +++ b/lib/gitlab/ci/config/entry/legacy_validation_helpers.rb @@ -11,6 +11,15 @@ module Gitlab false end + def validate_duration_limit(value, limit) + return false unless value.is_a?(String) + + ChronicDuration.parse(value).second.from_now < + ChronicDuration.parse(limit).second.from_now + rescue ChronicDuration::DurationParseError + false + end + def validate_array_of_strings(values) values.is_a?(Array) && values.all? { |value| validate_string(value) } end diff --git a/lib/gitlab/ci/config/entry/validators.rb b/lib/gitlab/ci/config/entry/validators.rb index b3c889ee92f..f6b4ba7843e 100644 --- a/lib/gitlab/ci/config/entry/validators.rb +++ b/lib/gitlab/ci/config/entry/validators.rb @@ -49,6 +49,12 @@ module Gitlab unless validate_duration(value) record.errors.add(attribute, 'should be a duration') end + + if options[:limit] + unless validate_duration_limit(value, options[:limit]) + record.errors.add(attribute, 'should not exceed the limit') + end + end end end diff --git a/lib/gitlab/ci/status/build/factory.rb b/lib/gitlab/ci/status/build/factory.rb index 2b26ebb45a1..4a74d6d6ed1 100644 --- a/lib/gitlab/ci/status/build/factory.rb +++ b/lib/gitlab/ci/status/build/factory.rb @@ -5,6 +5,7 @@ module Gitlab class Factory < Status::Factory def self.extended_statuses [[Status::Build::Erased, + Status::Build::Scheduled, Status::Build::Manual, Status::Build::Canceled, Status::Build::Created, @@ -14,6 +15,7 @@ module Gitlab Status::Build::Retryable], [Status::Build::Failed], [Status::Build::FailedAllowed, + Status::Build::Unschedule, Status::Build::Play, Status::Build::Stop], [Status::Build::Action], diff --git a/lib/gitlab/ci/status/build/failed.rb b/lib/gitlab/ci/status/build/failed.rb index 2fa9a0d4541..50b0d044265 100644 --- a/lib/gitlab/ci/status/build/failed.rb +++ b/lib/gitlab/ci/status/build/failed.rb @@ -10,7 +10,8 @@ module Gitlab stuck_or_timeout_failure: 'stuck or timeout failure', runner_system_failure: 'runner system failure', missing_dependency_failure: 'missing dependency failure', - runner_unsupported: 'unsupported runner' + runner_unsupported: 'unsupported runner', + stale_schedule: 'stale schedule' }.freeze private_constant :REASONS diff --git a/lib/gitlab/ci/status/build/scheduled.rb b/lib/gitlab/ci/status/build/scheduled.rb new file mode 100644 index 00000000000..eebb3f761c5 --- /dev/null +++ b/lib/gitlab/ci/status/build/scheduled.rb @@ -0,0 +1,38 @@ +module Gitlab + module Ci + module Status + module Build + class Scheduled < Status::Extended + def illustration + { + image: 'illustrations/illustrations_scheduled-job_countdown.svg', + size: 'svg-394', + title: _("This is a scheduled to run in ") + " #{execute_in}", + content: _("This job will automatically run after it's timer finishes. " \ + "Often they are used for incremental roll-out deploys " \ + "to production environments. When unscheduled it converts " \ + "into a manual action.") + } + end + + def status_tooltip + "scheduled manual action (#{execute_in})" + end + + def self.matches?(build, user) + build.scheduled? && build.scheduled_at + end + + private + + include TimeHelper + + def execute_in + remaining_seconds = [0, subject.scheduled_at - Time.now].max + duration_in_numbers(remaining_seconds, true) + end + end + end + end + end +end diff --git a/lib/gitlab/ci/status/build/unschedule.rb b/lib/gitlab/ci/status/build/unschedule.rb new file mode 100644 index 00000000000..e1b7b83428c --- /dev/null +++ b/lib/gitlab/ci/status/build/unschedule.rb @@ -0,0 +1,41 @@ +module Gitlab + module Ci + module Status + module Build + class Unschedule < Status::Extended + def label + 'unschedule action' + end + + def has_action? + can?(user, :update_build, subject) + end + + def action_icon + 'time-out' + end + + def action_title + 'Unschedule' + end + + def action_button_title + _('Unschedule job') + end + + def action_path + unschedule_project_job_path(subject.project, subject) + end + + def action_method + :post + end + + def self.matches?(build, user) + build.scheduled? + end + end + end + end + end +end diff --git a/lib/gitlab/ci/status/pipeline/factory.rb b/lib/gitlab/ci/status/pipeline/factory.rb index 17f9a75f436..00d8f01cbdc 100644 --- a/lib/gitlab/ci/status/pipeline/factory.rb +++ b/lib/gitlab/ci/status/pipeline/factory.rb @@ -5,6 +5,7 @@ module Gitlab class Factory < Status::Factory def self.extended_statuses [[Status::SuccessWarning, + Status::Pipeline::Scheduled, Status::Pipeline::Blocked]] end diff --git a/lib/gitlab/ci/status/pipeline/scheduled.rb b/lib/gitlab/ci/status/pipeline/scheduled.rb new file mode 100644 index 00000000000..9ec6994bd2f --- /dev/null +++ b/lib/gitlab/ci/status/pipeline/scheduled.rb @@ -0,0 +1,21 @@ +module Gitlab + module Ci + module Status + module Pipeline + class Scheduled < Status::Extended + def text + s_('CiStatusText|scheduled') + end + + def label + s_('CiStatusLabel|waiting for delayed job') + end + + def self.matches?(pipeline, user) + pipeline.scheduled? + end + end + end + end + end +end diff --git a/lib/gitlab/ci/status/scheduled.rb b/lib/gitlab/ci/status/scheduled.rb new file mode 100644 index 00000000000..542100e41da --- /dev/null +++ b/lib/gitlab/ci/status/scheduled.rb @@ -0,0 +1,23 @@ +module Gitlab + module Ci + module Status + class Scheduled < Status::Core + def text + s_('CiStatusText|scheduled') + end + + def label + s_('CiStatusLabel|scheduled') + end + + def icon + 'status_scheduled' + end + + def favicon + 'favicon_status_scheduled' + end + end + end + end +end diff --git a/lib/gitlab/ci/yaml_processor.rb b/lib/gitlab/ci/yaml_processor.rb index 5d1864ae9e2..a427aa30683 100644 --- a/lib/gitlab/ci/yaml_processor.rb +++ b/lib/gitlab/ci/yaml_processor.rb @@ -49,7 +49,8 @@ module Gitlab script: job[:script], after_script: job[:after_script], environment: job[:environment], - retry: job[:retry] + retry: job[:retry], + start_in: job[:start_in] }.compact } end |