Less ambiguous sections in 'only' and 'except' blocks in "complex" CI/CD YAML
Problem to solve
There are two problems with the refs:
block within only:
and except:
in CI YAML:
- It's poorly named, because many of the possible values are not refs.
- The possible values are ambiguous -- they could be branch names, tag names, or one of the "special keywords", it's impossible to be precise about the conditions, and unexpected behavior may result in some cases (see gitlab-ce#57075). The only way to get specific behaviors is to use the
variables:
block.
It seems it would be easy to replace the refs:
block with some more meaningful options that would greatly improve the usability of the CI/CD configuration.
This would make the refs:
block behave differently from the "simplified" form of only
and except
, but IMHO that's OK (and preferable if it allows more power and flexibility).
Target audience
This helps whoever writes, tests, and manages the GitLab CI configuration. Might include:
- Delaney, Development Team Lead
- Sasha, Software Developer
- Devon, DevOps Engineer
Further details
Git refs are branch names and tag names. It's true those are valid values for the refs:
block. But there are also the "special keywords" such as "tags", "branches", "api", and "external". Those are not refs in the Git sense of the word. Although the "simplified" only/except form allows them all comingled, the "complex" form allows more specificity.
Plus, the options are ambiguous, resulting in unexpected behavior. For example, if your job is set to
only:
refs:
- web
... it will actually run under 3 conditions:
- When run using the "Run pipeline" button in the GitLab UI (as described in the documentation)
- When run on a branch called 'web'
- When run on a tag called 'web'
(and it's ambiguous which one is meant in that case.)
Given that this is the "complex" form of the only/except blocks, we can be more specific and remove the ambiguity.
Proposal
I propose replacing the refs:
block with three separate options.
-
branches:
for branch names only -
tags:
for tag names only -
triggers:
(or some more appropriate word) for only the special keywords listed in the docs such as "branches", "tags", and "web" -- which should only have their "special keyword" meaning and not reference tags or branches.
There may be some confusion about the interplay between these blocks. Given that the child keys within only:
are ANDed against each other, I imagine that if the developer includes both branches:
and tags:
that their job will actually never run. Because a pipeline is (I believe) always run on either a branch or a tag, but not both. So perhaps it should be an error to include both, or the AND/OR logic should be changed (I realize there are some other issues about that).
Note that the documentation for CI/CD YAML says of the "complex" form:
This an alpha feature, and it is subject to change at any time without prior notice!
... therefore it is reasonable to change it to make it better at this time.
It could be possible to implement these new blocks and leave the "refs" block in as deprecated for anyone who has used it
What does success look like, and how can we measure that?
Some possible success metrics (I'm ignorant of what can actually be measured):
- increased usage of the
only
andexcept
blocks with the more specific options, indicating that it's useful - decreased usage of the
variables:
block for simple cases like testing$CI_COMMIT_TAG
(which is currently the only definitive way to run a job on a specific tag name reliably) - decreased support tickets with issues related to CI/CD configuration
- massive growth in sales and renewals because everyone loves the product!
Acceptance criteria: the branches:
, tags:
, and triggers
blocks work as described and don't interfere with each other.
Links / references
Comingling of "simplified" only
options causes unexpected behavior (gitlab-ce#57075)