CI complex except does not work according to the documentation
Everyone can contribute. Help move this issue forward while earning points, leveling up and collecting rewards.
Problem to solve
Following up on the https://gitlab.com/gitlab-org/gitlab-ce/issues/49481 . The current behaviour of Gitlab CI except with variables and refs is opposite to the documentation. The documentation states If you use multiple keys under only or except, they act as an AND. The logic is: (any of refs) AND (any of variables) AND (any of changes) AND (if kubernetes is active).
But right now only works like that, but except works like refs OR variables. The documentation should be updated and there should be a way to specify exclusive behaviour for except instead of inclusive.
Intended users
Gitlab CI users with complex pipelines.
Further details
My use case and what I saw in the issue specified above is that it is common problem when you try to bump the version of your application inside pipelines.
You want to have stage that commits and pushes new version after merge request was merged to the master/devel branch and because this will make another push to the branch, this will cause all pipelines to run again, which slows down CI by a lot.
version_upgrade:
only:
refs:
- devel
except:
variables:
- $CI_COMMIT_MESSAGE =~ /\[server\] version upgrade to:/
test-e2e:
except:
refs:
- devel
variables:
- $CI_COMMIT_MESSAGE =~ /\[server\] version upgrade to:/
There is a workaround, but you need to specify more jobs:
version_upgrade:
only:
refs:
- devel
except:
variables:
- $CI_COMMIT_MESSAGE =~ /\[server\] version upgrade to:/
test-e2e:
except:
refs:
- devel
test-e2e-devel:
only:
refs:
- devel
except:
variables:
- $CI_COMMIT_MESSAGE =~ /\[server\] version upgrade to:/
But if you have a lot of jobs this forces you to write a lot of boilerplate code that could be solved easily. Also the current behaviour of complex except feels counterintuitive (and does not work as described in the documentation), because there is different behaviour for only and except.
Proposal
As described in the issue above by @brodock , I propose only_and, only_or, except_and, except_or
only_and:
refs: # AND
- branches # OR
- tags # OR
- triggers # OR
variables: # AND
- $GITLAB_DEV # OR
only_or:
refs: # OR
- branches # OR
- tags # OR
- triggers # OR
variables: # OR
- $GITLAB_DEV # OR
except_and:
refs: # AND
- branches # OR
- tags # OR
- triggers # OR
variables: # AND
- $GITLAB_DEV # OR
except_or:
refs: # OR
- branches # OR
- tags # OR
- triggers # OR
variables: # OR
- $GITLAB_DEV # OR
Permissions and Security
no extra permissions
Documentation
https://docs.gitlab.com/ee/ci/yaml/#onlyexcept-advanced section needs to be updated regardless of this proposal, because now it is not correct.
Testing
I see it as a quite a small change that does not break backward compatibility (even though complex except/only is still in alpha) and does not need any special testing plan.
What does success look like, and how can we measure that?
Reduce the number of duplicated jobs in Gitlab CI configuration file and make the behaviour more consistent and predictable.