How to run a job only when on tags, AND if specific folder has changed?

Hello,

I have a gitlab CI/CD pipeline which has a couple manual jobs that I want to run only on specific conditions

The jobs should only appear in the pipeline if the pipeline running is a tag, AND if there have been changes to a specific folder that we’ll call tests.

I have a .gitlab-ci.yml that looks like this:

stages:
  - build
  - test
  - deploy

build:
  stage: build
  image and stuff...

test:
  stage: test
  when: manual
  allow_failure: false
  needs:
    - build
  only:
    changes:
      - tests/*
    refs:
      - tags

deploy:
  stage: deploy
  needs:
    - test
  only:
    changes:
      - tests/*
    refs:
      - tags

I’m omitting other jobs here that are not relevant to my question.

With this configuration, if I have a tag but no changes in the tests folder, the test job still appears, and because I have it set as not allowed to fail, the pipeline gets stuck. So I have to comment out the allow_failure: false line if I want it to work. It seems to me that only makes the job appear if the pipeline is a tag OR if there’s been changes to the tests folder, and I’d like it to make the job appear if the pipeline is a tag AND if there’s been changes to the tests folder.

I see in the documentation that only is not developed anymore, and that it’s encouraged to use rules instead, but I’ve searched in the documentation and couldn’t find a way to make a job only appear in the pipeline if it’s a tag. The only things tag related I could find was to create a tag, but I create my tags manually.

How could I get the behaviour I want, with only or with rules ? Is it even possible with current gitlab or will I have to keep my manual jobs as allowed to fail, and skip them ?

Thanks

Hi @araly welcome to the forum. I think you want something like this:

workflow:
  rules:
    - if: $CI_MERGE_REQUEST_ID
      when: never
    - when: always

stages:
  - build
  - test
  - deploy

build:
  stage: build
  image and stuff...

test:
  stage: test
  rules:
    - if: '$CI_COMMIT_TAG'
      changes:
        - tests/*
      when: manual
    - when: never
  script:
    - echo "test"

deploy:
  stage: deploy
  needs:
    - test
  rules:
    - if: '$CI_COMMIT_TAG'
      changes:
        - tests/*
      when: on_success
    - when: never
  script:
    - echo "deploy"

That workflow key at the top prevents you having two pipelines for every merge request.

I’m not sure whether you wanted the test job to run manually when tests/* has changed and a tag has been pushed. If you want that to happen automatically, but the job to run manually otherwise, you want:

test:
  stage: test
  rules:
    - if: '$CI_COMMIT_TAG'
      changes:
        - tests/*
      when: on_success
    - when: manual
  script:
    - echo "test"

BTW when you’re using rules it’s always useful to have the predefined variables page open.

HTH,

Sarah

1 Like