Specification

Humanitec Pipelines are defined through a YAML structure uploaded through the Humanitec UI, API, or the Terraform Provider.

The structure contains three required components:

  • The name of the Pipeline
  • The triggers it accepts including definitions of inputs
  • One or more Jobs containing one or more Steps

The structure of the syntax is similar to that of GitHub Actions and defined in detail below. The schema of the structure is available as a json-schema document through the Humanitec API. This is the latest schema active in the Organization:

humctl api GET "/orgs/${HUMANITEC_ORG}/pipeline-schemas/latest"

Root

The top-level structure is a map of properties.

Property Required Example Description
name yes "My Pipeline" A human-readable display name for the Pipeline.
on yes {…} Configuration of triggers and inputs. See details below.
jobs yes {…} Definition of the Pipeline Jobs and Steps. See details below.
id no "my-pipeline" An override for the Pipeline id used in API requests or foreign references. This defaults to a UUID if not provided.
metadata no {"my-org.io/key": "value"} An optional map of key value metadata.
timeout-minutes no 10 An optional timeout for Pipeline Runs, which defaults to 60 minutes. The Run will be canceled if it’s been running longer than this time.
concurrency no {…} Limits and locks around Run concurrency. See details below.
permissions no {…} Definition of Roles to delegate to this Pipeline during execution. The author of the Pipeline must have the same or greater Roles when creating or updating the Pipeline definition.

on

Each key in the map is a supported trigger and provides a different set of inputs to the Pipeline Run as it executes. A Pipeline must support at least one trigger.

deployment_request

This is triggered when there is a deployment request and a Pipeline Criteria exists that maps to this Pipeline.

For more information, see Deployment Pipelines.

No properties are configurable.

The deployment_request trigger provides fixed inputs to the Pipeline Run:

Key Type Value
env_id string The Environment id from the deployment request.
delta_id string The Delta from the deployment request if one was provided.
set_id string The Deployment Set from the deployment request if provided, or retrieved from the deployment specified in deployment_id.
value_set_version_id string The value set version from the deployment request if provided, or retrieved from the deployment specified in deployment_id.
deployment_id string The Deployment to redeploy to the Environment. This is translated into a set_id and value_set_version_id.
comment string An optional comment for the deployment.

artefact

This is triggered when new artefact versions are uploaded to the Organization that match the criteria within the trigger definition. This trigger supports both container and workload (Score) artefact types.

For more information, see Artefact Automation.

The following options can be configured:

Property Required Example Description
type yes "container" A string or list of strings for the artefact types matched by this trigger. This can be container or workload.
include no ["my-artefact-name", "my-artefact\\d"] An optional list of artefact names to be matched by this trigger. Regular expressions are supported.
exclude no ["my-other-artefact-name"] An optional list of artefact names to exclude from this trigger. This takes precedence over include. Regular expressions are supported.
match-ref no "refs/heads/.*" An optional regular expression to match with the ref of an artefact version.
exclude-ref no "refs/heads/main" An optional regular expression which will skip artefact versions that have a matching ref.
batch-minutes no 10 Overrides the batching time for artefact changes. By default artefact changes will be batched together for ten minutes before the Pipeline Run is created.

When triggered, this will start a new Pipeline Run with the following inputs provided:

Key Type Value
container_artefacts String array Zero or more container image references matched by this trigger. Each item is an OCI image reference like my-repo/my-registry:some-version@sha256:01234567-89ab-cdef-0123-456789abcdef.
workload_artefacts String array Zero or more workload artefact references matched by this trigger. Each item is a reference like my-artefact-name:artefact-version@01234567-89ab-cdef-0123-456789abcdef.

pipeline_call

This is triggered by an API request to create a new Pipeline Run. If a Pipeline does not define this trigger, these requests will be rejected.

For more information, see API Triggered Pipelines.

The trigger definition defines the inputs that can be passed to the Pipeline.

Property Required Example Description
inputs no {"name": {"type": "string"}} The map of inputs for the Pipeline.

Each value in the inputs map can further define:

Property Required Example Description
type yes "string' The accepted data type. One of string, boolean, or number.
required no true Whether the input is required or not. Required inputs will reject the trigger request.
description no "My input" An optional description for this input.

Permissions

The permissions configuration indicates the set of Roles to delegate to this Pipeline as it executes. These Roles will impact what kinds of Platform Orchestrator operations can be performed.

Property Required Example Description
application no "developer" The application role the pipeline should execute with.
env-types no {"development": "deployer"} The Role the pipeline should execute as in each environment type.
run-as no "s-01234567-89ab-cdef-0123-456789abcdef"
or
"inherit"
An optional ID of a user or service user to execute this Pipeline as. If equal to inherit, the Run will execute with the permissions of the user who triggered it if there is one.
This is mutually exclusive with application and env-types.

The default permissions configuration is:

permissions:
  run-as: inherit

Pipelines that define an artefact trigger must replace this with a declaration of which roles are delegated to the Pipeline when it runs. For example, the following configuration restricts the Pipeline to just deployment-related activities:

permissions:
  application: developer
  env-types:
    development: deployer

Alternatively, an Organization admin can create a service user and specify the user id to run as:

permissions:
  run-as: s-01234567-89ab-cdef-0123-456789abcdef

Jobs

This is a map of job id to job definition. The job id must be a valid identifier of A-z, 0-9, -, and _ less than 100 characters.

Jobs execute in parallel by default unless there are dependencies between them via the needs property. Any dependency cycles will cause Jobs to fail or not execute.

Each Job contains the following properties:

Property Required Example Description
steps yes [] The sequential list of Steps in this Job.
name no "Deploy job" An optional display name for this Job.
if no ${{ true }} An optional expression that will skip this Job if it evaluates to false.
needs no ["other-job-id"] An optional list of Job ids that must complete successfully before this Job will be executed. Without this, the Job will execute in parallel with other Jobs.
timeout-minutes no 10 An optional timeout for this Job. If this value is exceeded, the Job will be canceled. This can be increased to 48 hours.
continue-on-error no true An optional override that will treat this job as though it had completed successfully even if it fails. This can be used to prevent failure of the Run or to allow execution of dependent Jobs. By default, Jobs will fail and prevent execution of dependent Jobs.
outputs no {"key": "value"} The set of outputs to make available for other Jobs to consume. Each value supports expressions for accessing outputs from Steps.

Steps

Each Step defines a sequential execution within the Job and supports the following properties.

Note that a Step does not have an explicit outputs property. Step outputs are defined through the definition of the Action being used.

Property Required Example Description
uses yes "native://actions/humanitec/deploy@v1" The Action to execute in this Step.
with no {…} The definition of inputs for the action. This property supports expressions.
if no ${{ true }} An optional expression that will skip this Step if it evaluates to false.
id no "step-id" An optional identifier for this Step that can be used to refer to the Step inside expressions.
name no "My Super Step" An optional display name for this Step.
continue-on-error no false An optional override that will treat this Step as though it had completed successfully even if it fails. This can be used to prevent failure of the Step and surrounding Job.

Concurrency

By default, each Pipeline is limited to a maximum of ten concurrent Runs. The concurrency section can be used to further define locks and limit the number of Pipeline Runs.

Property Required Example Description
group no "my-lock" An optional concurrency group. This field may contain interpolated expressions using the ${{ }} syntax. Only one Pipeline Run in the whole Application can be in the executing state at a time for each value of the group.

Expressions

Humanitec Pipelines support an expressions syntax that provides interpolation and transformation functionality in supported fields:

  • concurrency.group
  • jobs.*.if
  • jobs.*.outputs
  • jobs.*.steps.*.if
  • jobs.*.steps.*.with.*

A supported field can contain one or more expressions delineated by a ${{ prefix and }} suffix. Each expression evaluates to a typed value which is coerced to a string if necessary.

  • ${{ 'hello' }} -> "hello"
  • ${{ 42 }} -> 42
  • My name is ${{ 'bob' }} -> "My name is bob"
  • Most ${{ 'cars' }} have ${{ 4 }} wheels -> "Most cars have 4 wheels"

Literals

Expressions support null, booleans, integers, floating point, hexadecimal, and string literals.

  • ${{ true }} and ${{ false }} evaluate to the boolean value
  • ${{ null }} evaluates to a null value
  • Signed 64-bit integer literals are supported through ${{ 123 }} and in hexadecimal like ${{ 0xFF }}
  • Floating point numbers can be expressed as ${{ 0.5 }} and as exponentials like ${{ 2.1e5 }}
  • Strings are encoded using single-quotes as ${{ 'something' }} and single quotes inside a string are encoded using double-single-quotes: ${{ 'it''s easy' }}.

Literal objects and arrays are not supported. If these are required, use fromJson to decode them from a json string literal. For example: ${{ fromJSON('{"key": "value"}') }}. This reduces the chance of errors.

Logical not operator

The only unary operator supported is “not” via the ! symbol. This operator will evaluate to false if the input value is “truthy”. Examples of “truthy” values are “true”, non-empty strings, and non-zero numbers. Objects and arrays are always truthy.

  • ${{ ! true }} -> false
  • ${{ ! '' }} -> true
  • ${{ ! ! 0 }} -> false

Note that !! can be used as shorthand to convert a value into its boolean truthy or falsey.

Logical and operator

The && operator evaluates two arguments and returns whether both values are “truthy”. This returns the 1st value if it is falsey, and the 2nd value in any other case.

  • ${{ true && false }} -> false
  • ${{ false && true }} -> false
  • ${{ true && true }} -> true
  • ${{ true && 0 }} -> 0
  • ${{ '' && true }} -> ""

Since expressions are parsed from left to right, more terms can be added for more complex expressions:

  • ${{ true && 0 && true }} -> 0

Logical or operator

The || operator evaluates two arguments and returns whether either value is “truthy”. This returns the 1st value if it is truthy, and the 2nd value in any other case.

  • ${{ true || false }} -> true
  • ${{ false || true }} -> true
  • ${{ false || 0 }} -> 0
  • ${{ true || 0 }} -> true

This is often used to provide a default value for an expression:

  • ${{ some-value || 'default' }}

Comparison operators

The syntax supports comparison operators <, <=, >, >=, ==, and !=. Values are comparable if they can be coerced to either strings or numbers. The output is boolean. Strings are compared lexicographically.

Arithmetic operators

Arithmetic operators like “+” and “*” are not supported at this time.

Nested expressions

For readability and to manipulate evaluation order, expressions can be nested using parentheses.

  • ${{ ( true ) }} -> true
  • ${{ (1 == 0) || 1 }} -> 1
  • ${{ 1 == (0 || 1) }} -> true

Object indexing

When a value is known to be an object with string keys mapping to values, they can be accessed by “.” or “[..]”. Unknown keys map to a null value.

Assuming an object “foo” exists as {"outer":{"inner": "hello"}}

  • ${{ foo.outer.inner }} -> "hello"
  • ${{ foo.other }} -> null
  • ${{ foo.outer }} -> {"inner":"hello"}
  • ${{ foo.outer['inner'] }} -> "hello"

Array Indexing

When a value is known to be an array, its items can be accessed by integer keys using “[..]”. Unknown items map to a null value.

Assuming an object “foo” exists as ["cat", "dog"]

  • ${{ foo[0] }} -> "cat"
  • ${{ foo[1] }} -> "dog"
  • ${{ foo[2] }} -> null

Context Variables

Different context variables exist depending on where an expression is evaluated and what Jobs or Steps have completed within the Pipeline.

All expressions have access to the “pipeline” and “inputs” contexts.

  • pipeline.org.id -> the Organization id
  • pipeline.app.id -> the Application id
  • pipeline.id -> the Pipeline id
  • pipeline.run.id -> the Pipeline Run id
  • pipeline.run.status -> the current status of the Pipeline Run
  • pipeline.run.trigger -> the event that triggered this Pipeline. (e.g. “pipeline_call”)
  • pipeline.run.run_as -> the user id that this Pipeline Run is executing as
  • inputs -> the map of inputs to the Pipeline Run

Expressions executing in the context of a Job (such as jobs.*.if, jobs.*.steps.*.if or jobs.*.steps.*.with) will additionally have access to variables regarding the Job and dependent Jobs, as well as the Steps within the current Job.

  • job.id -> the Job id
  • job.name -> the Job name or id if name is not set
  • job.status -> The current status of the Job. This could be executing, succeeded, failed, or cancelled.
  • steps.<id>.status -> The status of a previous Step with the given id within the Job. This could be skipped, succeeded, failed, or cancelled.
  • steps.<id>.outputs -> the map of outputs produced by the Step with the given id
  • needs.<id>.name -> the name of the Job with the given id
  • needs.<id>.status -> The status of the Job with the given id. This could be succeeded, or failed.
  • needs.<id>.outputs -> the outputs of a previous Job with the given id that this Job depended on

Expressions in the Job will also have access to Application values and secrets through the “app” context.

  • app.values.MY_KEY -> "my-value"
  • app.values.MY_SECRET -> sensitive("my password")

Secrets will return sensitive values that will be masked out of any log output and cannot pass between steps and jobs. Secrets are only available if the Application has the Humanitec secret store configured as its primary secret store.

Built-in functions

Various built-in functions are available.

Function Output Description
contains(container, item) boolean For arrays, this returns whether the array contains the given item. For other types, this converts the values to lowercase strings and returns whether the container contains the item.
startswith(container, item) boolean Both inputs will be coerced to a string, and the result will be true if there is a prefix match.
endswith(container, item) boolean Both inputs will be coerced to a string, and the result will be true if there is a suffix match.
format(pattern, arguments…) string The pattern will be treated as a formatting string, and the arguments will be interpolated into it to replace {0}, {1}… {N} as applicable.
join(items, delimiter?) string The items will be coerced to strings and combined into a single string using the given delimiter or “,”.
tojson(input) string The input will be encoded as json and returned.
fromjson(input) any The input will be decoded from json and returned.
sensitive(input) any The input will be coerced to a string and recorded as a sensitive value that must be masked from outputs. The original, unmasked, value will be returned for use in the expression.
map(items, inline function) array The inline function will be applied to each item in the input array and returned.
filter(items, inline function) array The inline function will be applied to each item in the input and the item will be returned if it yields a truthy value.
group(items, inline function) object The inline function will be applied to each item in the input array and the items will be returned grouped into arrays by resulting value.

The map, filter, and group functions take in an inline function which can be written using a variable => expression syntax. For example:

filter(fromJSON('[1, 2, 3, 4, 5, 6]'), i => i > 3)  ==  [4, 5, 6]
Top