Skip to content

Functions

All CEL standard functions and macros are available. Slipway adds the following.

Function Description
hashFiles(glob...) SHA-256 over the contents of all files matching the globs, for cache keys
contains(x, y) String contains substring, or list contains element
startsWith(s, p) / endsWith(s, p) Prefix and suffix tests (also available as methods)
format("{0}-{1}", a, b) Positional string formatting
join(list, sep) Join a list of strings
toJSON(v) / fromJSON(s) Serialise to and parse JSON
glob(pattern, path) Whether path matches pattern (** supported)
semver.gt(a, b), semver.lt(a, b) Semver comparison
semver.satisfies(v, range) Whether version v satisfies a range such as ">=1.2 <2"
success() Every needed job succeeded (the default job if)
failure() At least one needed job failed
always() True regardless of results
cancelled() The run was cancelled
fileExists(path) Whether a path exists in the workspace. Job scope only
now() Current timestamp
env(name) Read an environment variable at the current scope
# Cache key from lockfiles
cache:
- key: npm-${{ hashFiles("package-lock.json", "**/package-lock.json") }}
paths: [~/.npm]
# Stable image tag
env:
TAG: ${{ format("{0}-{1}", git.branch, git.short_sha) }}
# JSON from a step output
- run: echo "matrix=$(jq -c . services.json)" >> "$SLIPWAY_OUTPUT"
id: plan
# ...in another job:
matrix:
service: ${{ fromJSON(needs.plan.outputs.matrix) }}
# Release gating by version
if: semver.satisfies(release.version, ">=2.0.0 <3.0.0")
# Debug on failure
- run: ./dump-logs.sh
if: failure()
# Skip a step when a file is absent
if: fileExists("Dockerfile")

success(), failure(), always() and cancelled() always refer to the needed jobs when used at job level, and to the previous steps in the job when used at step level. A job if that does not call a status function behaves as if it were wrapped in success() &&. To run after a failure, say so:

- name: notify
needs: [deploy]
if: failure()

Expressions that fail to evaluate (for example indexing a missing key) fail the job with the expression and the offending value in the log. Use has(x.y) to test for a field’s presence first.