2020-02-27 13:09:21 -05:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
|
|
|
module Ci
|
2021-08-03 02:08:50 -04:00
|
|
|
class Ref < Ci::ApplicationRecord
|
2020-07-30 11:09:40 -04:00
|
|
|
include AfterCommitQueue
|
2020-06-10 05:08:35 -04:00
|
|
|
include Gitlab::OptimisticLocking
|
2020-02-27 13:09:21 -05:00
|
|
|
|
2020-06-10 05:08:35 -04:00
|
|
|
FAILING_STATUSES = %w[failed broken still_failing].freeze
|
|
|
|
|
|
|
|
belongs_to :project, inverse_of: :ci_refs
|
|
|
|
has_many :pipelines, class_name: 'Ci::Pipeline', foreign_key: :ci_ref_id, inverse_of: :ci_ref
|
|
|
|
|
|
|
|
state_machine :status, initial: :unknown do
|
|
|
|
event :succeed do
|
|
|
|
transition unknown: :success
|
|
|
|
transition fixed: :success
|
|
|
|
transition %i[failed broken still_failing] => :fixed
|
2020-07-30 11:09:40 -04:00
|
|
|
transition success: same
|
2020-06-10 05:08:35 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
event :do_fail do
|
|
|
|
transition unknown: :failed
|
|
|
|
transition %i[failed broken] => :still_failing
|
|
|
|
transition %i[success fixed] => :broken
|
|
|
|
end
|
|
|
|
|
|
|
|
state :unknown, value: 0
|
|
|
|
state :success, value: 1
|
|
|
|
state :failed, value: 2
|
|
|
|
state :fixed, value: 3
|
|
|
|
state :broken, value: 4
|
|
|
|
state :still_failing, value: 5
|
2020-07-30 11:09:40 -04:00
|
|
|
|
|
|
|
after_transition any => [:fixed, :success] do |ci_ref|
|
2021-01-12 13:11:03 -05:00
|
|
|
# Do not try to unlock if no artifacts are locked
|
|
|
|
next unless ci_ref.artifacts_locked?
|
|
|
|
|
2020-07-30 11:09:40 -04:00
|
|
|
ci_ref.run_after_commit do
|
|
|
|
Ci::PipelineSuccessUnlockArtifactsWorker.perform_async(ci_ref.last_finished_pipeline_id)
|
|
|
|
end
|
|
|
|
end
|
2020-06-10 05:08:35 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
class << self
|
|
|
|
def ensure_for(pipeline)
|
|
|
|
safe_find_or_create_by(project_id: pipeline.project_id,
|
|
|
|
ref_path: pipeline.source_ref_path)
|
|
|
|
end
|
|
|
|
|
|
|
|
def failing_state?(status_name)
|
|
|
|
FAILING_STATUSES.include?(status_name)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def last_finished_pipeline_id
|
2020-06-25 11:08:37 -04:00
|
|
|
Ci::Pipeline.last_finished_for_ref_id(self.id)&.id
|
2020-06-10 05:08:35 -04:00
|
|
|
end
|
|
|
|
|
2021-01-12 13:11:03 -05:00
|
|
|
def artifacts_locked?
|
|
|
|
self.pipelines.where(locked: :artifacts_locked).exists?
|
|
|
|
end
|
|
|
|
|
2020-06-10 05:08:35 -04:00
|
|
|
def update_status_by!(pipeline)
|
2021-03-02 10:10:57 -05:00
|
|
|
retry_lock(self, name: 'ci_ref_update_status_by') do
|
2020-06-10 05:08:35 -04:00
|
|
|
next unless last_finished_pipeline_id == pipeline.id
|
|
|
|
|
|
|
|
case pipeline.status
|
|
|
|
when 'success' then self.succeed
|
|
|
|
when 'failed' then self.do_fail
|
|
|
|
end
|
|
|
|
|
|
|
|
self.status_name
|
|
|
|
end
|
|
|
|
end
|
2020-02-27 13:09:21 -05:00
|
|
|
end
|
|
|
|
end
|