only and except could not be combined coherently — specifying both applied them independently and produced results nobody predicted.
deploy:production:
stage: deploy
script: [./deploy.sh]
rules:
- if: '$CI_COMMIT_BRANCH == "master" && $CI_PIPELINE_SOURCE == "push"'
when: manual
allow_failure: false
- when: never
# rules are evaluated in order; the first match wins.
# the trailing 'when: never' is the explicit default.
First-match-wins ordering is what makes rules comprehensible where the old pair was not, and the explicit terminating rule is a habit worth adopting — without it the default when nothing matches is on_success, which is the opposite of what a deploy job wants. allow_failure: false on a manual job is what stops the pipeline being marked green while the deployment is still waiting for somebody to press the button.