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 task-config.outputs 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 task-config.image_resource 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