Class: Ci::CreatePipelineService

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

Constant Summary collapse

CreateError =
Class.new(StandardError)
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::Build::Associations,
Gitlab::Ci::Pipeline::Chain::Validate::Abilities,
Gitlab::Ci::Pipeline::Chain::Validate::Repository,
Gitlab::Ci::Pipeline::Chain::Limit::RateLimit,
Gitlab::Ci::Pipeline::Chain::Validate::SecurityOrchestrationPolicy,
Gitlab::Ci::Pipeline::Chain::Skip,
Gitlab::Ci::Pipeline::Chain::Config::Content,
Gitlab::Ci::Pipeline::Chain::Config::Process,
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::Deployments,
Gitlab::Ci::Pipeline::Chain::Validate::External,
Gitlab::Ci::Pipeline::Chain::Populate,
Gitlab::Ci::Pipeline::Chain::StopDryRun,
Gitlab::Ci::Pipeline::Chain::EnsureEnvironments,
Gitlab::Ci::Pipeline::Chain::EnsureResourceGroups,
Gitlab::Ci::Pipeline::Chain::Create,
Gitlab::Ci::Pipeline::Chain::CreateDeployments,
Gitlab::Ci::Pipeline::Chain::CreateCrossDatabaseAssociations,
Gitlab::Ci::Pipeline::Chain::Limit::Activity,
Gitlab::Ci::Pipeline::Chain::Limit::JobActivity,
Gitlab::Ci::Pipeline::Chain::CancelPendingPipelines,
Gitlab::Ci::Pipeline::Chain::Metrics,
Gitlab::Ci::Pipeline::Chain::TemplateUsage,
Gitlab::Ci::Pipeline::Chain::Pipeline::Process].freeze

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?

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, trigger_request: nil, schedule: nil, merge_request: nil, external_pull_request: nil, bridge: nil, **options, &block) ⇒ Ci::Pipeline

Create a new pipeline in the specified project.

rubocop: disable Metrics/ParameterLists

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)

  • trigger_request (Ci::TriggerRequest) (defaults to: nil)

    The pipeline trigger triggers the pipeline creation.

  • 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 (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:


63
64
65
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
# File 'app/services/ci/create_pipeline_service.rb', line 63

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

  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.
    trigger_request: trigger_request,
    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: params[:push_options] || {},
    chat_data: params[:chat_data],
    bridge: bridge,
    logger: @logger,
    **extra_options(**options))

  # Ensure we never persist the pipeline when dry_run: true
  @pipeline.readonly! if command.dry_run?

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

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

    create_namespace_onboarding_action
  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
    ServiceResponse.error(message: error_message, payload: pipeline)
  else
    ServiceResponse.success(payload: pipeline)
  end

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

#execute!(*args, &block) ⇒ Object

rubocop: enable Metrics/ParameterLists


120
121
122
123
124
125
126
127
128
129
# File 'app/services/ci/create_pipeline_service.rb', line 120

def execute!(*args, &block)
  source = args[0]
  params = Hash(args[1])

  execute(source, **params, &block).tap do |response|
    unless response.payload.persisted?
      raise CreateError, pipeline.full_error_messages
    end
  end
end