Can't figure out job rules

Hello everyone.

I have a mono repository with a couple of projects and have recently set up a pipeline to build only one project and it worked great. But now I need to add a build for one more project and they both need to work separately and independently.
As I said, this is monorepo, so these projects share the same gitlab-ci.yml
I created the same file structures for both projects to store their stages and job configurations, and combined them using the include directive. This is how it looks:
image

Contents of .gitlab-ci.yml:

include:
    - local: 'gitlab-ci/main.yml'

Contents of gitlab-ci/main.yml:

include:
    - local: 'gitlab-ci/stages.yml'
    - local: 'gitlab-ci/vars.yml'

Contents of gitlab-ci/stages.yml

stages:
    - build-project1
    - test-project1
    - deploy-project1
    - build-project2
    - test-project2
    - deploy-project2

include:
    - local: 'gitlab-ci/project1/build.yml'
    - local: 'gitlab-ci/project1/test.yml'
    - local: 'gitlab-ci/project1/deploy.yml'
    - local: 'gitlab-ci/project2/build.yml'
    - local: 'gitlab-ci/project2/test.yml'
    - local: 'gitlab-ci/project2/deploy.yml'

For example contents of gitlab-ci/project1/test.yml (and same for the rest files):

include:
    - local: "gitlab-ci/project1/templates/test-tpl.yml"

test:project1:
    extends: .test:project1:tpl
    ....

And finally contens of gitlab-ci/project1/templates/test-tpl.yml:

.test:project1:tpl:
      stage: test-project1
      variables:
        ...
      script:
        ...
      rules:
        rules:
        - if: $CI_COMMIT_MESSAGE =~ /^test_ci$/i
          when: always
        - if: $CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == "project1"
          changes:
            - Dockerfile*
          when: manual
        - if: $CI_COMMIT_TAG =~ /^.*release.*$/i
          when: always
          allow_failure: false
        - allow_failure: true
        - when: never

In this example the main goal that I tried to achieve is that:

  • test stage for project1 always runs if commit message contents “test_ci” (for pipeline testing)
  • runs manually if it was a push to a project branch but changes were made on dockerfiles
  • always runs if it was tagged with “release”
  • and doesn’t run in other cases

But in reality, this work is never created, and it seems that the “if” conditions are completely ignored. And if I remove the last “- when: never” directive, it will be created and will always be executed.
And if I manually run the pipeline for the project1 branch through the gitlab web interface, then none of its jobs will be created, but the jobs for project2 will be (I assume its because there’s a master branch in conditions of project2)

I think I misunderstood something in rules concept (btw I also can’t get “correct” behaviour with only/except) but can’t figure out what exactly.

P.S.: this example was simplified to explain my use case, sorry if it looks confusing anyway. The real pipeline config is a bit more complicated
P.P.S: I’m running gitlab-ee v13.3.6

Hi @npopov
I guess that the double rules: in gitlab-ci/project1/templates/test-tpl.yml is just a copy/paste error.
Rules are evaluated from the top to bottom until first match is find.

I have tried to replicate your issues on my gitlab-ee 13.9 and all rules worked as you expect. So this might be something that was changed/fixed in later versions.

What you could try (and I am only guessing here) is to encapsulate the conditions in single quotes like this:

      rules:
        - if: '$CI_COMMIT_MESSAGE =~ /^test_ci$/i'
          when: always

One thing I have noticed in the past is that all official examples of rules used to have conditions in single quotes and only recently new examples don’t include them anymore.

Docs for 13.3 are not available on web anymore so I cannot check if something else changed.

Ok, thanks. I’ll give it a try

Unfortunatly that doesn’t help. I guess I need to try to update gitlab…