ci pipelines: add negation support in expressions

This is my first feature proposal for Gitlab. I'm not sure an MR is the right place for that, and if it isn't, I'd appreciate information what would be.

What does this MR do and why?

This merge request adds a ! operator to pipeline expressions, so you can negate them. For example:

job:
 rules:
 - if: "!$VAR1 && $VAR2"

The motivation for this is that often it's either more convenient to negate a whole subexpression than to negate all the operators, but also, because sometimes there's no other way.

Consider the following expression: !($[[inputs.user_supplied_predicate]]). There is no generic way of negating a predicate from an input right now, and this operator provides it. We could ask the user to provide the negated form of course, but what if we actually need both of them?

Even if we don't take it from an input, in my opinion this is more readable and maintainable:

.predicates:
  condition:     ' (($CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH == "develop") && $MY_VARIABLE)'
  not_condition: '!(($CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH == "develop") && $MY_VARIABLE)'

Than this:

.predicates:
  condition:     '($CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH == "develop") && $MY_VARIABLE'
  not_condition: '($CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH && $CI_COMMIT_BRANCH != "develop") || $MY_VARIABLE == null || $MY_VARIABLE == ""'

I'm actually not sure if I didn't make a mistake in the latter.

Besides, as an user, I think having ! is intuitively obvious when you have parentheses, && and ||.

References

This MR probably partially addresses #584375. There's also a request to document this, assuming that it's already possible to negate expressions. I haven't found a feature request for this feature specifically.

Screenshots or screen recordings

There's nothing to show on a screenshot.

How to set up and validate locally

Try the examples from the docs, or just add ! somewhere in a rule:if in your pipeline.

MR acceptance checklist

This is a rather simple MR. To the best of my knowledge, it cannot meaningfully impact performance or security. The quality should be on par with the rest of the code, considering that most of it is copy-pasted boilerplate from other components.

Merge request reports

Loading