lib/release_tools/services/publish_service/base_publish_service.rb (88 lines of code) (raw):
# frozen_string_literal: true
module ReleaseTools
module Services
class BasePublishService
include ::SemanticLogger::Loggable
class PipelineNotFoundError < StandardError
def initialize(version)
super("Pipeline not found for #{version}")
end
end
def initialize(version)
@version = version
end
def play_stages
raise NotImplementedError
end
def release_versions
raise NotImplementedError
end
def project
raise NotImplementedError
end
def execute
logger.info('Publishing versions', release_versions: release_versions)
all_played_pipelines = []
all_failed_pipelines = []
release_versions.each do |version|
pipeline = pipeline_for_version(version)
if pipeline.status == 'failed'
all_failed_pipelines.append(pipeline)
logger.warn("Pipeline failed. Not searching for manual jobs.", pipeline: pipeline.web_url, version: version)
next
end
played_pipeline = publish_version(version, pipeline)
all_played_pipelines.append(played_pipeline) if played_pipeline
end
[all_played_pipelines, all_failed_pipelines]
end
private
def publish_version(version, pipeline)
logger.info('Finding manual jobs', pipeline: pipeline.web_url, version: version)
triggers = jobs_to_be_triggered(pipeline)
logger.info('Found jobs to be triggered', triggers_count: triggers.count)
if triggers.any?
play_manual_jobs(triggers)
return pipeline
end
# If there are no manual jobs, and the pipeline has not failed,
# maybe it is just a pipeline that has no manual jobs
logger.warn('No jobs found', url: pipeline.web_url)
nil
end
def pipeline_for_version(version)
pipeline =
Retriable.with_context(:api) do
client
.pipelines(project, scope: :tags, ref: version)
.first
end
raise PipelineNotFoundError.new(version) unless pipeline
pipeline
end
def jobs_to_be_triggered(pipeline)
Retriable.with_context(:api) do
client
.pipeline_jobs(project, pipeline.id, scope: :manual, per_page: 100)
.auto_paginate
.select { |job| play_stages.include?(job.stage) }
end
end
def play_manual_jobs(triggers)
triggers.each do |job|
if SharedStatus.dry_run?
logger.info('Would play job', name: job.name, url: job.web_url)
next
end
logger.info('Play job', name: job.name, url: job.web_url)
Retriable.with_context(:api) do
client.job_play(project_path, job.id)
end
end
end
def project_path
project.dev_path
end
def client
@client ||= GitlabDevClient
end
end
end
end