Discussion: CI inputs and interpolation strategy and future vision
Note on scope of this issue: The intention of this issue is to discuss how inputs how interpolated, and the impact of that implementation on our feature plans. It is not to discuss alternative ways of defining inputs (from a file, in the UI, etc)
Expected outcome: Creating issues for the chosen next steps so we can fix input types not being respected and implement array type inputs
Objectives
-
✅ Objective 1: Have inputs be usable in all places that variables can be used, and be able to have any value variables can have- Hash interpolation supports this now, except that number and boolean types are not being respected
-
💪 Objective 2: Make inputs more powerful than variables- Add
array
type: gitlab-org/gitlab#407176 (closed)- Question: Do we want to require users to type the items in an array input? Will we allow multi-type arrays?
- Add
hash
type:- Question: We do want these, right? Will we enforce typing of subkeys in the hash? Will the input definition specify the entire hash structure?
- If we want this, let's make an issue for it
- Support inputs with
!reference
: gitlab-org/gitlab#424481- Text interpolation supports this. Hash interpolation does not
- Note: This may not be necessary: gitlab-org/gitlab#424481 (comment 1751780425)
- Have a way to use inputs to selectively include or not include CI keywords: gitlab-org/gitlab#438771 (closed)
- Add
-
🛠 Objective 3: Ensure that inputs can be used in an isolated and consistent manner- Expand variables before using them as input values: gitlab-org/gitlab#438723
- Ensure that input types are respected: gitlab-org/gitlab#434826 (closed)
- Maybe: Provide a function that makes it easier to inject inputs into scripts without worrying about quoting issues gitlab-org/gitlab#407556 (comment 1636396937)
-
🔒 Objective 4: Ensure the implementation does not unnecessarily open us or our users up to attack- Question: In text interpolation, it's possible to use string inputs to manipulate the content of the YAML file. Are we okay with that? gitlab-org/gitlab#439272 (comment 1751952462)
- Question: Are we planning to try to use inputs with compliance pipelines in a way that does not allow users to change the content of the pipeline?
Options
Hash interpolation
This is the first iteration of CI interpolation. It's currently being used in the CI Catalog and CI inputs Betas.
How it works
- An included YAML file is parsed into a Ruby hash
- Each node of the hash is scanned for interpolation blocks.
- If one is found, it's replaced with the corresponding input
- This operation uses
gsub
Challenges
- Non-string types are not being respected
- We don't yet know how or if to implement structure types
- We don't know yet how or if to make
!reference
work (if we decide that is a necessity)
Possible next steps
- Fix non-string input types: gitlab-org/gitlab#439272 (comment 1751757103) contains a possible fix
- Spike on including array and hash type inputs
- Spike on using
!reference
Text interpolation
This is a proposed second iteration of CI interpolation. It's currently implemented behind the (disabled) ci_text_interpolation
feature flag.
How it works
- An included YAML file is scanned in its entirety for interpolation blocks (
gsub
) - Input values are cast to JSON (except string types, which are more complicated)
- The blocks are replaced by the input values (
gsub
) - The YAML is parsed into Ruby
Challenges
- Because the YAML is parsed after interpolation, string inputs can be used to manipulate the included YAML in possibly unexpected ways
- This could prevent us from using inputs to strengthen the immutability of compliance pipelines
- String inputs need to be treated as a special case because casting them to JSON sometimes adds unwanted quotes
Possible Next steps
- Implement a "best attempt" fix for string type interpolation: gitlab-org/gitlab!143078 (closed) (with some updates)
- When a string input meets the following conditions:
- It might be parsed as a non-string
- It is surrounded by whitespace
- Then surround it with quotes. Otherwise leave it unquoted
- Update the docs to provide examples of workarounds for this problem
- When a string input meets the following conditions:
- Add functions that can be used to control the quoting of string inputs. One option might be to have a
shellescape
function that makes it easier to insert strings into shell commands. We could also havequote
andunquote
functions - Determine whether YAML manipulation is a security concern
- Particularly in the case of compliance pipelines
???
Is there a better way to go about this? Is there a point at which we'd like to explore replacing YAML with something easier to interpolate/manipulate?
Decision time!
We'll move ahead with the plan discussed in #127 (comment 1755423243)