Backend: Expand `include:component` to load locally defined components
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}
).