summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlessio Caiazza <acaiazza@gitlab.com>2018-09-07 15:14:41 +0200
committerAlessio Caiazza <acaiazza@gitlab.com>2018-09-07 15:26:58 +0200
commitbf3ee5f0065859a8387ee80f59a917dc3db936da (patch)
treeb13076b5edac66c7a557277f1f84fc71df272cce
parentc3d5e219deeb2d340876f276f2e89733592dbffb (diff)
downloadgitlab-ce-1660-scheduled-jobs.tar.gz
Add scheduled state to HasStatus1660-scheduled-jobs
-rw-r--r--app/models/ci/build.rb23
-rw-r--r--app/models/ci/pipeline.rb5
-rw-r--r--app/models/ci/stage.rb5
-rw-r--r--app/models/commit_status.rb8
-rw-r--r--app/models/concerns/has_status.rb15
-rw-r--r--app/services/ci/process_pipeline_service.rb10
-rw-r--r--app/workers/all_queues.yml1
-rw-r--r--app/workers/ci/enqueue_build_worker.rb16
-rw-r--r--changelogs/unreleased/1660-scheduled-jobs.yml5
-rw-r--r--lib/gitlab/ci/status/scheduled.rb23
10 files changed, 102 insertions, 9 deletions
diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb
index faa160ad6ba..22d46a1824f 100644
--- a/app/models/ci/build.rb
+++ b/app/models/ci/build.rb
@@ -150,6 +150,12 @@ module Ci
transition created: :manual
end
+ after_transition any => [:scheduled] do |build|
+ build.run_after_commit do
+ EnqueueBuildWorker.perform_in(build.perform_in, id)
+ end
+ end
+
after_transition any => [:pending] do |build|
build.run_after_commit do
BuildQueueWorker.perform_async(id)
@@ -221,7 +227,22 @@ module Ci
end
def action?
- self.when == 'manual'
+ self.when == 'manual' || delayed?
+ end
+
+ def delayed?
+ self.when&.start_with?('in') && (created? || scheduled?)
+ end
+
+ def perform_in
+ return unless delayed?
+
+ begin
+ time = self.when['in'.size..-1]
+ ChronicDuration.parse(time).seconds
+ rescue ChronicDuration::DurationParseError
+ return
+ end
end
def play(current_user)
diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb
index 526bf7af99b..0931961a58c 100644
--- a/app/models/ci/pipeline.rb
+++ b/app/models/ci/pipeline.rb
@@ -84,6 +84,10 @@ module Ci
transition [:success, :failed, :canceled] => :running
end
+ event :schedule do
+ transition [:created, :skipped] => :scheduled
+ end
+
event :run do
transition any - [:running] => :running
end
@@ -527,6 +531,7 @@ module Ci
retry_optimistic_lock(self) do
case latest_builds_status.to_s
when 'created' then nil
+ when 'scheduled' then schedule
when 'pending' then enqueue
when 'running' then run
when 'success' then succeed
diff --git a/app/models/ci/stage.rb b/app/models/ci/stage.rb
index 511ded55dc3..9561a0d573e 100644
--- a/app/models/ci/stage.rb
+++ b/app/models/ci/stage.rb
@@ -42,6 +42,10 @@ module Ci
transition [:success, :failed, :canceled, :skipped] => :running
end
+ event :schedule do
+ transition [:created, :skipped] => :scheduled
+ end
+
event :run do
transition any - [:running] => :running
end
@@ -71,6 +75,7 @@ module Ci
retry_optimistic_lock(self) do
case statuses.latest.status
when 'created' then nil
+ when 'scheduled' then schedule
when 'pending' then enqueue
when 'running' then run
when 'success' then succeed
diff --git a/app/models/commit_status.rb b/app/models/commit_status.rb
index b65d7672973..b1262088992 100644
--- a/app/models/commit_status.rb
+++ b/app/models/commit_status.rb
@@ -68,8 +68,12 @@ class CommitStatus < ActiveRecord::Base
transition [:skipped, :manual] => :created
end
+ event :schedule do
+ transition [:created, :skipped] => :scheduled
+ end
+
event :enqueue do
- transition [:created, :skipped, :manual] => :pending
+ transition [:created, :skipped, :manual, :scheduled] => :pending
end
event :run do
@@ -89,7 +93,7 @@ class CommitStatus < ActiveRecord::Base
end
event :cancel do
- transition [:created, :pending, :running, :manual] => :canceled
+ transition [:created, :pending, :running, :manual, :scheduled] => :canceled
end
before_transition [:created, :skipped, :manual] => :pending do |commit_status|
diff --git a/app/models/concerns/has_status.rb b/app/models/concerns/has_status.rb
index b3960cbad1a..774214648a7 100644
--- a/app/models/concerns/has_status.rb
+++ b/app/models/concerns/has_status.rb
@@ -5,13 +5,14 @@ module HasStatus
DEFAULT_STATUS = 'created'.freeze
BLOCKED_STATUS = 'manual'.freeze
- AVAILABLE_STATUSES = %w[created pending running success failed canceled skipped manual].freeze
+ AVAILABLE_STATUSES = %w[created pending running success failed canceled skipped manual scheduled].freeze
STARTED_STATUSES = %w[running success failed skipped manual].freeze
- ACTIVE_STATUSES = %w[pending running].freeze
+ ACTIVE_STATUSES = %w[pending running scheduled].freeze
COMPLETED_STATUSES = %w[success failed canceled skipped].freeze
- ORDERED_STATUSES = %w[failed pending running manual canceled success skipped created].freeze
+ ORDERED_STATUSES = %w[failed pending running scheduled manual canceled success skipped created].freeze
STATUSES_ENUM = { created: 0, pending: 1, running: 2, success: 3,
- failed: 4, canceled: 5, skipped: 6, manual: 7 }.freeze
+ failed: 4, canceled: 5, skipped: 6, manual: 7,
+ scheduled: 8 }.freeze
UnknownStatusError = Class.new(StandardError)
@@ -26,6 +27,7 @@ module HasStatus
manual = scope_relevant.manual.select('count(*)').to_sql
pending = scope_relevant.pending.select('count(*)').to_sql
running = scope_relevant.running.select('count(*)').to_sql
+ scheduled = scope_relevant.scheduled.select('count(*)').to_sql
skipped = scope_relevant.skipped.select('count(*)').to_sql
canceled = scope_relevant.canceled.select('count(*)').to_sql
warnings = scope_warnings.select('count(*) > 0').to_sql.presence || 'false'
@@ -35,10 +37,11 @@ module HasStatus
WHEN (#{builds})=(#{skipped}) THEN 'skipped'
WHEN (#{builds})=(#{success}) THEN 'success'
WHEN (#{builds})=(#{created}) THEN 'created'
+ WHEN (#{builds})=(#{scheduled}) THEN 'scheduled'
WHEN (#{builds})=(#{success})+(#{skipped}) THEN 'success'
WHEN (#{builds})=(#{success})+(#{skipped})+(#{canceled}) THEN 'canceled'
WHEN (#{builds})=(#{created})+(#{skipped})+(#{pending}) THEN 'pending'
- WHEN (#{running})+(#{pending})>0 THEN 'running'
+ WHEN (#{running})+(#{pending})+(#{scheduled})>0 THEN 'running'
WHEN (#{manual})>0 THEN 'manual'
WHEN (#{created})>0 THEN 'running'
ELSE 'failed'
@@ -74,6 +77,7 @@ module HasStatus
state :canceled, value: 'canceled'
state :skipped, value: 'skipped'
state :manual, value: 'manual'
+ state :scheduled, value: 'scheduled'
end
scope :created, -> { where(status: 'created') }
@@ -85,6 +89,7 @@ module HasStatus
scope :canceled, -> { where(status: 'canceled') }
scope :skipped, -> { where(status: 'skipped') }
scope :manual, -> { where(status: 'manual') }
+ scope :scheduled, -> { where(status: 'scheduled') }
scope :alive, -> { where(status: [:created, :pending, :running]) }
scope :created_or_pending, -> { where(status: [:created, :pending]) }
scope :running_or_pending, -> { where(status: [:running, :pending]) }
diff --git a/app/services/ci/process_pipeline_service.rb b/app/services/ci/process_pipeline_service.rb
index cafee76a33c..ba0d2c07a2b 100644
--- a/app/services/ci/process_pipeline_service.rb
+++ b/app/services/ci/process_pipeline_service.rb
@@ -37,7 +37,13 @@ module Ci
def process_build(build, current_status)
if valid_statuses_for_when(build.when).include?(current_status)
- build.action? ? build.actionize : enqueue_build(build)
+ if build.delayed?
+ build.schedule
+ elsif build.action?
+ build.actionize
+ else
+ enqueue_build(build)
+ end
true
else
build.skip
@@ -55,6 +61,8 @@ module Ci
%w[success failed skipped]
when 'manual'
%w[success skipped]
+ when /^in/
+ %w[success skipped]
else
[]
end
diff --git a/app/workers/all_queues.yml b/app/workers/all_queues.yml
index f95df7ecf03..bcaa60e0c85 100644
--- a/app/workers/all_queues.yml
+++ b/app/workers/all_queues.yml
@@ -68,6 +68,7 @@
- pipeline_processing:pipeline_update
- pipeline_processing:stage_update
- pipeline_processing:update_head_pipeline_for_merge_request
+- pipeline_processing:ci_enqueue_build
- repository_check:repository_check_clear
- repository_check:repository_check_batch
diff --git a/app/workers/ci/enqueue_build_worker.rb b/app/workers/ci/enqueue_build_worker.rb
new file mode 100644
index 00000000000..2f2b2ad2af4
--- /dev/null
+++ b/app/workers/ci/enqueue_build_worker.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+module Ci
+ class EnqueueBuildWorker
+ include ApplicationWorker
+ include PipelineQueue
+
+ queue_namespace :pipeline_processing
+
+ def perform(build_id)
+ ::Ci::Build.find_by(id: build_id).try do |build|
+ build.enqueue
+ end
+ end
+ end
+end
diff --git a/changelogs/unreleased/1660-scheduled-jobs.yml b/changelogs/unreleased/1660-scheduled-jobs.yml
new file mode 100644
index 00000000000..48f060fefe6
--- /dev/null
+++ b/changelogs/unreleased/1660-scheduled-jobs.yml
@@ -0,0 +1,5 @@
+---
+title: Add scheduled job support in gitlab-ci.yml
+merge_request: 21587
+author:
+type: added
diff --git a/lib/gitlab/ci/status/scheduled.rb b/lib/gitlab/ci/status/scheduled.rb
new file mode 100644
index 00000000000..3a7ff17dff7
--- /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
+ 'timer'
+ end
+
+ def favicon
+ 'favicon_status_scheduled'
+ end
+ end
+ end
+ end
+end