Yes, there is a difference. By default, the value of when: is on_success -- jobs only run if jobs in previous stages succeed. Using always will allow the job to run, even if jobs in the previous stage failed.

Per the docs these are the possible values for when:

on_success (default): Run the job only when all jobs in earlier stages succeed or have allow_failure: true.
manual: Run the job only when triggered manually.
always: Run the job regardless of the status of jobs in earlier stages. Can also be used in workflow:rules.
on_failure: Run the job only when at least one job in an earlier stage fails. A job with allow_failure: true is always considered successful.
delayed: Delay the execution of a job for a specified duration.
never: Don’t run the job. Can only be used in a rules section or workflow: rules.

But if you did the following, it would be effectively the same as the first example:

  - if: "$CI_PIPELINE_SOURCE == "merge_request_event"
    when: on_success

This also assumes when: is not used in the job body.

If you do have when: in the body AND in your rules, this changes a bit.

myjob:
  when: always
  rules:
    - if: ...
      when: on_success  # this takes precedence if this rule matches
    - if: ...  # uses the default "when:" if this rule matches

In which case, adding the when: to the rules, the when: specified in the rules will take precedence over the when: set in the job body when the rule matches.

In older versions of GitLab, mixing job:when: and job:rules:when: is not allowed and results in an error.

Answer from sytech on Stack Overflow
🌐
GitLab
docs.gitlab.com › gitlab docs › use gitlab › use ci/cd to build your application › ci/cd yaml syntax reference
CI/CD YAML syntax reference | GitLab Docs
The two configurations are merged together, and the configuration in the .gitlab-ci.yml file takes precedence over the included configuration. ... Job, the include files are not fetched again. All jobs in a pipeline use the configuration fetched when the pipeline was created.
🌐
GitLab
docs.gitlab.com › gitlab docs › use gitlab › use ci/cd to build your application › jobs › control how jobs run › specify when jobs run with rules
Specify when jobs run with rules | GitLab Docs
job: script: echo "This job does NOT create double pipelines!" rules: - if: $CUSTOM_VARIABLE == "true" && $CI_PIPELINE_SOURCE == "merge_request_event" You can also avoid duplicate pipelines by changing the job rules to avoid either push (branch) pipelines or merge request pipelines. However, if you use a - when: always rule without workflow: rules, GitLab displays a pipeline warning.
Top answer
1 of 1
19

Yes, there is a difference. By default, the value of when: is on_success -- jobs only run if jobs in previous stages succeed. Using always will allow the job to run, even if jobs in the previous stage failed.

Per the docs these are the possible values for when:

on_success (default): Run the job only when all jobs in earlier stages succeed or have allow_failure: true.
manual: Run the job only when triggered manually.
always: Run the job regardless of the status of jobs in earlier stages. Can also be used in workflow:rules.
on_failure: Run the job only when at least one job in an earlier stage fails. A job with allow_failure: true is always considered successful.
delayed: Delay the execution of a job for a specified duration.
never: Don’t run the job. Can only be used in a rules section or workflow: rules.

But if you did the following, it would be effectively the same as the first example:

  - if: "$CI_PIPELINE_SOURCE == "merge_request_event"
    when: on_success

This also assumes when: is not used in the job body.

If you do have when: in the body AND in your rules, this changes a bit.

myjob:
  when: always
  rules:
    - if: ...
      when: on_success  # this takes precedence if this rule matches
    - if: ...  # uses the default "when:" if this rule matches

In which case, adding the when: to the rules, the when: specified in the rules will take precedence over the when: set in the job body when the rule matches.

In older versions of GitLab, mixing job:when: and job:rules:when: is not allowed and results in an error.

🌐
GitLab
about.gitlab.com › home › solutions › continuous integration and delivery (ci/cd)
Continuous Integration and Delivery (CI/CD)
Every team ends up rebuilding the same pipeline steps: security scans, build patterns, and deployment flows, because there's nowhere to find what already works. The CI/CD Catalog gives you a shared, versioned home for tested components, so new projects start from proven building blocks instead of another copy-pasted .gitlab-ci.yml.
🌐
GitLab
docs.gitlab.com › gitlab docs › use gitlab › use ci/cd to build your application › getting started
Get started with GitLab CI/CD | GitLab Docs
For example, a .gitlab-ci.yml file with a build stage and a test stage might look like this: stages: - build - test build-job: stage: build script: - echo "Compiling the code..." test-job: stage: test script: - echo "Running tests..." GitLab creates a pipeline each time it’s triggered, for example, by a commit, a merge request, on a schedule, or when you manually run one.
🌐
GitLab
docs.gitlab.com › gitlab docs › use gitlab › use ci/cd to build your application › jobs
CI/CD Jobs | GitLab Docs
Jobs are configured in the .gitlab-ci.yml file with a list of commands to execute to accomplish tasks like building, testing, or deploying code. ... Execute on a runner, for example in a Docker container. Run independently from other jobs. Have a job log with the full execution log for the job. Jobs are defined with YAML keywords that define all aspects of the job’s execution, including keywords that: Control how and when ...
Find elsewhere
🌐
Medium
medium.com › @yian806884 › comprehensive-guide-to-gitlab-ci-cd-081305b06a9a
Comprehensive Guide to GitLab CI/CD | by Yian Hsiao | Medium | Medium
October 16, 2023 - Typically, stages included in a CI/CD pipeline are: 1. Build: Code is compiled and ready for testing. 2. Test: Automated tests are executed on built code. 3. Deploy: After the build stage and test stages pass, the application could be deployed. The names and number of stages can vary depending on the specific needs of your project. Others might include stages like Lint, SAST, DAST, or Release. # in .gitlab-ci.yml stages: - build - test - deploy
🌐
GitLab
mfix.netl.doe.gov › help › help
Index · Pipelines · Ci · Help · GitLab
Select Settings > CI/CD. Select Display pipeline variables. Go to Build > Pipelines and select a pipeline that was run manually. Select the Manual Variables tab. Variable values are masked by default. If you have at least the Developer role, you can select the eye icon to reveal values. Markdown rendering on the Run pipeline page Introduced in GitLab 17.11.
🌐
Medium
medium.com › @bectorhimanshu › understanding-gitlab-ci-cd-end-to-end-workflow-made-simple-for-beginners-cdf5527f2fa4
Understanding GitLab CI/CD — End-to-End Workflow (Made Simple for Beginners) | by bectorhimanshu | Medium
October 18, 2025 - Let’s summarise what happens when a CI/CD pipeline runs : Developer pushes code to GitLab GitLab detects push (trigger) Reads .gitlab-ci.yml for instructions CI Runner is triggered Runner clones repo & runs defined jobs Jobs run as per defined stages Logs are sent back to GitLab UI Artifacts saved / App deployed
🌐
GitLab
docs.gitlab.com › gitlab docs › use gitlab › use ci/cd to build your application › pipelines
CI/CD pipelines | GitLab Docs
CI/CD pipelines are the fundamental component of GitLab CI/CD. Pipelines are configured in a .gitlab-ci.yml file by using YAML keywords. Pipelines can run automatically for specific events, like when pushing to a branch, creating a merge request, or on a schedule.
🌐
GitLab
docs.gitlab.com › gitlab docs › use gitlab › use ci/cd to build your application › jobs › job inputs
Job inputs | GitLab Docs
Job inputs and CI/CD pipeline configuration inputs serve different purposes: Job inputs are interpolated into the job configuration when the job is created. They are not environment variables and cannot be accessed with $INPUT_NAME syntax.
🌐
Medium
rragesh.medium.com › gitlab-pipelines-101-exact-job-targeting-with-rules-variables-4d4466deedd5
GitLab Pipelines 101: Exact Job Targeting with Rules & Variables | by Ragesh Ramachandran | Medium
October 15, 2025 - Schedule-specific jobs use rules with CI_PIPELINE_SOURCE == "schedule" and the right flag · Mutual exclusion in rules (A == true && B != true) ... If you have any questions do let me know in the comments. 📝✍ · Split Your GitLab Schedules: Run Only the Stages You Want with Scoped Variables + Rules
🌐
DEV Community
dev.to › zenika › gitlab-ci-10-best-practices-to-avoid-widespread-anti-patterns-2mb5
🦊 GitLab CI: 10+ Best Practices to Avoid Widespread Anti-Patterns - DEV Community
September 25, 2023 - In many companies, the software delivery process often includes centralized GitLab templates. This is particularly true in cases where the DevOps Team Silo anti-pattern exists. Instead of constantly adding and enriching templates in a centralized location for every new requirement, it is recommended to start by building your CI YAML locally.
🌐
GitLab
forum.gitlab.com › gitlab ci/cd
Job with when:manual runs every time - GitLab CI/CD - GitLab Forum
March 5, 2024 - Problem to solve I have a CI job defined mostly like this: metainfo: stage: test image: "some-image:latest" script: - validate-metainfo data/metainfo.xml needs: ["build@x86_64"] rules: - changes: - data/metainfo.xml when: always - when: manual allow_failure: true The idea is to always validate the file if it has been changed, but also to be able to trigger the change manually if we ant.
🌐
GitLab
forum.gitlab.com › gitlab ci/cd
How to run a job only when on tags, AND if specific folder has changed? - GitLab CI/CD - GitLab Forum
July 5, 2021 - 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.
🌐
Gitlab
docs.gitlab.co.jp › ee › ci › yaml › workflow.html
GitLab CI/CD `workflow` keyword | GitLab
workflow: rules: - if: $CI_PIPELINE_SOURCE == "schedule" when: never - if: $CI_PIPELINE_SOURCE == "push" when: never - when: always · This example prevents pipelines for schedules or push (branches and tags) pipelines. The final when: always rule runs all other pipeline types, including merge request pipelines. Introduced in GitLab 13.8.
🌐
Gitlab
alinex.gitlab.io › env › gitlab-ci.html
GitLab CI/CD - Alinex IT Reference & Guide
By giving a .gitlab-ci.yml configuration within the project this can be configured. The YAML file defines a set of jobs with constraints stating when they should be run, this is called the pipeline.