Triggers
on: pull_request
Run on pull requests
on: [push, pull_request]
Several events at once
on.push.branches: [main, 'release/**']
Only these branches
on.push.tags: ['v*']
Run on version tags
on.<event>.paths: ['src/**']
Only when these files change
A skipped workflow leaves a required check pending.
on.pull_request.types: [opened, synchronize]
Limit PR activity types
on.workflow_dispatch
Allow manual runs
Only fires from the default branch.
on.workflow_dispatch.inputs.<name>
Manual run parameters
on.schedule: - cron: '0 3 * * 1'
Run on a cron schedule (UTC)
on.workflow_call
Make workflow reusable
on.pull_request_target
PR event with base-branch secrets
Never check out and run untrusted PR code with it.
Matrix & Containers
strategy.matrix.<key>: [a, b]
One job per value
${{ matrix.<key> }}
Read the current value
matrix.include: [{...}]
Add or extend combinations
matrix.exclude: [{...}]
Drop combinations
strategy.fail-fast: false
Let other legs finish
Default is true: one failure cancels the rest.
container: <image>
Run the job in a container
services.<id>.image: <image>
Sidecar such as a database
services.<id>.options: --health-cmd ...
Docker flags, health checks
Expressions & Contexts
${{ <expression> }}
Evaluate an expression
github.event_name
Event that triggered the run
github.ref / github.ref_name
Full ref / short branch or tag
github.sha
Commit SHA of the run
vars.<NAME>
Configuration variable
needs.<job>.outputs.<name>
Output of a needed job
steps.<id>.outputs.<name>
Output of an earlier step
runner.os
Runner OS (Linux, Windows, macOS)
contains(<a>, <b>)
Substring or array membership
startsWith(<s>, <prefix>)
String prefix test
hashFiles('**/package-lock.json')
Hash of files, e.g. cache key
toJSON(<v>) / fromJSON(<s>)
Convert to and from JSON
fromJSON on an output builds a dynamic matrix.
success() / failure() / cancelled()
Status check functions
Operators
| Operator |
Meaning |
&& || |
and, or |
! |
not |
== != |
equal (case-insensitive strings) |
<= >= |
compare |
Data & Secrets
secrets.<NAME>
Read a repository secret
secrets.GITHUB_TOKEN
Automatic per-run token
echo "k=v" >> "$GITHUB_OUTPUT"
Set a step output
echo "K=v" >> "$GITHUB_ENV"
Set env for later steps
echo "<dir>" >>
"$GITHUB_PATH"
Prepend to PATH for later steps
cat report.md >> "$GITHUB_STEP_SUMMARY"
Markdown on the run summary page
echo "::error file=<f>::<msg>"
Annotate an error
jobs.<id>.outputs.<name>: ${{
steps.<id>.outputs.<name> }}
Expose step output to other jobs
on.workflow_call.outputs
Return values from a reusable workflow
Permissions & Concurrency
permissions: contents: read
Least-privilege GITHUB_TOKEN
Naming any scope sets the rest to none.
permissions: id-token: write
Allow OIDC to cloud providers
permissions: pull-requests: write
Let a job comment on PRs
concurrency.group: <name>
One run per group at a time
concurrency.cancel-in-progress: true
Cancel superseded runs
env: <VAR>: <value>
Workflow-wide variable