Commit 1a4f497e authored by Shinya Maeda's avatar Shinya Maeda Committed by Alessio Caiazza

Update pipelines and stages status as well

parent a7c767f1
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
# #
# See 'detailed_status?` method and `Gitlab::Ci::Status` module. # See 'detailed_status?` method and `Gitlab::Ci::Status` module.
# #
# TODO: DO I need to update this deprecated module?
module CiStatusHelper module CiStatusHelper
def ci_label_for_status(status) def ci_label_for_status(status)
if detailed_status?(status) if detailed_status?(status)
......
...@@ -169,11 +169,11 @@ module Ci ...@@ -169,11 +169,11 @@ module Ci
end end
before_transition created: :scheduled do |build| before_transition created: :scheduled do |build|
build_build_schedule(execute_at: execute_at) build.build_build_schedule(execute_at: build.execute_at)
end end
before_transition scheduled: any do |build| before_transition scheduled: any do |build|
build_schedule.delete! build.build_schedule.delete
end end
after_transition any => [:pending] do |build| after_transition any => [:pending] do |build|
......
...@@ -108,6 +108,10 @@ module Ci ...@@ -108,6 +108,10 @@ module Ci
transition any - [:manual] => :manual transition any - [:manual] => :manual
end end
event :schedule do
transition any - [:scheduled] => :scheduled
end
# IMPORTANT # IMPORTANT
# Do not add any operations to this state_machine # Do not add any operations to this state_machine
# Create a separate worker for each new operation # Create a separate worker for each new operation
...@@ -544,6 +548,7 @@ module Ci ...@@ -544,6 +548,7 @@ module Ci
when 'canceled' then cancel when 'canceled' then cancel
when 'skipped' then skip when 'skipped' then skip
when 'manual' then block when 'manual' then block
when 'scheduled' then schedule
else else
raise HasStatus::UnknownStatusError, raise HasStatus::UnknownStatusError,
"Unknown status `#{latest_builds_status}`" "Unknown status `#{latest_builds_status}`"
......
...@@ -65,6 +65,10 @@ module Ci ...@@ -65,6 +65,10 @@ module Ci
event :block do event :block do
transition any - [:manual] => :manual transition any - [:manual] => :manual
end end
event :schedule do
transition any - [:scheduled] => :scheduled
end
end end
def update_status def update_status
...@@ -77,6 +81,7 @@ module Ci ...@@ -77,6 +81,7 @@ module Ci
when 'failed' then drop when 'failed' then drop
when 'canceled' then cancel when 'canceled' then cancel
when 'manual' then block when 'manual' then block
when 'scheduled' then schedule
when 'skipped', nil then skip when 'skipped', nil then skip
else else
raise HasStatus::UnknownStatusError, raise HasStatus::UnknownStatusError,
......
...@@ -77,6 +77,7 @@ module HasStatus ...@@ -77,6 +77,7 @@ module HasStatus
state :canceled, value: 'canceled' state :canceled, value: 'canceled'
state :skipped, value: 'skipped' state :skipped, value: 'skipped'
state :manual, value: 'manual' state :manual, value: 'manual'
state :scheduled, value: 'scheduled'
end end
scope :created, -> { where(status: 'created') } scope :created, -> { where(status: 'created') }
...@@ -88,6 +89,7 @@ module HasStatus ...@@ -88,6 +89,7 @@ module HasStatus
scope :canceled, -> { where(status: 'canceled') } scope :canceled, -> { where(status: 'canceled') }
scope :skipped, -> { where(status: 'skipped') } scope :skipped, -> { where(status: 'skipped') }
scope :manual, -> { where(status: 'manual') } scope :manual, -> { where(status: 'manual') }
scope :scheduled, -> { where(status: 'scheduled') }
scope :alive, -> { where(status: [:created, :pending, :running]) } scope :alive, -> { where(status: [:created, :pending, :running]) }
scope :created_or_pending, -> { where(status: [:created, :pending]) } scope :created_or_pending, -> { where(status: [:created, :pending]) }
scope :running_or_pending, -> { where(status: [:running, :pending]) } scope :running_or_pending, -> { where(status: [:running, :pending]) }
......
...@@ -3,31 +3,9 @@ module Gitlab ...@@ -3,31 +3,9 @@ module Gitlab
module Status module Status
module Build module Build
class Scheduled < Status::Extended class Scheduled < Status::Extended
###
# Core override
###
def text
s_('CiStatusText|scheduled')
end
def label
s_('CiStatusLabel|scheduled')
end
def icon
'timer'
end
def favicon
'favicon_status_scheduled'
end
###
# Extension override
###
def illustration def illustration
{ {
image: 'illustrations/canceled-job_empty.svg', image: 'illustrations/scheduled-job_countdown.svg',
size: 'svg-394', size: 'svg-394',
title: _("This is a scheduled to run in ") + " #{execute_in}", 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.") 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.")
......
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' # TODO: 'status_scheduled'
end
def favicon
'favicon_status_scheduled'
end
end
end
end
end
...@@ -62,31 +62,87 @@ cleanup: ...@@ -62,31 +62,87 @@ cleanup:
# require '/path/to/scheduled_job_fixture.rb' # Load this script # require '/path/to/scheduled_job_fixture.rb' # Load this script
# ``` # ```
# #
# ### Reproduce the scenario A) ~ Succeccfull timed incremantal rollout ~ # ### Reproduce the scenario ~ when all stages succeeded ~
# #
# ```` # 1. ScheduledJobFixture.new(29, 1).create_pipeline('master')
# project = Project.find_by(path: 'incremental-rollout') # 1. ScheduledJobFixture.new(29, 1).finish_stage_until('test')
# user = User.find_by(username: 'root') # 1. Wait until rollout 10% job is triggered
# fixture = ScheduledJobFixture.new(project.id, user.id) # 1. ScheduledJobFixture.new(29, 1).finish_stage_until('rollout 10%')
# # 1. Wait until rollout 50% job is triggered
# fixture.create_pipeline('master') # 1. ScheduledJobFixture.new(29, 1).finish_stage_until('rollout 50%')
# fixture.finish_stage_until('test') # Succeed 'build' and 'test' jobs. 'rollout 10%' job will be scheduled. See the pipeline page # 1. Wait until rollout 100% job is triggered
# fixture.finish_stage_until('rollout 10%') # Succeed `rollout 10%` job. 'rollout 50%' job will be scheduled. # 1. ScheduledJobFixture.new(29, 1).finish_stage_until('rollout 100%')
# fixture.finish_stage_until('rollout 50%') # Succeed `rollout 50%` job. 'rollout 100%' job will be scheduled. # 1. ScheduledJobFixture.new(29, 1).finish_stage_until('cleanup')
# fixture.finish_stage_until('rollout 100%') # Succeed `rollout 100%` job. 'cleanup' job will be scheduled. #
# fixture.finish_stage_until('cleanup') # Succeed `cleanup` job. The pipeline becomes green. # Expectation: Users see a succeccful pipeline
# ``` #
# ### Reproduce the scenario ~ when rollout 10% jobs failed ~
#
# 1. ScheduledJobFixture.new(29, 1).create_pipeline('master')
# 1. ScheduledJobFixture.new(29, 1).finish_stage_until('test')
# 1. Wait until rollout 10% job is triggered
# 1. ScheduledJobFixture.new(29, 1).drop_jobs('rollout 10%')
#
# Expectation: Following stages should be skipped.
#
# ### Reproduce the scenario ~ when user clicked cancel button before build job finished ~
#
# 1. ScheduledJobFixture.new(29, 1).create_pipeline('master')
# 1. ScheduledJobFixture.new(29, 1).cancel_pipeline
#
# Expectation: All stages should be canceled.
#
# ### Reproduce the scenario ~ when user canceled the pipeline after rollout 10% job is scheduled ~
#
# 1. ScheduledJobFixture.new(29, 1).create_pipeline('master')
# 1. ScheduledJobFixture.new(29, 1).finish_stage_until('test')
# 1. Run next command before rollout 10% job is triggered
# 1. ScheduledJobFixture.new(29, 1).cancel_pipeline
#
# Expectation: rollout 10% job will be canceled. Following stages will be skipped.
#
# ### Reproduce the scenario ~ when user canceled rollout 10% job after rollout 10% job is scheduled ~
#
# 1. ScheduledJobFixture.new(29, 1).create_pipeline('master')
# 1. ScheduledJobFixture.new(29, 1).finish_stage_until('test')
# 1. Run next command before rollout 10% job is triggered
# 1. ScheduledJobFixture.new(29, 1).cancel_jobs('rollout 10%')
#
# Expectation: rollout 10% job will be canceled. Following stages will be skipped.
#
# ### Reproduce the scenario ~ when user played rollout 10% job immidiately ~
#
# 1. ScheduledJobFixture.new(29, 1).create_pipeline('master')
# 1. ScheduledJobFixture.new(29, 1).finish_stage_until('test')
# 1. Play rollout 10% job before rollout 10% job is triggered
#
# Expectation: rollout 10% becomes pending immidiately
#
# ### Reproduce the scenario ~ when rollout 10% job is allowed to fail ~
#
# 1. Set `allow_failure: true` to rollout 10% job
# 1. ScheduledJobFixture.new(29, 1).create_pipeline('master')
# 1. ScheduledJobFixture.new(29, 1).finish_stage_until('test')
# 1. Wait until rollout 10% job is triggered
# 1. ScheduledJobFixture.new(29, 1).drop_jobs('rollout 10%')
#
# Expectation: rollout 50% job should be triggered
#
class ScheduledJobFixture class ScheduledJobFixture
attr_reader :project attr_reader :project
attr_reader :user attr_reader :user
include GitlabRoutingHelper
def initialize(project_id, user_id) def initialize(project_id, user_id)
@project = Project.find_by_id(project_id) @project = Project.find_by_id(project_id)
@user = User.find_by_id(user_id) @user = User.find_by_id(user_id)
end end
def create_pipeline(ref) def create_pipeline(ref)
Ci::CreatePipelineService.new(project, user, ref: ref).execute(:web) pipeline = Ci::CreatePipelineService.new(project, user, ref: ref).execute(:web)
Rails.application.routes.url_helpers.namespace_project_pipeline_url(project.namespace, project, pipeline)
end end
def finish_stage_until(stage_name) def finish_stage_until(stage_name)
...@@ -99,4 +155,32 @@ class ScheduledJobFixture ...@@ -99,4 +155,32 @@ class ScheduledJobFixture
return if stage.name == stage_name return if stage.name == stage_name
end end
end end
def run_jobs(stage_name)
pipeline = Ci::Pipeline.last
stage = pipeline.stages.find_by_name(stage_name)
stage.builds.map(&:run)
stage.update_status
pipeline.update_status
end
def drop_jobs(stage_name)
pipeline = Ci::Pipeline.last
stage = pipeline.stages.find_by_name(stage_name)
stage.builds.map(&:drop)
stage.update_status
pipeline.update_status
end
def cancel_jobs(stage_name)
pipeline = Ci::Pipeline.last
stage = pipeline.stages.find_by_name(stage_name)
stage.builds.map(&:cancel)
stage.update_status
pipeline.update_status
end
def cancel_pipeline
Ci::Pipeline.last.cancel_running
end
end end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment