Conjunction logic for build conditions
Description
There are two specific conditions that I want to be true for when our libraries are deployed for a specific commit:
- The commit must be to the master branch.
- The commit is a tag.
When I read through the documentation, I thought I might be able to define this in our .gitlab-ci.yml
file like so:
job:
stage: publish
script:
- ./do-publish.sh
only:
- tags
- master
However, these conditions under the only
clause are not conjunctive, but rather disjunctive. In other words, the build will be triggered for tag commits or commits to master - not when both conditions are true. This is undesirable and, frankly, surprising. It makes sense if your conditions are a collection of branch names as a commit cannot be in two branches at the same time, but not for any situation when you combine different types of constraints.
From our perspective, if someone happens to make a tag in a feature branch for others to reference, that should not cause a deployment. Additionally, not all commits to master should result in a deployment. We may be merging several features together before we consider it a completed version we wish to deploy.
Proposal
I have two ideas here, the first being a nonbreaking change and less discoverable, the second being a breaking change but, in my humble opinion, easier to understand:
Suggestion 1 - Nonbreaking, but less discoverable
Since multiple lines under the only
(and potentially except
?) clauses are already locked into disjunctive OR
logic, you could reuse the well known &&
operator from a variety of scripting languages to combine clauses together. The end result would look something like this:
job:
stage: publish
script:
- ./do-publish.sh
only:
- tags && master
Suggestion 2 - Breaking, but more explicit and discoverable
- Make
only
andexcept
more explicit, such that each type of constraint is conjunctive, but the conditions for each type is disjunctive. For example, something like this for my situation:
job:
stage: publish
script:
- ./do-publish.sh
only:
tags: true
branches:
- master
But if you wanted the old functionality, you could do the following:
job:
stage: publish
script:
- ./do-publish.sh
only:
tags: false
branches:
- release
- master
Suggestion 3 - Easier to understand and reason about
This version is inspired by Travis conditions
only: source:triggers AND ref:master AND var($TRIGGER_ACTION == "index") AND var($APP_ID) AND var($API_KEY)
or
only: ref:master AND NOT $SOME_VAR == 'some value'
as discussed in #57231 (moved)
Links / references
This has been discussed in length over on GitHub as the community has scrounged for solutions and workarounds, but apparently that was not the place to discuss it. At a request of @zj on this GitHub issue, it sounds like this is the place to open this issue.