Workflow syntax
The Workflow section defines a list of steps to build, test and deploy. Steps are executed serially in the order in which they are defined. If a step returns a non-zero exit code, the workflow and therefore the entire workflow terminates and returns an error status.
Exemplary step definition:
steps: - name: backend image: <image> commands: - <command 1> - <command 2> - name: frontend image: <image> commands: | <command 1>Besides steps:, various other top-level commands are understood which allow controlling the pipeline execution flow.
A common use case is to disable partial cloning, to allow for a possible git push in a follow-up step (which does not work with a partial clone).
clone: - name: clone image: codeberg.org/crow-plugins/clone settings: partial: falseSee the default configuration of the clone plugin to check for possible options to change.
The name field allows to set a custom name for a pipeline.
By default, the workflow name is derived from the YAML file name (e.g., build.yaml → build).
For matrix pipelines, a NAME (case-insensitive) key can be provided for each matrix entry:
matrix: include: - NAME: name1 VAR1: value1 - NAME: name2 VAR1: value2Both name and NAME support variable substitution (e.g., ${ENVIRONMENT}).
If a matrix NAME is set, it takes priority over other options.
Otherwise, the top-level name is used.
If neither is set, the file name is used.
depends_on
Section titled “depends_on”Multiple workflows can be set up for a repository.
Those will run independent of each other by default.
To introduce a dependency among these, the depends_on keyword can be used with the workflow name (usually the name of the YAML file).
labels
Section titled “labels”Labels can be set for workflows. These are used by agents to filter their execution. An agent will pick up and run a workflow when every label assigned to it matches the agents labels.
Every workflow has the repo=your-user/your-repo-name label set.
If the platform attribute of a workflow has been set, a label like platform=your-os/your-arch is set as well.
Labels can be set in a map:
labels: location: europe # only agents with `location=europe` or `location=*` will be used weather: sun hostname: '' # this label will be ignored as it is empty
steps: - name: build image: <image> commands: - go build - go testmatrix
Section titled “matrix”Matrix builds allow separate workflows for each combination in the matrix, simplifying building and testing a single commit against multiple configurations.
For more details check the dedicated documentation on matrix builds.
privileged
Section titled “privileged”Steps can be given “privileged” capabilities. Doing so is a security risk and should only be used in private environments, and even there only as the last resort.
Privileged plugin image matching
Section titled “Privileged plugin image matching”The environment variable CROW_PLUGINS_PRIVILEGED controls which plugin images are allowed to run in privileged mode.
The way images are matched is controlled by CROW_PLUGINS_PRIVILEGED_MATCH_TYPE (default: semver).
Match types
Section titled “Match types”- semver (default):
<image>:6matches all plugin versions with major version 6 (e.g.,<image>:6.1.2).<image>:6.3matches all plugin versions with major version 6 and minor version 3 (e.g.,<image>:6.3.5).<image>:6.3.1matches only the specific version 6.3.1.
- semver-range: Uses semver constraint syntax for more flexible version matching:
<image>:>=6matches any version 6.0.0 or higher.<image>:<7.0matches any version less than 7.0.0.<image>:>=6.0.0,<7.0.0matches any version from 6.0.0 (inclusive) to 7.0.0 (exclusive).<image>:~6.3equivalent to<image>:>=6.3.0,<6.4.0(allows patch-level changes).<image>:^6.3equivalent to<image>:>=6.3.0,<7.0.0(allows minor-level changes).
- regex: Each entry in
CROW_PLUGINS_PRIVILEGEDis treated as a regular expression and matched against the full image name (including tag). - exact: Only exact string matches are allowed.
Example usage
Section titled “Example usage”export CROW_PLUGINS_PRIVILEGED="codeberg.org/crow-plugins/docker-buildx:1,plugins/gcr:7.2"export CROW_PLUGINS_PRIVILEGED_MATCH_TYPE=semver- This will allow any
crow-plugins/docker-buildximage with a major version 1 tag, and anyplugins/gcrimage with a 7.2.x tag, to run in privileged mode.
export CROW_PLUGINS_PRIVILEGED="codeberg.org/crow-plugins/docker-buildx:1\\..*"export CROW_PLUGINS_PRIVILEGED_MATCH_TYPE=regex- This will allow any
crow-plugins/docker-buildximage with a tag starting with 1.
export CROW_PLUGINS_PRIVILEGED="codeberg.org/crow-plugins/docker-buildx:1.0.0"export CROW_PLUGINS_PRIVILEGED_MATCH_TYPE=exact- This will only allow the exact image
codeberg.org/crow-plugins/docker-buildx:1.0.0to run in privileged mode.
export CROW_PLUGINS_PRIVILEGED="codeberg.org/crow-plugins/docker-buildx:>=1.0.0,<2.0.0"export CROW_PLUGINS_PRIVILEGED_MATCH_TYPE=semver-range- This will allow any
crow-plugins/docker-buildximage with a version from 1.0.0 (inclusive) to 2.0.0 (exclusive) to run in privileged mode.
runs_on
Section titled “runs_on”Workflows that should run even if dependent workflows failed.
runs_on: [success, failure]See the “Execution control” page for more details.
services
Section titled “services”Service containers can be used to asynchronously run databases or cache containers during the execution of a workflow.
For more details check the services docs.
skip_clone
Section titled “skip_clone”The implicit clone step, which can be configured through the clone keyword, can be skipped entirely.
skip_clone: truevariables
Section titled “variables”Variables are global workflow definitions which can be reused across the workflow definition.
Advanced YAML features such as anchors and aliases are supported.
For more details and examples see the advanced usage documentation.
The when: defines the events when a workflow is triggered.
If at least one of the conditions in the when block evaluates to true, the step is executed, otherwise it is skipped.
A condition is evaluated to true if all sub-conditions are true.
when: - event: pull_request - event: push branch: ${CI_REPO_DEFAULT_BRANCH}The above example would trigger the workflow
- on
pull_requestevents - on
pushevents to the default branch of the repository
For more information about the specific filter combinations, take a look at the step-specific when filters.
workspace
Section titled “workspace”The workspace defines the shared volume and working directory which is shared by all workflow steps.
The default workspace base is /crow and the path is extended with the repository URL (src/{url-without-schema}).
A full example would be /crow/src/github.com/octocat/hello-world.
The base attribute defines a shared base volume available to all steps. This ensures that source code, dependencies and other dynamic assets are persisted and shared between steps.
workspace: base: /go path: src/github.com/octocat/hello-worldThe path attribute defines the working directory of the build.
The value of path must be relative and is combined with the base path.
commands
Section titled “commands”The commands of every step are executed serially as if they would be entered into a terminal.
steps: - name: backend image: <image> commands: - go build - go testBehind the scenes, the commands are converted into a shell script, which is then executed as the container entrypoint (docker run --entrypoint=build.sh golang):
#!/bin/shset -e
go buildgo testSometimes (e.g. to avoid issues with escaping quotes and double-colons) it can be easier to specify all commands as a block instead of a list in YAML:
steps: - name: backend image: <image> commands: | go build go testdepends_on
Section titled “depends_on”Normally, workflow steps are executed serially in the order in which they are defined.
As soon as depends_on is set for one or more steps, a directed acyclic graph (DAG) will be created and all steps of the workflow will be executed in parallel.
Only the steps that have a dependency set to another step via depends_on are executed serially:
steps: - name: build # will be executed immediately image: <image> commands: - go build
- name: deploy image: <image> settings: repo: foo/bar depends_on: [build, test] # deploy will be executed after 'build' and 'test' finished
- name: test # will be executed immediately as no dependencies are set image: <image> commands: - go testdetach
Section titled “detach”The detach options can be used to run steps in the background until a workflow has finished.
It is similar to services: and hence explained in more detail in the “services” documentation.
directory
Section titled “directory”The directory options allows setting a subdirectory inside the container in which the commands will be executed.
entrypoint
Section titled “entrypoint”The container entrypoint.
The default entrypoint is
"/bin/sh", "-c", "echo $CI_SCRIPT | base64 -d | /bin/sh -e"An alternative to the above which allows defining custom parameters is to use a custom shell via the env var CI_SCRIPT (Base64-encoded).
environment
Section titled “environment”Pass arbitrary environment variables to individual steps.
steps: - name: backend image: <image> environment: XY: true commands: | go build go testFor more details, check the dedicated “environment variables” documentation.
failure
Section titled “failure”Allow steps to fail without causing the whole workflow and the subsequent pipeline to fail (e.g., a step executing a linting check).
If an error is encountered while executing the step, the step will be reported as “failed” but the next steps of the workflow will continue to execute.
steps: - name: backend image: <image> commands: - go build - go test failure: ignoreThe container image to use for the step.
steps: - name: build image: <image>
services: - name: database image: mysqlvolumes
Section titled “volumes”Additional volumes can be mounted to individual steps.
For the docker backend, this option can be used to mount files or folders from the host machine into the respective containers.
For the kubernetes backend, an existing persistent volume claim (PVC) is used.
More details can be found in the volumes documentation.
Woodpecker supports defining a list of conditions for a step by using a when block.
If at least one of the conditions in the when block evaluate to true, the step is executed, otherwise it is skipped.
A condition is evaluated to true if all sub-conditions are true.
branch
Section titled “branch”steps: - name: backend image: <image> commands: - go build - go test when: - branch: mainTo only run for pushes to main, the following would need to be set:
steps: - name: backend image: <image> commands: - go build - go test when: - branch: main event: pushA condition can also be a list:
steps: - name: backend image: <image> commands: - go build - go test when: - branch: [main, dev] event: pushRegex is also supported:
steps: - name: backend image: <image> commands: - go build - go test when: - branch: prefix/* event: pushThe matching is done via bmatcuk/doublestar/. Please check its documentation for complex condition sets.
An example which includes both explicit exclude and include parts could be written as:
when: - branch: include: [main, release/*] exclude: [release/1.0.0, release/1.1.*]when: - event: cron cron: <cron name>evaluate
Section titled “evaluate”Execute a step only if the provided evaluate expression equals to true.
Both built-in CI_ and custom variables can be used inside the expression.
Examples:
-
Run on pushes to the default branch for the repository
owner/repo:when:- evaluate: 'CI_PIPELINE_EVENT == "push" && CI_REPO == "owner/repo" && CI_COMMIT_BRANCH == CI_REPO_DEFAULT_BRANCH' -
Run on commits created by user
user1:when:- evaluate: 'CI_COMMIT_AUTHOR == "user1"' -
Skip all commits containing “please ignore me” in the commit message:
when:- evaluate: 'not (CI_COMMIT_MESSAGE contains "please ignore me")' -
Run on pull requests with the label
deploy:when:- evaluate: 'CI_COMMIT_PULL_REQUEST_LABELS contains "deploy"' -
Skip step only if
SKIP=true, run otherwise or if undefined:when:- evaluate: 'SKIP != "true"'
A list of all available events:
push: triggered when a commit is pushed to a branch.pull_request: triggered when a pull request is opened or a new commit is pushed to it.pull_request_closed: triggered when a pull request is closed without being merged.pull_request_merged: triggered when a pull request is merged.pull_request_edited: triggered when a pull request is edited (the PR title or body).tag: triggered when a tag is pushed.release: triggered when a release, pre-release or draft is created. (Further filters can be applied using evaluate in combination with environment variables.)deployment: triggered when a “deployment” is created in the repository. (There are two ways to trigger this event: from the Crow UI directly or from a forge which supports “deployment” events (e.g., GitHub))cron: triggered when a cron job is executed. Requires a cron job to be configured in the dashboard.manual: triggered when a user manually triggers a pipeline in UI or via CLI.
Event triggers can be combined.
If this is used, all conditions need to evaluate to true.
Example: Execute a step if the pipeline event is a push to a specified branch:
when: - event: push branch: mainExecute a step for multiple events:
when: - event: [push, tag, deployment, manual] # alternative syntax # - event: # - push # - tag # - deployment # - manualmatrix
Section titled “matrix”Execute a step for a single matrix permutation:
when: - matrix: GO_VERSION: 1.5 REDIS_VERSION: 2.8Only execute a step when specific files were changed:
when: - path: 'src/*'Glob patterns are used to match the changed files.
For pipelines without file changes (empty commits or on events without file changes like tag), on_empty can be used to set whether the condition should be true (default) or false.
when: - path: include: ['.crow/*.yaml', '*.ini'] exclude: ['*.md', 'docs/**'] ignore_message: '[ALL]' on_empty: trueplatform
Section titled “platform”Execute a step for a specific platform:
when: - platform: linux/amd64Execute a step for a specific platform using wildcards:
when: - platform: ['linux/*', 'windows/amd64']The ref filter is compared against the git reference of the workflow.
Example: filter tags that start with v:
when: - event: tag ref: refs/tags/v*Filter by repository:
when: - repo: test/teststatus
Section titled “status”To execute steps on failure of previous pipelines, for example to send notifications for such, the status filter can be used:
when: - status: [success, failure]