Specification
On this page
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 idpipeline.app.id
-> the Application idpipeline.id
-> the Pipeline idpipeline.run.id
-> the Pipeline Run idpipeline.run.status
-> the current status of the Pipeline Runpipeline.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 asinputs
-> 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 idjob.name
-> the Job name or id if name is not setjob.status
-> The current status of the Job. This could beexecuting
,succeeded
,failed
, orcancelled
.steps.<id>.status
-> The status of a previous Step with the given id within the Job. This could beskipped
,succeeded
,failed
, orcancelled
.steps.<id>.outputs
-> the map of outputs produced by the Step with the given idneeds.<id>.name
-> the name of the Job with the given idneeds.<id>.status
-> The status of the Job with the given id. This could besucceeded
, orfailed
.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]