gitlab-org--gitlab-foss/lib/gitlab/data_builder/pipeline.rb

160 lines
4.8 KiB
Ruby

# frozen_string_literal: true
module Gitlab
module DataBuilder
# Some callers want to include retried builds, so we wrap the payload hash
# in a SimpleDelegator with additional methods.
class Pipeline < SimpleDelegator
def self.build(pipeline)
new(pipeline)
end
def initialize(pipeline)
@pipeline = pipeline
attrs = {
object_kind: 'pipeline',
object_attributes: hook_attrs(pipeline),
merge_request: pipeline.merge_request && merge_request_attrs(pipeline.merge_request),
user: pipeline.user.try(:hook_attrs),
project: pipeline.project.hook_attrs(backward: false),
commit: pipeline.commit.try(:hook_attrs),
builds: Gitlab::Lazy.new do
preload_builds(pipeline, :latest_builds)
pipeline.latest_builds.map(&method(:build_hook_attrs))
end
}
if pipeline.source_pipeline.present?
attrs[:source_pipeline] = source_pipeline_attrs(pipeline.source_pipeline)
end
super(attrs)
end
def with_retried_builds
merge(
builds: Gitlab::Lazy.new do
preload_builds(@pipeline, :builds)
@pipeline.builds.map(&method(:build_hook_attrs))
end
)
end
private
# rubocop: disable CodeReuse/ActiveRecord
def preload_builds(pipeline, association)
ActiveRecord::Associations::Preloader.new.preload(pipeline,
{
association => {
**::Ci::Pipeline::PROJECT_ROUTE_AND_NAMESPACE_ROUTE,
runner: :tags,
job_artifacts_archive: [],
user: [],
metadata: [],
ci_stage: []
}
}
)
end
# rubocop: enable CodeReuse/ActiveRecord
def hook_attrs(pipeline)
{
id: pipeline.id,
iid: pipeline.iid,
ref: pipeline.source_ref,
tag: pipeline.tag,
sha: pipeline.sha,
before_sha: pipeline.before_sha,
source: pipeline.source,
status: pipeline.status,
detailed_status: pipeline.detailed_status(nil).label,
stages: pipeline.stages_names,
created_at: pipeline.created_at,
finished_at: pipeline.finished_at,
duration: pipeline.duration,
queued_duration: pipeline.queued_duration,
variables: pipeline.variables.map(&:hook_attrs)
}
end
def source_pipeline_attrs(source_pipeline)
project = source_pipeline.source_project
{
project: {
id: project.id,
web_url: project.web_url,
path_with_namespace: project.full_path
},
job_id: source_pipeline.source_job_id,
pipeline_id: source_pipeline.source_pipeline_id
}
end
def merge_request_attrs(merge_request)
{
id: merge_request.id,
iid: merge_request.iid,
title: merge_request.title,
source_branch: merge_request.source_branch,
source_project_id: merge_request.source_project_id,
target_branch: merge_request.target_branch,
target_project_id: merge_request.target_project_id,
state: merge_request.state,
merge_status: merge_request.public_merge_status,
url: Gitlab::UrlBuilder.build(merge_request)
}
end
def build_hook_attrs(build)
{
id: build.id,
stage: build.stage_name,
name: build.name,
status: build.status,
created_at: build.created_at,
started_at: build.started_at,
finished_at: build.finished_at,
duration: build.duration,
queued_duration: build.queued_duration,
failure_reason: (build.failure_reason if build.failed?),
when: build.when,
manual: build.action?,
allow_failure: build.allow_failure,
user: build.user.try(:hook_attrs),
runner: build.runner && runner_hook_attrs(build.runner),
artifacts_file: {
filename: build.artifacts_file&.filename,
size: build.artifacts_size
},
environment: environment_hook_attrs(build)
}
end
def runner_hook_attrs(runner)
{
id: runner.id,
description: runner.description,
runner_type: runner.runner_type,
active: runner.active?,
is_shared: runner.instance_type?,
tags: runner.tags&.map(&:name)
}
end
def environment_hook_attrs(build)
return unless build.has_environment?
{
name: build.expanded_environment_name,
action: build.environment_action,
deployment_tier: build.persisted_environment.try(:tier)
}
end
end
end
end