expressions
contains / startsWith / format / join / fromJSON
Built-in functions available inside `${{ }}` expressions. GitHub Actions does not allow user-defined functions — only the documented list is valid.
${{ <function>(<args>) }} Common values / subkeys
| Value / Subkey | Purpose |
|---|---|
| contains(search, item) | Substring or array membership test (case-insensitive for strings) |
| startsWith / endsWith(str, needle) | Prefix / suffix test |
| format('{0}-{1}', a, b) | Positional string formatting |
| join(array, sep) | Join an array into a string |
| toJSON / fromJSON | Serialize to / parse from JSON |
| hashFiles('glob', ...) | SHA-256 of matching files, ideal cache key |
| success / failure / cancelled / always | Job/step status predicates |
Examples
if: ${{ startsWith(github.ref, 'refs/tags/v') }} Only run on version tags
with:
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} Cache key derived from a lockfile hash
run: echo ${{ join(matrix.tags, ',') }} Comma-join a matrix array into a string
strategy:
matrix: ${{ fromJSON(needs.setup.outputs.matrix) }} Parse JSON from an upstream output into a matrix
Gotcha
`contains()` is case-insensitive when comparing strings but strictly equal for array items; `toJSON` produces a string that consumers must re-parse with `fromJSON`.
Related keywords
${{ <expression> }}
GitHub Actions expressions are evaluated by the runner and interpolated into YAML values before shells see them. They support literals, operators, contexts, and a fixed set of functions — this is unrelated to Terraform's `${}` interpolation.
${{ github }}
The `github` context exposes information about the workflow run, event payload, repository, and actor. It is available in most expression fields and is the primary source of triggering-event data.
strategy:
Fans a job out across a matrix of variable combinations. Each combination becomes an independent job whose values are exposed via the `matrix` context.