1.11.3 task
step
Executes a task. Expand each section below for more details and examples.
When a task completes, the artifacts specified by
will be registered in the build's artifact namespace. This allows subsequent task
steps and put
steps to access the result of a task.
The identifier value is just a name - short and sweet. The value is shown in the web UI but otherwise has no affect on anything. This may change in the future; RFC #32 proposes that the name be used to reference a file within the project.
You can think of tasks like functions. They have predefined inputs and outputs and can be written in idempotent ways.
The following pipeline contains a function that increments a number. You can think of the task add-one
like this pseudo-function:
func AddOne(num int) int {
return num + 1
}
jobs:
- name: idempotent-task
plan:
- get: counter
- task: add-one
config:
platform: linux
image_resource:
type: mock
source: {mirror_self: true}
inputs:
- name: counter
outputs:
- name: counter
run:
path: sh
args:
- -c
- |
COUNTER=$(cat counter/version)
NEXT=$(($COUNTER + 1))
echo "new version: $NEXT"
echo $NEXT > counter/next
- put: counter
params:
file: counter/next
resources:
- name: counter
type: mock
source:
initial_version: "1"
The task config to execute.
jobs:
- name: job
public: true
plan:
- task: simple-task
config: # contains all field in a task config
platform: linux
image_resource:
type: registry-image
source: { repository: busybox }
run:
path: echo
args: ["Hello world!"]
A dynamic alternative to task
step config
.
file
points at a .yml
file containing the task config, which allows this to be tracked with your resources.
The first segment in the path should refer to another source from the plan, and the rest of the path is relative to that source.
The content of the config file may contain template ((vars))
, which will be filled in using task
step vars
or a configured credential manager.
Uses this config file.
jobs:
- name: task-config-in-file
plan:
- get: ci
- task: config-from-file
file: ci/tasks/hello-world.yml
resources:
- name: ci
type: git
source:
uri: https://github.com/concourse/examples.git
Specifies an artifact source containing an image to use for the task. This overrides any
configuration present in the task configuration.
This is very useful when part of your pipeline involves building an image, possibly with dependencies pre-baked. You can then propagate that image through the rest of your pipeline, guaranteeing that the correct version (and thus a consistent set of dependencies) is used throughout your pipeline.
This can be used to explicitly keep track of dependent images. You could also modify it to build and push the image in one job and use it in later jobs. See Building and Pushing an Image.
resources:
- name: golang
type: registry-image
source:
repository: golang # could also be the full URL "docker.io/golang"
tag: "1.17"
jobs:
- name: fetch-and-run-image
plan:
- get: golang
- task: use-fetched-image-in-task
image: golang # reference the image from the get step
config:
platform: linux
run:
path: go
args: ["version"]
Default false
. If set to true
, the task will run with escalated capabilities available on the task's platform.
Setting privileged: true
is a gaping security hole; use wisely and only if necessary. This is not part of the task configuration in order to prevent privilege escalation via pull requests changing the task file.
For the linux
platform, this determines whether or not the container will run in a separate user namespace. When set to true
, the container's root
user is actual root
, i.e. not in a user namespace. This is not recommended, and should never be used with code you do not trust - e.g. pull requests.
For macOS and Windows this field has no effect since workloads on those machines are not containerized.
A map of template variables to pass to an external task. Not to be confused with task
step params
, which provides environment variables to the task.
This is to be used with external tasks defined in task
step file
.
A var may be statically passed like so:
jobs:
- name: task-vars
plan:
- get: ci
- task: override-task-vars
file: ci/tasks/print-var.yml
vars: # statically defined vars
my-var: "Cookies are the best"
second-var: "chips are a close second"
resources:
- name: ci
type: git
source:
uri: https://github.com/concourse/examples.git
When run with the following task config:
platform: linux
image_resource:
type: mock
source: { mirror_self: true }
params:
MY_VAR: ((my-var))
run:
path: sh
args:
- -c
- |
echo ${MY_VAR} and ((second-var))
The "((my-var))"
will be resolved to "Cookies are the best"
and ((second-var))
will be resolved to "chips are a close second"
.
This can also be used in combination with Vars from a credential manager (i.e. Vault) as a way to re-map variable names to match what the task is expecting:
jobs:
- name: task-vars
plan:
- get: ci
- task: override-task-vars
file: ci/tasks/print-var.yml
vars: # re-mapped vars
my-var: ((var-from-vault))
second-var: ((apple.type))
resources:
- name: ci
type: git
source:
uri: https://github.com/concourse/examples.git
CPU and memory limits to enforce on the task container.
Note that these values, when specified, will override any limits set by passing the --default-task-cpu-limit
or --default-task-memory-limit
flags to the concourse web
command.
These values will also override any configuration set on a task's config container_limits
.
The maximum amount of CPU available to the task container, measured in shares. 0 means unlimited.
CPU shares are relative to the CPU shares of other containers on a worker. For example, if you have two containers both with a CPU limit of 2 shares then each container will get 50% of the CPU's time.
Container A: 2 shares - 50% CPU
Container B: 2 shares - 50% CPU
Total CPU shares declared: 4
If you introduce another container then the number of CPU time per container changes. CPU shares are relative to each other.
Container A: 2 shares - 25% CPU
Container B: 2 shares - 25% CPU
Container C: 4 shares - 50% CPU
Total CPU shares declared: 8
The maximum amount of memory available to the task container, measured in bytes. 0 means unlimited.
This task will only be given 10MB of memory and 2 CPU shares.
jobs:
- name: limited-resources
plan:
- task: constrained-task
container_limits:
cpu: 2 # CPU shares are relative
memory: 10000000 # 10MB
config:
platform: linux
image_resource:
type: registry-image
source: { repository: busybox }
run:
path: echo
args: ["Hello world!"]
A map of task environment variable parameters to set, overriding those configured in the task's config
or file
.
The difference between params
and vars
is that vars
allows you to interpolate any template variable in an external task file, while params
can be used to overwrite task parameters specifically. Also, params
can have default values declared in the task.
Let's say we have a task config like so:
platform: linux
image_resource:
type: mock
source: { mirror_self: true }
params:
ECHO_ME: "default text to echo from task config file"
ALSO_ME:
run:
path: sh
args:
- -c
- |
echo ${ECHO_ME} and ${ALSO_ME}
This indicates that there are two params which can be set: ECHO_ME
, which has a default, and ALSO_ME
which has no default set.
A pipeline could run the task with values passed in like so:
jobs:
- name: task-params
plan:
- get: ci
- task: constrained-task
file: ci/tasks/print-param.yml
params:
ECHO_ME: "Eat your fruits"
ALSO_ME: "veggies"
resources:
- name: ci
type: git
source:
uri: https://github.com/concourse/examples.git
jobs:
- name: task-params
plan:
- get: ci
- task: constrained-task
file: ci/tasks/print-param.yml
params:
ECHO_ME: ((some-var))
ALSO_ME: ((another-var))
resources:
- name: ci
type: git
source:
uri: https://github.com/concourse/examples.git
A map from task input names to concrete names in the build plan. This allows a task with generic input names to be used multiple times in the same plan, mapping its inputs to specific resources within the plan.
The following example demonstrates a task with generic main
and dev
inputs being mapped to more specific artifact names, repo
and repo-dev
:
jobs:
- name: task-input-mapping
plan:
- in_parallel:
- get: repo
- get: repo-dev
- get: ci
- task: list-inputs
input_mapping:
main: repo
dev: repo-dev
file: ci/tasks/generic-inputs.yml
resources:
- name: repo
type: mock
- name: repo-dev
type: mock
- name: ci
type: git
source:
uri: https://github.com/concourse/examples.git
A map from task output names to concrete names to register in the build plan. This allows a task with generic output names to be used multiple times in the same plan.
This is often used together with task
step input_mapping
:
Given this task config:
platform: linux
image_resource:
type: mock
source: {mirror_self: true}
inputs:
- name: main
- name: dev
outputs:
- name: main
- name: dev
run:
path: sh
args:
- -c
- |
ls -lah
echo "creating versions"
echo "hello-world" > main/version
echo "hey there dev" > dev/version
This pipeline will map the inputs and outputs of the task to match the name of the resources in the pipeline.
jobs:
- name: task-output-mapping
plan:
- in_parallel:
- get: repo
- get: repo-dev
- get: ci
- task: create-outputs
input_mapping:
main: repo
dev: repo-dev
output_mapping:
main: repo
dev: repo-dev
file: ci/tasks/generic-outputs.yml
- in_parallel:
- put: repo
params:
file: repo/version
- put: repo-dev
params:
file: repo-dev/version
resources:
- name: repo
type: mock
- name: repo-dev
type: mock
- name: ci
type: git
source:
uri: https://github.com/concourse/examples.git