Class: Ci::CreatePipelineService

Inherits:
BaseService show all
Defined in:
app/services/ci/create_pipeline_service.rb

Constant Summary collapse

LOG_MAX_DURATION_THRESHOLD =
3.seconds
LOG_MAX_PIPELINE_SIZE =
2_000
LOG_MAX_CREATION_THRESHOLD =
20.seconds
SEQUENCE =
[Gitlab::Ci::Pipeline::Chain::Build,
Gitlab::Ci::Pipeline::Chain::Validate::Abilities,
Gitlab::Ci::Pipeline::Chain::Validate::Repository,
Gitlab::Ci::Pipeline::Chain::Build::Associations,
Gitlab::Ci::Pipeline::Chain::Limit::RateLimit,
Gitlab::Ci::Pipeline::Chain::Validate::SecurityOrchestrationPolicy,
Gitlab::Ci::Pipeline::Chain::AssignPartition,
Gitlab::Ci::Pipeline::Chain::PipelineExecutionPolicies::EvaluatePolicies,
Gitlab::Ci::Pipeline::Chain::Skip,
Gitlab::Ci::Pipeline::Chain::Validate::Config,
Gitlab::Ci::Pipeline::Chain::Config::Content,
Gitlab::Ci::Pipeline::Chain::Config::Process,
Gitlab::Ci::Pipeline::Chain::StopLinting,
Gitlab::Ci::Pipeline::Chain::Validate::AfterConfig,
Gitlab::Ci::Pipeline::Chain::RemoveUnwantedChatJobs,
Gitlab::Ci::Pipeline::Chain::SeedBlock,
Gitlab::Ci::Pipeline::Chain::EvaluateWorkflowRules,
Gitlab::Ci::Pipeline::Chain::Seed,
Gitlab::Ci::Pipeline::Chain::Limit::Size,
Gitlab::Ci::Pipeline::Chain::Limit::ActiveJobs,
Gitlab::Ci::Pipeline::Chain::Limit::Deployments,
Gitlab::Ci::Pipeline::Chain::Validate::External,
Gitlab::Ci::Pipeline::Chain::SetBuildSources,
Gitlab::Ci::Pipeline::Chain::Populate,
Gitlab::Ci::Pipeline::Chain::PopulateMetadata,
Gitlab::Ci::Pipeline::Chain::PipelineExecutionPolicies::ApplyPolicies,
Gitlab::Ci::Pipeline::Chain::StopDryRun,
Gitlab::Ci::Pipeline::Chain::EnsureEnvironments,
Gitlab::Ci::Pipeline::Chain::EnsureResourceGroups,
Gitlab::Ci::Pipeline::Chain::Create,
Gitlab::Ci::Pipeline::Chain::CreateCrossDatabaseAssociations,
Gitlab::Ci::Pipeline::Chain::CancelPendingPipelines,
Gitlab::Ci::Pipeline::Chain::Metrics,
Gitlab::Ci::Pipeline::Chain::TemplateUsage,
Gitlab::Ci::Pipeline::Chain::ComponentUsage,
Gitlab::Ci::Pipeline::Chain::KeywordUsage,
Gitlab::Ci::Pipeline::Chain::Pipeline::Process].freeze

Constants inherited from BaseService

BaseService::UnauthorizedError

Instance Attribute Summary collapse

Attributes inherited from BaseService

#current_user, #params, #project

Instance Method Summary collapse

Methods inherited from BaseService

#initialize

Methods included from BaseServiceUtility

#deny_visibility_level, #event_service, #log_error, #log_info, #notification_service, #system_hook_service, #todo_service, #visibility_level

Methods included from Gitlab::Allowable

#can?, #can_all?, #can_any?

Constructor Details

This class inherits a constructor from BaseService

Instance Attribute Details

#loggerObject (readonly)

Returns the value of attribute logger.



5
6
7
# File 'app/services/ci/create_pipeline_service.rb', line 5

def logger
  @logger
end

#pipelineObject (readonly)

Returns the value of attribute pipeline.



5
6
7
# File 'app/services/ci/create_pipeline_service.rb', line 5

def pipeline
  @pipeline
end

Instance Method Details

#execute(source, ignore_skip_ci: false, save_on_errors: true, schedule: nil, merge_request: nil, external_pull_request: nil, bridge: nil, inputs: {}, **options, &block) ⇒ Ci::Pipeline

Create a new pipeline in the specified project.

rubocop: disable Metrics/ParameterLists, Metrics/AbcSize

Parameters:

  • source (Symbol)

    What event (Ci::Pipeline.sources) triggers the pipeline creation.

  • ignore_skip_ci (Boolean) (defaults to: false)

    Whether skipping a pipeline creation when ‘[skip ci]` comment is present in the commit body

  • save_on_errors (Boolean) (defaults to: true)

    Whether persisting an invalid pipeline when it encounters an error during creation (e.g. invalid yaml)

  • schedule (Ci::PipelineSchedule) (defaults to: nil)

    The pipeline schedule triggers the pipeline creation.

  • merge_request (MergeRequest) (defaults to: nil)

    The merge request triggers the pipeline creation.

  • external_pull_request (Ci::ExternalPullRequest) (defaults to: nil)

    The external pull request triggers the pipeline creation.

  • bridge (Ci::Bridge) (defaults to: nil)

    The bridge job that triggers the downstream pipeline creation.

  • content (String)

    The content of .gitlab-ci.yml to override the default config contents (e.g. .gitlab-ci.yml in repostiry). Mainly used for generating a dangling pipeline.

Returns:



66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# File 'app/services/ci/create_pipeline_service.rb', line 66

def execute(
  source,
  ignore_skip_ci: false, save_on_errors: true, schedule: nil, merge_request: nil,
  external_pull_request: nil, bridge: nil, inputs: {},
  **options, &block
)
  @logger = build_logger
  @command_logger = Gitlab::Ci::Pipeline::CommandLogger.new
  @pipeline = Ci::Pipeline.new

  validate_options!(options)

  @command = Gitlab::Ci::Pipeline::Chain::Command.new(
    source: source,
    origin_ref: params[:ref],
    checkout_sha: params[:checkout_sha],
    after_sha: params[:after],
    before_sha: params[:before],          # The base SHA of the source branch (i.e merge_request.diff_base_sha).
    source_sha: params[:source_sha],      # The HEAD SHA of the source branch (i.e merge_request.diff_head_sha).
    target_sha: params[:target_sha],      # The HEAD SHA of the target branch.
    schedule: schedule,
    merge_request: merge_request,
    external_pull_request: external_pull_request,
    ignore_skip_ci: ignore_skip_ci,
    save_incompleted: save_on_errors,
    seeds_block: block,
    variables_attributes: params[:variables_attributes],
    project: project,
    current_user: current_user,
    push_options: ::Ci::PipelineCreation::PushOptions.fabricate(params[:push_options]),
    chat_data: params[:chat_data],
    bridge: bridge,
    logger: @logger,
    partition_id: params[:partition_id],
    inputs: inputs,
    gitaly_context: params[:gitaly_context],
    **extra_options(**options))

  @pipeline.readonly! if @command.readonly?

  Gitlab::Ci::Pipeline::Chain::Sequence
    .new(pipeline, @command, SEQUENCE)
    .build!

  if pipeline.persisted?
    Gitlab::EventStore.publish(
      Ci::PipelineCreatedEvent.new(data: { pipeline_id: pipeline.id, partition_id: pipeline.partition_id })
    )

    after_successful_creation_hook
  else
    # If pipeline is not persisted, try to recover IID
    pipeline.reset_project_iid
  end

  if error_message = pipeline.full_error_messages.presence || pipeline.failure_reason.presence
    ::Ci::PipelineCreation::Requests.failed(params[:pipeline_creation_request], error_message)

    ServiceResponse.error(message: error_message, payload: pipeline)
  else
    ::Ci::PipelineCreation::Requests.succeeded(params[:pipeline_creation_request], pipeline.id)

    ServiceResponse.success(payload: pipeline)
  end

ensure
  @logger.commit(pipeline: pipeline, caller: self.class.name)
  @command_logger.commit(pipeline: pipeline, command: @command) if @command
end

#execute_async(source, options) ⇒ Object

rubocop: enable Metrics/ParameterLists, Metrics/AbcSize



137
138
139
140
141
142
143
144
145
146
147
# File 'app/services/ci/create_pipeline_service.rb', line 137

def execute_async(source, options)
  pipeline_creation_request = ::Ci::PipelineCreation::Requests.start_for_project(project)
  creation_params = params.merge(pipeline_creation_request: pipeline_creation_request)

  ::CreatePipelineWorker.perform_async(
    project.id, current_user.id, params[:ref], source.to_s,
    options.stringify_keys, creation_params.except(:ref).stringify_keys
  )

  ServiceResponse.success(payload: pipeline_creation_request['id'])
end

#yaml_processor_resultObject



149
150
151
# File 'app/services/ci/create_pipeline_service.rb', line 149

def yaml_processor_result
  @command.yaml_processor_result
end