Group step
A group step can contain various sub-steps, and display them in a single logical group on the Build page.
For example, you can group all of your linting steps or all of your UI test steps to keep the Build page less messy. Sub-groups and nested groups are not supported.
The group step also helps manage dependencies between a collection of steps, for example, "step X" depends_on
everything in "group Y".
A group step can be defined in your pipeline settings or your pipeline.yml file.
Here is an example of using the group step:
steps:
- group: ":lock_with_ink_pen: Security Audits"
key: "audits"
steps:
- label: ":brakeman: Brakeman"
command: ".buildkite/steps/brakeman"
- label: ":bundleaudit: Bundle Audit"
command: ".buildkite/steps/bundleaudit"
- label: ":yarn: Yarn Audit"
command: ".buildkite/steps/yarn"
- label: ":yarn: Outdated Check"
command: ".buildkite/steps/outdated"
This is how it's displayed in the UI:

Only the first 50 jobs within a build header can ever be displayed in the UI, so you might not see all of your groups at all times. However, the jobs are fine and will still show up on the build page.
Group step attributes
Required attributes:
group |
Name of the group in the UI. In YAML, if you don't want a label, pass a `~`. Can also be provided in the `label` attribute if `null` is provided to the `group` attribute. Type: string or null
|
steps |
A list of steps in the group; at least 1 step is required. Allowed step types: wait , trigger , command /commands , block , input .Type: array
|
Optional attributes:
allow_dependency_failure |
Whether to continue to run this step if any of the steps named in the depends_on attribute fail.Default: false
|
depends_on |
A list of step or group keys that this step depends on. This step or group will only run after the named steps have completed. See managing step dependencies for more information. Example: "test-suite"
|
if |
A boolean expression that omits the step when false. See Using conditionals for supported expressions. Example: build.message != "skip me"
|
key |
A unique string to identify the step, block, or group. Keys can not have the same pattern as a UUID ( xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx ).Example: "test-suite" Alias: identifier
|
label |
The label that will be displayed in the pipeline visualisation in Buildkite (name of the group in the UI). Supports emoji. Example: ":hammer: Tests" will be rendered as "🔨 Tests" |
notify |
Allows you to trigger build notifications to different services. You can also choose to conditionally send notifications based on pipeline events. Example: "github_commit_status:" |
skip |
Whether to skip this step or not. Passing a string provides a reason for skipping this command. Passing an empty string is equivalent to false .
Note: Skipped steps will be hidden in the pipeline view by default, but can be made visible by toggling the 'Skipped jobs' icon.Example: true Example: false Example: "My reason"
|
Agent-applied attributes
These attributes are only applied by the Buildkite Agent when uploading a pipeline (buildkite-agent pipeline upload
), since they require direct access to your code or repository to process correctly.
if_changed |
A glob pattern that omits the step from a build if it does not match any files changed in the build. Example: "{**.go,go.mod,go.sum,fixtures/**}" From version 3.109.0 of the Buildkite Agent, if_changed also supports lists of glob patterns and include and exclude attributes.Minimum Buildkite Agent versions: 3.99 (with --apply-if-changed flag), 3.103.0 (enabled by default), 3.109.0 (expanded syntax)
|
Agent-applied attributes are not accepted in pipelines set using the Buildkite interface.
Example pipeline, demonstrating various forms of if_changed
:
steps:
# if_changed can specify a single glob pattern.
# Note that YAML requires some strings to be quoted.
- label: "Only run if a .go file anywhere in the repo is changed"
if_changed: "**.go"
# Braces {,} let you combine patterns and subpatterns.
# Note that this syntax is whitespace-sensitive: a space within a
# pattern is treated as part of the file path to be matched.
- label: "Only run if go.mod or go.sum are changed"
if_changed: go.{mod,sum}
# Wrong: go.{mod, sum}
# Combining the two previous examples:
- label: "Run if any Go-related file is changed"
if_changed: "{**.go,go.{mod,sum}}"
# A less Go-centric example:
- label: "Run for any changes within app/ or spec/"
if_changed: "{app/**,spec/**}"
# From version 3.109 of the Buildkite Agent, lists of patterns
# are supported. If any changed file matches any of the patterns,
# the step is run. This can be a more ergonomic alternative to
# using braces.
- label: "Run if any Go-related file is changed"
if_changed:
- "**.go"
- go.{mod,sum}
- label: "Run for any changes in app/ or spec/"
if_changed:
- app/**
- spec/**
# From version 3.109 of the Buildkite Agent, `include` and
# `exclude` are supported attributes. As for `if_changed`, these
# attributes may contain single patterns or lists of patterns.
# `exclude` eliminates changed files from causing a step to run.
# If the `exclude` attribute is present, then the `include` attribute,
# along with its pattern or list of patterns, is required too.
- label: "Run for changes in spec/, but not in spec/integration/"
if_changed:
include: spec/**
exclude: spec/integration/**
- label: "Run for api and internal, but not api/docs or internal .py files"
if_changed:
include:
- api/**
- internal/**
exclude:
- api/docs/**
- internal/**.py
Parallel groups
If you put two or more group steps in a YAML config file consecutively, they will run in parallel. For example:
# 1.sh and 3.sh will start at the same time.
# 2.sh will start when 1.sh finishes, and 4.sh will start
# when 3.sh finishes.
steps:
- group: "first"
steps:
- command: "1.sh"
- wait
- command: "2.sh"
- group: "second"
steps:
- command: "3.sh"
- wait
- command: "4.sh"
Running jobs in parallel has some limitations:
- Parallel groups will be displayed ungrouped if the build's jobs are truncated because Buildkite doesn't currently store or calculate any information about the number of jobs in a non-parallel group.
If a parallel step exists within a group, parallel jobs are treated as regular jobs within a step group - so you can't have parallel groups within step groups. So, for example, a
group
that contains twosteps
each withparallel: 4
will display eight jobs in it, with no visual indication that those eight jobs are two parallel steps.If a parallel job group is within a named group, the groups are handled as though the parallel group isn't there.
It's impossible to have a parallel job with only some of the jobs within a group, as they're all created on the same YAML step entry.
Using wait steps in job groups
You can have wait steps in a group. Such steps operate independently of other groups. For example, both groups will operate independently here, meaning d.sh
won't wait on a.sh
to finish. Note also that wait steps are counted in the group step total, so both Group01
and Group02
contain 3 steps.
steps:
- group: "Group01"
depends_on: "tests"
steps:
- command: "a.sh"
- wait
- command: "b.sh"
- group: "Group02"
depends_on: "tests"
id: "toast"
steps:
- command: "c.sh"
- wait
- command: "d.sh"
- command: "yay.sh"
depends_on: "toast"
Group merging
If you upload a pipeline that has a group
or label
that matches the group of the step that uploaded it, those groups will be merged together in the Buildkite UI.
This merging behavior only applies if the group step with the matching group
or label
is the first step within the uploaded pipeline.
Note that inside a single pipeline, groups with the same group
or label
will not be merged in the Buildkite UI.
You can't define the same key twice
Trying to create different groups or steps with the same key
attribute will result in an error.
For example, you have a YAML file:
steps:
- group: "Setup"
steps:
- commands:
- "buildkite-agent pipeline upload"
- echo "start"
And this YAML file uploads a pipeline that has a group with the same name:
steps:
- group: "Setup"
steps:
- command: "docker build"
These groups will be merged into one in the UI, and the docker build
step will be added to the existing group.
Similarly, if you have a YAML file:
steps:
- group: ~
label: "Setup"
steps:
- commands:
- "buildkite-agent pipeline upload"
- echo "start"
And this YAML file uploads a pipeline that has a group with the same label:
steps:
- group: ~
label: "Setup"
steps:
- command: echo "proceed"
These groups will be merged into one in the UI, and the echo "proceed"
step will be added to the existing group.
Example
Group steps
An example of how to group steps in a pipeline
github.com/buildkite/group-step-example