Skip to content

Templates

OrchStep uses Go templates with Sprig functions for variable interpolation, and supports JavaScript expressions via the Goja VM for complex logic.

Expressions are enclosed in {{ }}:

steps:
- func: shell
do: echo "Deploying {{ vars.version }} to {{ vars.environment }}"
PatternDescription
{{ vars.name }}Workflow variable
{{ steps.step_name.field }}Step output
{{ env.VAR_NAME }}Environment variable
{{ result.output }}Current step result (in outputs:)
{{ loop.item }}Current loop item
{{ loop.index }}Current loop index (zero-based)
do: |
echo "Deploying to {{ vars.env }}"
{{- if eq vars.env "production" }}
echo "Extra production checks enabled"
{{- end }}
do: |
{{ range vars.servers }}
echo "Server: {{ . }}"
{{ end }}

OrchStep includes Sprig v3 with 100+ utility functions.

FunctionExampleResult
upper{{ "hello" | upper }}HELLO
lower{{ "HELLO" | lower }}hello
title{{ "hello world" | title }}Hello World
trim{{ " hello " | trim }}hello
trimSuffix{{ "hello.txt" | trimSuffix ".txt" }}hello
replace{{ "hello" | replace "l" "r" }}herro
contains{{ contains "hello" "ell" }}true
hasPrefix{{ hasPrefix "hello" "hel" }}true
hasSuffix{{ hasSuffix "hello" "llo" }}true
repeat{{ "ab" | repeat 3 }}ababab
substr{{ substr 0 5 "hello world" }}hello
trunc{{ trunc 5 "hello world" }}hello
camelcase{{ "my-service" | camelcase }}myService
snakecase{{ "myService" | snakecase }}my_service
kebabcase{{ "myService" | kebabcase }}my-service
split{{ split "," "a,b,c" }}list [a, b, c]
join{{ list "a" "b" "c" | join "," }}a,b,c
FunctionExampleResult
add{{ add 1 2 }}3
sub{{ sub 10 3 }}7
mul{{ mul 3 4 }}12
div{{ div 10 3 }}3
mod{{ mod 10 3 }}1
max{{ max 5 10 }}10
min{{ min 5 10 }}5
ceil{{ ceil 1.5 }}2
floor{{ floor 1.5 }}1
FunctionDescription
firstFirst element of a list
lastLast element of a list
restAll elements except first
appendAdd element to end of list
concatMerge two lists
uniqRemove duplicate elements
hasCheck if list contains element
withoutRemove elements from list
sliceSub-list extraction
reverseReverse list order
FunctionDescription
getGet value by key
setSet value for key
hasKeyCheck if key exists
keysGet all keys
valuesGet all values
pickSelect subset of keys
omitExclude subset of keys
mergeMerge dictionaries
FunctionDescription
atoiString to integer
toStringConvert to string
toJsonSerialize to JSON string
toPrettyJsonSerialize to formatted JSON
fromJsonParse JSON string to object
toYamlSerialize to YAML string
FunctionExample
nowCurrent time
date{{ now | date "2006-01-02" }}
dateModify{{ now | dateModify "+24h" }}
unixEpoch{{ now | unixEpoch }}
FunctionDescription
b64encBase64 encode
b64decBase64 decode
sha256sumSHA-256 hash
urlqueryURL-encode string
uuidv4Generate UUID v4
FunctionExample
default{{ vars.port | default 8080 }}
empty{{ empty vars.name }}
coalesce{{ coalesce vars.a vars.b "fallback" }}
ternary{{ ternary "yes" "no" (eq vars.env "prod") }}
FunctionDescriptionExample
regexMatchTest if string matches pattern{{ regexMatch "v[0-9]+" vars.version }}
regexFindExtract first capture group{{ result.output | regexFind "ID=(.+)" }}
regexFindAllExtract all matches{{ regexFindAll "[0-9]+" result.output -1 }}
regexReplaceAllReplace all matches{{ regexReplaceAll "[0-9]+" result.output "X" }}
FunctionExample
semver{{ semver "1.2.3" }} — parse to semver object
semverCompare{{ semverCompare ">=1.2.0" vars.version }} — compare versions

Use regex in outputs: to extract structured data from command output:

steps:
- name: build
func: shell
do: |
echo "Building..."
echo "IMAGE=myapp:v1.2.3"
echo "DIGEST=sha256:abc123"
echo "SIZE=42MB"
outputs:
image: '{{ result.output | regexFind "IMAGE=(.+)" }}'
digest: '{{ result.output | regexFind "DIGEST=(.+)" }}'
size: '{{ result.output | regexFind "SIZE=(.+)" }}'
# Extract key=value pair
output_field: '{{ result.output | regexFind "KEY=(.+)" }}'
# Extract JSON field from mixed output
json_field: '{{ result.data.field_name }}'
# Trim whitespace from output
clean_output: '{{ result.output | trim }}'
# Default value if empty
safe_value: '{{ result.output | default "unknown" }}'
# Extract version number
version: '{{ result.output | regexFind "([0-9]+\\.[0-9]+\\.[0-9]+)" }}'

For complex logic that goes beyond Go templates, OrchStep supports JavaScript via the Goja VM. JavaScript is used in:

  • assert conditions (when no {{ }} wrapper)
  • retry.when conditions
  • loop.until conditions
  • transform function do: blocks
# Assert with JavaScript
- func: assert
args:
condition: 'steps.api.status_code >= 200 && steps.api.status_code < 300'
# Retry with JavaScript condition
retry:
when: |
result.exit_code != 0 &&
!result.output.includes('invalid') &&
retry.attempt < 3
# Loop until with JavaScript
loop:
count: 30
until: 'steps.check.output.includes("READY")'
  • Use single quotes around Go template conditions to avoid YAML escaping: '{{ eq vars.x "y" }}'
  • Prefer regexFind over complex shell parsing for output extraction
  • Use default to provide fallback values: {{ vars.port | default 8080 }}
  • Use trim on extracted outputs to remove trailing newlines
  • Use JavaScript syntax for complex boolean logic (more readable than nested Go template and/or)