Pipeline job is executed although the rules should not apply

Hi,

if have a job like this:

build_php8_ci_image:
    stage: build_image
    image: docker:20.10.10
    before_script:
        - ''
    services:
        - docker:20.10.10-dind
    rules:
        - if: $CI_PIPELINE_SOURCE == "schedule"
        - if:  $CI_PIPELINE_SOURCE != "schedule"
          changes:
              - "container/ci-php8/*"
              - "ci-cd/gitlab-ci/build-php8-ci-image.yml"
    script: ....

I am expecting, that this job runs only, if the pipeline is triggered by

  1. scheduling or
  2. at least one of the named files has changed.

But the job runs also if

  1. a git tag is added ($CI_PIPELINE_SOURCE = push)
  2. the pipeline is triggered by the web-GUI ($CI_PIPELINE_SOURCE = web)

On a “normal” push (not creating a tag) or merge the job don’t run as expected. So I don’t understand, why the job runs when adding a tag or the pipeline is triggered by the web-GUI.

I am using gitlab.com and no specific runner is configured.
What is my mistake?

Thanks for your help!
Mathias

Hi @bytecounter1

The default rule is when: on_success, so I think you need something like this:

    rules:
        - if: $CI_PIPELINE_SOURCE == "schedule"
        - if:  $CI_PIPELINE_SOURCE != "schedule"
          changes:
              - "container/ci-php8/*"
              - "ci-cd/gitlab-ci/build-php8-ci-image.yml"
        - when: never

Hi @snim2,

I tried out, still same problem. Your suggestion seems to be a possible solution, but then the problem should also appear with other jobs. “when” I used very little. The rules in other jobs works as expected.
I have not yet found an simple way to debug rules. This could be a good approach.

Addendum: I expanded the $CI_PIPELINE_SOURCE != "schedule" condition with
$CI_PIPELINE_SOURCE != "schedule" && $CI_PIPELINE_SOURCE != "web" && $CI_COMMIT_TAG == null
Now the job don’t run when a git-tag is created or the pipeline is triggered by the web interface. Not nice but the problem is fixed for now. Still, I’d like to know why the problem happened…
So I leave this topic as unresolved.

If you don’t use when then the default is always on_success. In your original question, you say the job still runs when you push a tag, but you didn’t have a when clause for tags, so the pipeline ran. I’d have expected the when: never in my answer to deal with that, so I’m curious that you say it didn’t.

I don’t have time to try this out on a test repo today, but I’ll try to come back to it.

I had the same issue: wanted to run specific jobs via web-ui by setting a variable in UI (e.g. DEPLOY_YOURAPP ) or when some files changed.
The following solution worked for me:

yourapp_deploy:
  rules:
    - if: $CI_PIPELINE_SOURCE == "web" && $DEPLOY_YOURAPP != "true"
      when: never
    - if: $CI
      changes:
        paths:
          - "**/yourapp/*"

Just for proper closing this, I found this in the gitlab documentation:

You should use rules: changes only with branch pipelines or merge request pipelines . You can use rules: changes with other pipeline types, but rules: changes always evaluates to true when there is no Git push event. Tag pipelines, scheduled pipelines, manual pipelines, and so on do not have a Git push event associated with them. A rules: changes job is always added to those pipelines if there is no if that limits the job to branch or merge request pipelines.

Do you know how I can check if a pipeline is a branch pipeline?
The documentation here says that checking with if: $CI_COMMIT_BRANCH is enough.

But this is not true since the job will also run for pipelines that are triggered manually.

- if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
  changes:
        - 'somefile.yaml'