Using conditionals
Using conditionals, you can run builds or steps only when specific conditions are met. Define boolean conditions using C-like expressions.
You can define conditionals at the step level in your pipeline.yml
or at the pipeline level in your Buildkite version control provider settings.
Conditionals in pipelines
You can have complete control over when to trigger pipeline builds by using conditional expressions to filter incoming webhooks. You need to define conditionals in the pipeline's Settings page for your repository provider to run builds only when expressions evaluate to true
. For example, to run only when a pull request is targeting the main branch:
Pipeline-level build conditionals are evaluated before any other build trigger settings. If both a conditional and a branch filter are present, both filters must pass for a build to be created – first the pipeline-level limiting filter and then the conditional filter.
Conditionals are supported in Bitbucket, Bitbucket Server, GitHub, GitHub Enterprise, and GitLab (including GitLab Community and GitLab Enterprise). You can add a conditional on your pipeline's Settings page in the Buildkite interface or using the REST API.
Conditional expressions are evaluated at pipeline upload, not at step runtime.
Conditionals in steps
Use the if
attribute in your step definition to conditionally run a step.
In the below example, the tests
step will only be run if the build message does not contain the string "skip tests".
The if
attribute can be used in any type of step, and with any of the supported expressions and parameters. However, it cannot be used at the same time as the branches
attribute.
Be careful when defining conditionals within YAML. Many symbols have special meaning in YAML and will change the type of a value. You can avoid this by quoting your conditional as a string.
Multi-line conditionals can be added with the |
character, and avoid the need for quotes:
Since if
conditions are evaluated at the time of the pipeline upload, it's not possible to use the if
attribute to conditionally run a step based on the result of another step.
To run a step based on the result of another step, upload a new pipeline based on the if
condition set up in the command step like in the example below:
Conditional notifications
To trigger Build notifications only under certain conditions, use the same if
syntax as in your Steps.
For example, the following email notification will only be triggered if the build passes:
Note that conditional expressions on the build state are only available at the pipeline level. You can't use them at the step level.
Conditionals and the broken state
Jobs become broken
when their configuration prevents them from running. This might be because their branch configuration doesn't match the build's branch, or because a conditional returned false
. This is distinct from skipped
jobs, which might happen if a newer build is started and build skipping is enabled. A rough explanation is that jobs break because of something inside the build and are skipped by something outside the build.
Variable and syntax reference
Evaluate expressions made up of boolean operators and variables.
Operator syntax
The following expressions are supported by the if
attribute.
Comparators | == != =~ !~ |
Logical operators | || && |
Array operators | includes |
Integers | 12345 |
Strings | 'feature-branch' "feature-branch" |
Literals | true false null |
Parentheses | ( ) |
Regular expressions | /^v1.0/ |
Prefixes | ! |
Comments | // This is a comment |
Formatting regular expressions
When using regular expressions in conditionals, the regular expression must be on the right hand side, and the use of the $
anchor symbol must be escaped to avoid environment variable substitution. For example, to match branches ending in "/feature"
the conditional statement would be build.branch =~ /\/feature$$/
.
Variables
The following variables are supported by the if
attribute. Note that you cannot use Build Meta-data in conditional expressions.
Note that GitHub accepts unsigned commits, including information about the commit author and passes them along to webhooks, so you should not rely on these for authentication unless you are confident that all of your commits are trusted.
build.author.email |
String |
The unverified email address of the user who authored the build's commit |
build.author.id |
String |
The unverified ID of the user who authored the build's commit |
build.author.name |
String |
The unverified name of the user who authored the build's commit |
build.author.teams |
Array |
An unverified array of the team/s which the user who authored the build's commit is a member of |
build.branch |
String |
The branch on which this build is created from |
build.commit |
String |
The commit number of the commit the current build is based on |
build.creator.email |
String |
The email address of the user who created the build. The value differs depending on how the build was created:
For conditionals to use this variable, the user set must be a verified Buildkite user. |
build.creator.id |
String |
The ID of the user who created the build. The value differs depending on how the build was created:
For conditionals to use this variable, the user set must be a verified Buildkite user. |
build.creator.name |
String |
The name of the user who created the build. The value differs depending on how the build was created:
For conditionals to use this variable, the user set must be a verified Buildkite user. |
build.creator.teams |
Array |
An array of the teams which the user who created the build is a member of. The value differs depending on how the build was created:
For conditionals to use this variable, the user set must be a verified Buildkite user. |
build.env() |
String , null
|
This function returns the value of the environment passed as the first argument if that variable is set, or null if the environment variable is not set.build.env() works with variables you've defined, and the following BUILDKITE_* variables:BUILDKITE_BRANCH BUILDKITE_TAG BUILDKITE_MESSAGE BUILDKITE_COMMIT BUILDKITE_PIPELINE_SLUG BUILDKITE_PIPELINE_NAME BUILDKITE_PIPELINE_ID BUILDKITE_ORGANIZATION_SLUG BUILDKITE_TRIGGERED_FROM_BUILD_ID BUILDKITE_TRIGGERED_FROM_BUILD_NUMBER BUILDKITE_TRIGGERED_FROM_BUILD_PIPELINE_SLUG BUILDKITE_REBUILT_FROM_BUILD_ID BUILDKITE_REBUILT_FROM_BUILD_NUMBER BUILDKITE_REPO BUILDKITE_PULL_REQUEST BUILDKITE_PULL_REQUEST_BASE_BRANCH BUILDKITE_PULL_REQUEST_REPO BUILDKITE_GITHUB_DEPLOYMENT_ID BUILDKITE_GITHUB_DEPLOYMENT_TASK BUILDKITE_GITHUB_DEPLOYMENT_ENVIRONMENT BUILDKITE_GITHUB_DEPLOYMENT_PAYLOAD |
build.id |
String |
The ID of the current build |
build.message |
String , null
|
The current build's message |
build.number |
Integer |
The number of the current build |
build.pull_request.base_branch |
String , null
|
The base branch that the pull request is targeting, otherwise null if the branch is not a pull request |
build.pull_request.id |
String , null
|
The number of the pull request, otherwise null if the branch is not a pull request |
build.pull_request.draft |
Boolean , null
|
If the pull request is a draft, otherwise null if the branch is not a pull request or the provider doesn't support draft pull requests |
build.pull_request.labels |
Array |
An array of label names attached to the pull request |
build.pull_request.repository |
String , null
|
The repository URL of the pull request, otherwise null if the branch is not a pull request |
build.pull_request.repository.fork |
Boolean , null
|
If the pull request comes from a forked repository, otherwise null if the branch is not a pull request |
build.source |
String |
The source of the event that created the build Available sources: ui , api , webhook , trigger_job , schedule
|
build.state |
String |
The state the current build is in Available states:, started , scheduled , running , passed , failed , failing , started_failing , blocked , canceling , canceled , skipped , not_run
|
build.tag |
String , null
|
The tag associated with the commit the current build is based on |
pipeline.default_branch |
String , null
|
The default branch of the pipeline the current build is from |
pipeline.id |
String |
The ID of the pipeline the current build is from |
pipeline.repository |
String , null
|
The repository of the pipeline the current build is from |
pipeline.slug |
String |
The slug of the pipeline the current build is from |
organization.id |
String |
The ID of the organization the current build is running in |
organization.slug |
String |
The slug of the organization the current build is running in |
Using build.env()
with custom environment variables
To access custom environment variables with the build.env()
function, ensure that the YAML pipeline steps editor has been enabled in the Pipeline Settings menu.
Example expressions
To run only when the branch is main
or production
:
build.branch == "main" || build.branch == "production"
To run only when the branch is not production
:
build.branch != "production"
To run only when the branch starts with features/
:
build.branch =~ /^features\//
To run only when the branch ends with /release-123
, such as feature/release-123
:
build.branch =~ /\/release-123\$/
To run only when building a tag:
build.tag != null
To run only when building a tag beginning with a v
and ends with a .0
, such as v1.0
:
// Using the tag variable
build.tag =~ /^v[0-9]+\.0\$/
// Using the env function
build.env("BUILDKITE_TAG") =~ /^v[0-9]+\.0\$/
To run only if the message doesn't contain [skip tests]
, case insensitive:
build.message !~ /\[skip tests\]/i
To run only if the build was created from a schedule:
build.source == "schedule"
To run when the value of CUSTOM_ENVIRONMENT_VARIABLE
is value
:
build.env("CUSTOM_ENVIRONMENT_VARIABLE") == "value"
To run when the unverified build creator is in the deploy
team:
build.creator.teams includes "deploy"
To run only non-draft pull requests:
!build.pull_request.draft