Lesson 11 / 25
Expressions and Contexts
${{ }} everywhere.
github, env, vars, secrets, matrix, needs, steps
Expressions inside ${{ }} read contexts: github (event, ref, sha, actor), env, vars (configuration variables), secrets, matrix, needs, steps, runner, inputs. Operators and functions include ==, &&, contains(), startsWith(), format(), toJSON(), hashFiles() and status functions such as success() and failure(). Expressions are evaluated before the shell sees the script, which is why inserting untrusted values directly into run: is dangerous (see the security section). actionlint knows the shape of many contexts and catches misspelled properties.
Useful expressions
Not linted or run here; check the GitHub Actions documentation for current syntax.
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }}
if: ${{ contains(github.event.pull_request.labels.*.name, 'deploy') }}
key: deps-${{ runner.os }}-${{ hashFiles('**/package-lock.json') }}
name: Test on ${{ matrix.os }} / Node ${{ matrix.node }}
if: ${{ failure() && github.ref == 'refs/heads/main' }} # alert only for mainUse vars for non-secret configuration
Repository and environment variables (vars context) keep settings like regions or URLs out of workflow files without treating them as secrets.
Quick check: When are ${{ }} expressions in a run: script evaluated?
- Only on Windows
- By the shell at runtime
- Never
- Before the shell runs the script, by GitHub Actions
Answer
Before the shell runs the script, by GitHub Actions — Substitution happens first.