Skip to main content
Version: Next

Pipeline syntax

The pipeline section defines a list of steps to build, test and deploy your code. Pipeline steps are executed serially, in the order in which they are defined. If a step returns a non-zero exit code, the pipeline immediately aborts and returns a failure status.

Example pipeline:

pipeline:
backend:
image: golang
commands:
- go build
- go test
frontend:
image: node
commands:
- npm install
- npm run test
- npm run build

In the above example we define two pipeline steps, frontend and backend. The names of these steps are completely arbitrary.

Skip Commitsโ€‹

Woodpecker gives the ability to skip individual commits by adding [CI SKIP] to the commit message. Note this is case-insensitive.

git commit -m "updated README [CI SKIP]"

Stepsโ€‹

Every step of your pipeline executes arbitrary commands inside a specified container. The defined commands are executed serially. The associated commit of a current pipeline run is checked out with git to a workspace which is mounted to every step of the pipeline as the working directory.

 pipeline:
backend:
image: golang
commands:
+ - go build
+ - go test

File changes are incrementalโ€‹

  • Woodpecker clones the source code in the beginning pipeline
  • Changes to files are persisted through steps as the same volume is mounted to all steps
# .woodpecker.yml
pipeline:
build:
image: debian
commands:
- echo "test content" > myfile
a-test-step:
image: debian
commands:
- cat myfile

imageโ€‹

Woodpecker pulls the defined image and uses it as environment to execute the pipeline step commands, for plugins and for service containers.

When using the local backend, the image entry is used to specify the shell, such as Bash or Fish, that is used to run the commands.

 pipeline:
build:
+ image: golang:1.6
commands:
- go build
- go test

publish:
+ image: plugins/docker
repo: foo/bar

services:
database:
+ image: mysql

Woodpecker supports any valid Docker image from any Docker registry:

image: golang
image: golang:1.7
image: library/golang:1.7
image: index.docker.io/library/golang
image: index.docker.io/library/golang:1.7

Woodpecker does not automatically upgrade container images. Example configuration to always pull the latest image when updates are available:

 pipeline:
build:
image: golang:latest
+ pull: true
Images from private registriesโ€‹

You must provide registry credentials on the UI in order to pull private pipeline images defined in your YAML configuration file.

These credentials are never exposed to your pipeline, which means they cannot be used to push, and are safe to use with pull requests, for example. Pushing to a registry still require setting credentials for the appropriate plugin.

Example configuration using a private image:

 pipeline:
build:
+ image: gcr.io/custom/golang
commands:
- go build
- go test

Woodpecker matches the registry hostname to each image in your yaml. If the hostnames match, the registry credentials are used to authenticate to your registry and pull the image. Note that registry credentials are used by the Woodpecker agent and are never exposed to your build containers.

Example registry hostnames:

  • Image gcr.io/foo/bar has hostname gcr.io
  • Image foo/bar has hostname docker.io
  • Image qux.com:8000/foo/bar has hostname qux.com:8000

Example registry hostname matching logic:

  • Hostname gcr.io matches image gcr.io/foo/bar
  • Hostname docker.io matches golang
  • Hostname docker.io matches library/golang
  • Hostname docker.io matches bradyrydzewski/golang
  • Hostname docker.io matches bradyrydzewski/golang:latest
Global registry supportโ€‹

To make a private registry globally available check the server configuration docs.

GCR registry supportโ€‹

For specific details on configuring access to Google Container Registry, please view the docs here.

commandsโ€‹

Commands of every pipeline step are executed serially as if you would enter them into your local shell.

 pipeline:
backend:
image: golang
commands:
+ - go build
+ - go test

There is no magic here. The above commands are converted to a simple shell script. The commands in the above example are roughly converted to the below script:

#!/bin/sh
set -e

go build
go test

The above shell script is then executed as the container entrypoint. The below docker command is an (incomplete) example of how the script is executed:

docker run --entrypoint=build.sh golang

Please note that only build steps can define commands. You cannot use commands with plugins or services.

environmentโ€‹

Woodpecker provides the ability to pass environment variables to individual pipeline steps.

For more details check the environment docs.

secretsโ€‹

Woodpecker provides the ability to store named parameters external to the YAML configuration file, in a central secret store. These secrets can be passed to individual steps of the pipeline at runtime.

For more details check the secrets docs.

when - Conditional Executionโ€‹

Woodpecker supports defining a list of conditions for a pipeline 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 can be a check like:

 pipeline:
slack:
image: plugins/slack
settings:
channel: dev
+ when:
+ - event: pull_request
+ repo: test/test
+ - event: push
+ branch: main

repoโ€‹

Example conditional execution by repository:

 pipeline:
slack:
image: plugins/slack
settings:
channel: dev
+ when:
+ - repo: test/test

branchโ€‹

note

Branch conditions are not applied to tags.

Example conditional execution by branch:

pipeline:
slack:
image: plugins/slack
settings:
channel: dev
+ when:
+ - branch: master

The step now triggers on master, but also if the target branch of a pull request is master. Add an event condition to limit it further to pushes on master only.

Execute a step if the branch is master or develop:

when:
- branch: [master, develop]

Execute a step if the branch starts with prefix/*:

when:
- branch: prefix/*

The branch matching is done using doublestar, note that a pattern starting with * should be put between quotes and a literal / needs to be escaped. A few examples:

  • *\\/* to match patterns with exactly 1 /
  • *\\/** to match patters with at least 1 /
  • * to match patterns without /
  • ** to match everything

Execute a step using custom include and exclude logic:

when:
- branch:
include: [ master, release/* ]
exclude: [ release/1.0.0, release/1.1.* ]

eventโ€‹

info

By default steps are filtered by following event types:

push, pull_request, tag, deployment, manual.

Available events: push, pull_request, tag, deployment, cron, manual

Execute a step if the build event is a tag:

when:
- event: tag

Execute a step if the pipeline event is a push to a specified branch:

when:
- event: push
+ branch: main

Execute a step for multiple events:

when:
- event: [push, tag, deployment]

cronโ€‹

This filter only applies to cron events and filters based on the name of a cron job.

Make sure to have a event: cron condition in the when-filters as well.

when:
- event: cron
cron: sync_* # name of your cron job

Read more about cron

tagโ€‹

This filter only applies to tag events. Use glob expression to execute a step if the tag name starts with v:

when:
- event: tag
tag: v*

statusโ€‹

There are use cases for executing pipeline steps on failure, such as sending notifications for failed pipelines. Use the status constraint to execute steps even when the pipeline fails:

pipeline:
slack:
image: plugins/slack
settings:
channel: dev
+ when:
+ - status: [ success, failure ]

platformโ€‹

note

This condition should be used in conjunction with a matrix pipeline as a regular pipeline will only executed by a single agent which only has one arch.

Execute a step for a specific platform:

when:
- platform: linux/amd64

Execute a step for a specific platform using wildcards:

when:
- platform: [ linux/*, windows/amd64 ]

environmentโ€‹

Execute a step for deployment events matching the target deployment environment:

when:
- environment: production
- event: deployment

matrixโ€‹

Execute a step for a single matrix permutation:

when:
- matrix:
GO_VERSION: 1.5
REDIS_VERSION: 2.8

instanceโ€‹

Execute a step only on a certain Woodpecker instance matching the specified hostname:

when:
- instance: stage.woodpecker.company.com

pathโ€‹

info

Path conditions are applied only to push and pull_request events. It is currently only available for GitHub, GitLab. Gitea only supports push at the moment (go-gitea/gitea#18228).

Execute a step only on a pipeline with certain files being changed:

when:
- path: "src/*"

You can use glob patterns to match the changed files and specify if the step should run if a file matching that pattern has been changed include or if some files have not been changed exclude.

when:
- path:
include: [ '.woodpecker/*.yml', '*.ini' ]
exclude: [ '*.md', 'docs/**' ]
ignore_message: "[ALL]"

Hint: Passing a defined ignore-message like [ALL] inside the commit message will ignore all path conditions.

group - Parallel executionโ€‹

Woodpecker supports parallel step execution for same-machine fan-in and fan-out. Parallel steps are configured using the group attribute. This instructs the pipeline runner to execute the named group in parallel.

Example parallel configuration:

 pipeline:
backend:
+ group: build
image: golang
commands:
- go build
- go test
frontend:
+ group: build
image: node
commands:
- npm install
- npm run test
- npm run build
publish:
image: plugins/docker
repo: octocat/hello-world

In the above example, the frontend and backend steps are executed in parallel. The pipeline runner will not execute the publish step until the group completes.

volumesโ€‹

Woodpecker gives the ability to define Docker volumes in the YAML. You can use this parameter to mount files or folders on the host machine into your containers.

For more details check the volumes docs.

detachโ€‹

Woodpecker gives the ability to detach steps to run them in background until the pipeline finishes.

For more details check the service docs.

servicesโ€‹

Woodpecker can provide service containers. They can for example be used to run databases or cache containers during the execution of pipeline.

For more details check the services docs.

workspaceโ€‹

The workspace defines the shared volume and working directory shared by all pipeline steps. The default workspace matches the below pattern, based on your repository url.

/woodpecker/src/github.com/octocat/hello-world

The workspace can be customized using the workspace block in the YAML file:

+workspace:
+ base: /go
+ path: src/github.com/octocat/hello-world

pipeline:
build:
image: golang:latest
commands:
- go get
- go test

The base attribute defines a shared base volume available to all pipeline steps. This ensures your source code, dependencies and compiled binaries are persisted and shared between steps.

 workspace:
+ base: /go
path: src/github.com/octocat/hello-world

pipeline:
deps:
image: golang:latest
commands:
- go get
- go test
build:
image: node:latest
commands:
- go build

This would be equivalent to the following docker commands:

docker volume create my-named-volume

docker run --volume=my-named-volume:/go golang:latest
docker run --volume=my-named-volume:/go node:latest

The path attribute defines the working directory of your build. This is where your code is cloned and will be the default working directory of every step in your build process. The path must be relative and is combined with your base path.

 workspace:
base: /go
+ path: src/github.com/octocat/hello-world
git clone https://github.com/octocat/hello-world \
/go/src/github.com/octocat/hello-world

matrixโ€‹

Woodpecker has integrated support for matrix builds. Woodpecker executes a separate build task for each combination in the matrix, allowing you to build and test a single commit against multiple configurations.

For more details check the matrix build docs.

platformโ€‹

To configure your pipeline to only be executed on an agent with a specific platform, you can use the platform key. Have a look at the official go docs for the available platforms. The syntax of the platform is GOOS/GOARCH like linux/arm64 or linux/amd64.

Example:

Assuming we have two agents, one arm and one amd64. Previously this pipeline would have executed on either agent, as Woodpecker is not fussy about where it runs the pipelines. By setting the following option it will only be executed on an agent with the platform linux/arm64.

+platform: linux/arm64

pipeline:
build:
image: golang
commands:
- go build
- go test

labelsโ€‹

You can set labels for your pipeline to select an agent to execute the pipeline on. An agent will pick up and run a pipeline when every label assigned to a pipeline matches the agents labels.

To set additional agent labels check the agent configuration options. Agents will have at least three default labels: platform=agent-os/agent-arch, hostname=my-agent and repo=*. Agents can use a * as a wildcard for a label. For example repo=* will match every repo.

Pipeline labels with an empty value will be ignored. By default each pipeline has at least the repo=your-user/your-repo-name label. If you have set the platform attribute for your pipeline it will have a label like platform=your-os/your-arch as well.

You can add additional labels as a key value 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

pipeline:
build:
image: golang
commands:
- go build
- go test

variablesโ€‹

Woodpecker supports YAML anchors & aliases in the pipeline configuration. These can be used as variables to not repeat yourself.

For more details and examples check the Advanced YAML syntax docs

cloneโ€‹

Woodpecker automatically configures a default clone step if not explicitly defined. When using the local backend, the plugin-git binary must be on your $PATH for the default clone step to work. If not, you can still write a manual clone step.

You can manually configure the clone step in your pipeline for customization:

+clone:
+ git:
+ image: woodpeckerci/plugin-git

pipeline:
build:
image: golang
commands:
- go build
- go test

Example configuration to override depth:

 clone:
git:
image: woodpeckerci/plugin-git
+ settings:
+ depth: 50

Example configuration to use a custom clone plugin:

clone:
git:
+ image: octocat/custom-git-plugin

Example configuration to clone Mercurial repository:

 clone:
hg:
+ image: plugins/hg
+ settings:
+ path: bitbucket.org/foo/bar

Git Submodulesโ€‹

To use the credentials that cloned the repository to clone it's submodules, update .gitmodules to use https instead of git:

 [submodule "my-module"]
path = my-module
-url = git@github.com:octocat/my-module.git
+url = https://github.com/octocat/my-module.git

To use the ssh git url in .gitmodules for users cloning with ssh, and also use the https url in Woodpecker, add submodule_override:

 clone:
git:
image: woodpeckerci/plugin-git
settings:
recursive: true
+ submodule_override:
+ my-module: https://github.com/octocat/my-module.git

pipeline:
...

when - Global pipeline conditionsโ€‹

Woodpecker gives the ability to skip whole pipelines (not just steps #when---conditional-execution-1) based on certain conditions by a when block. If all conditions in the when block evaluate to true the pipeline is executed, otherwise it is skipped, but treated as successful and other pipelines depending on it will still continue.

repoโ€‹

Example conditional execution by repository:

 pipeline:
slack:
image: plugins/slack
settings:
channel: dev
+ when:
+ repo: test/test

branchโ€‹

note

Branch conditions are not applied to tags.

Example conditional execution by branch:

pipeline:
slack:
image: plugins/slack
settings:
channel: dev
+ when:
+ branch: master

The step now triggers on master, but also if the target branch of a pull request is master. Add an event condition to limit it further to pushes on master only.

Execute a step if the branch is master or develop:

when:
branch: [master, develop]

Execute a step if the branch starts with prefix/*:

when:
branch: prefix/*

Execute a step using custom include and exclude logic:

when:
branch:
include: [ master, release/* ]
exclude: [ release/1.0.0, release/1.1.* ]

eventโ€‹

Execute a step if the build event is a tag:

when:
event: tag

Execute a step if the pipeline event is a push to a specified branch:

when:
event: push
+ branch: main

Execute a step for all non-pull request events:

when:
event: [push, tag, deployment]

Execute a step for all build events:

when:
event: [push, pull_request, tag, deployment]

tagโ€‹

This filter only applies to tag events. Use glob expression to execute a step if the tag name starts with v:

when:
event: tag
tag: v*

environmentโ€‹

Execute a step for deployment events matching the target deployment environment:

when:
environment: production
event: deployment

instanceโ€‹

Execute a step only on a certain Woodpecker instance matching the specified hostname:

when:
instance: stage.woodpecker.company.com

pathโ€‹

info

Path conditions are applied only to push and pull_request events. It is currently only available for GitHub, GitLab. Gitea only supports push at the moment (go-gitea/gitea#18228).

Execute a step only on a pipeline with certain files being changed:

when:
path: "src/*"

You can use glob patterns to match the changed files and specify if the step should run if a file matching that pattern has been changed include or if some files have not been changed exclude.

when:
path:
include: [ '.woodpecker/*.yml', '*.ini' ]
exclude: [ '*.md', 'docs/**' ]
ignore_message: "[ALL]"

Hint: Passing a defined ignore-message like [ALL] inside the commit message will ignore all path conditions.

depends_onโ€‹

Woodpecker supports to define multiple pipelines for a repository. Those pipelines will run independent from each other. To depend them on each other you can use the depends_on keyword.

Privileged modeโ€‹

Woodpecker gives the ability to configure privileged mode in the YAML. You can use this parameter to launch containers with escalated capabilities.

Privileged mode is only available to trusted repositories and for security reasons should only be used in private environments. See project settings to enable trusted mode.

 pipeline:
build:
image: docker
environment:
- DOCKER_HOST=tcp://docker:2375
commands:
- docker --tls=false ps

services:
docker:
image: docker:dind
command: [ "--storage-driver=vfs", "--tls=false" ]
+ privileged: true