Feedback

Chat Icon

Cloud Native CI/CD with GitLab

From Commit to Production Ready

Conditional Jobs and Pipelines
66%

Workflows: Controlling Pipelines Execution

We have seen how to control the execution of a job based on conditions. For example, a job will launch only when a specific branch is pushed or when a specific user triggers the pipeline. However, sometimes you need to control the execution of the whole pipeline conditionally. This is where the workflow keyword is useful.

Example:

Let's use this command to create a .gitlab-ci.yml file with a workflow that runs only when the branch name starts with feature/:

cd $HOME/todo/app && \
git checkout main && \
cat <$HOME/todo/app/.gitlab-ci.yml && \
git add . && \
git commit -m "Add workflow rules" && \
git push origin main
# Define the workflow
workflow:
  # Add a rule to run the pipeline only when 
  # the branch name starts with "feature/"
  rules:
    - if: '\$CI_COMMIT_BRANCH =~ /^feature\//'

stages:
  - build
  - test
  - deploy

job-1:
  stage: build
  script:
    - echo "running job-1"

job-2:
  stage: test
  script:
    - echo "running job-2"

job-3:
  stage: deploy
  script:
    - echo "running job-3"
EOF

The pipeline above will not run because of the workflow rules. The workflow keyword is global and determines the execution of the whole pipeline. In this case, the pipeline will run only when the branch name starts with feature/ which is not the case (we are pushing to the main branch). If we push the code to a branch that starts with feature/, it will run.

You can also test this by creating a new branch and pushing the code to it:

cd $HOME/todo/app && \
git checkout -b feature/my-feature || git checkout feature/my-feature && \
git push origin feature/my-feature && \
git checkout main

Example:

It's worth noting that workflows rules in the main .gitlab-ci.yml file always override the rules in included files. For example, you have this configuration in your .gitlab-ci.yml file:

# .gitlab-ci.yml
include:
  - local: .includes/job.yml

workflow:
  rules:
    - if: '$CI_COMMIT_BRANCH == "main"'

job-0:
  stage: build
  script:
    - 'echo "$CI_COMMIT_BRANCH"'    

Here is the content of the included file:

# .includes/job.yml
workflow:
  rules:
    - if: '$CI_COMMIT_BRANCH == "dev"'

job-1:
  stage: build
  script:
    - 'echo "$CI_COMMIT_BRANCH"'

While the job-1 job is set to run only when the branch name is dev, it will run only when the branch name is main. This is because the workflow rules in the main .gitlab-ci.yml file override the rules in the included file.

Example:

Let's take another example to show some more advanced cases and pitfalls. Let's say you decided to use the features of GitLab workflows to control the execution of your included files. So instead of using it in the main .gitlab-ci.yml file, you decided to set the workflow rules in the included files.

This is what you may have in your main .gitlab-ci.yml file:

# .gitlab-ci.yml
include:
  - local: .includes/job-dev.yml
  - local: .includes/job-main.yml

job-0:
  stage: build
  script:
    - 'echo "$CI_COMMIT_BRANCH"'

The first file (job-dev.yml) contains the following content:

# .includes/job-dev.yml 
workflow:
  rules:
    - if: '$CI_COMMIT_BRANCH == "dev"'

job-dev:
  stage: build

Cloud Native CI/CD with GitLab

From Commit to Production Ready

Enroll now to unlock all content and receive all future updates for free.