gitlab-org--gitlab-foss/lib/gitlab/ci/pipeline/chain/build/associations.rb

83 lines
2.6 KiB
Ruby

# frozen_string_literal: true
module Gitlab
module Ci
module Pipeline
module Chain
class Build
class Associations < Chain::Base
include Gitlab::Allowable
include Chain::Helpers
def perform!
assign_pipeline_variables
assign_source_pipeline
end
def break?
@pipeline.errors.any?
end
private
def assign_pipeline_variables
@pipeline.variables_attributes = variables_attributes
end
def assign_source_pipeline
return unless @command.bridge
@pipeline.build_source_pipeline(
source_pipeline: @command.bridge.pipeline,
source_project: @command.bridge.project,
source_bridge: @command.bridge,
project: @command.project
)
end
def variables_attributes
variables = Array(@command.variables_attributes)
variables = apply_permissions(variables)
validate_uniqueness(variables)
end
def apply_permissions(variables)
# We allow parent pipelines to pass variables to child pipelines since
# these variables are coming from internal configurations. We will check
# permissions to :set_pipeline_variables when those are injected upstream,
# to the parent pipeline.
# In other scenarios (e.g. multi-project pipelines or run pipeline via UI)
# the variables are provided from the outside and those should be guarded.
return variables if @command.creates_child_pipeline?
if variables.present? && !can?(@command.current_user, :set_pipeline_variables, @command.project)
error("Insufficient permissions to set pipeline variables")
variables = []
end
variables
end
def validate_uniqueness(variables)
duplicated_keys = variables
.map { |var| var[:key] }
.tally
.filter_map { |key, count| key if count > 1 }
if duplicated_keys.empty?
variables
else
error(duplicate_variables_message(duplicated_keys), config_error: true)
[]
end
end
def duplicate_variables_message(keys)
"Duplicate variable #{'name'.pluralize(keys.size)}: #{keys.join(', ')}"
end
end
end
end
end
end
end