Skip to content

Backend: Expand include:component to load locally defined components

Everyone can contribute. Help move this issue forward while earning points, leveling up and collecting rewards.

Background

With Implement `include:component` syntax (#387178 - closed) we introduced include:component syntax that fetches and includes components defined in any projects on the GitLab instance.

In the blueprint we describe the use case of components that can be defined locally (in the same repo).

Problem statement

As a pipeline author I would like to breakdown my pipeline into high level components. I want to create components that are considered private to my repository and not published to any catalog.

Proposal (as per blueprint)

# .gitlab/ci/config.yml
include:
  - component: ./path/to/component #=> .gitlab/ci/path/to/component/template.yml
  - component: ../path/to/component #=> .gitlab/path/to/component/template.yml
  - component: ../../path/to/component #=> path/to/component/template.yml

I would like to include components using a path relative to the current file's directory.

Details

We need to introduce a new class Gitlab::Ci::Components::LocalPath that behaves like similarly to Gitlab::Ci::Components::InstancePath.

# pseudo code
class LocalPath
  def self.match?(address)
    !address.include?('@') && address.start_with?('.')
  end

  def initialize(address:, content_filename:, project:, sha:, current_filepath:)
    # 
  end

  def fetch_content!(current_user:)
    return unless project
    return unless sha

    raise Gitlab::Access::AccessDeniedError unless Ability.allowed?(current_user, :download_code, project)

    current_project.repository.blob_data_at(sha, project_file_path)
  end

  def project_file_path
    File.join(current_filepath, address, content_filename)
  end
  
  # ...
end

In order to use relative paths we need to propagate the current file's path in Gitlab::Ci::Config::External::Context. The use of relative path should raise an error if the current file's path is not provided in the context (e.g. when using any of include:{remote|template|artifact}).

Edited by 🤖 GitLab Bot 🤖