GitHub Actions Syntax Reference
Every YAML keyword and expression context — on, runs-on,
needs, if, steps, matrix,
secrets, ${{ }} expressions. With the context-availability
gotcha (job-level if: can NOT read env).
Workflow-Level
on:
Declares the events that trigger the workflow. Accepts a single event, a list, or a map with per-event filters (branches, paths, tags, types).
permissions:
Controls the scopes granted to the automatically generated GITHUB_TOKEN. Can be set at the workflow or job level; the job-level block overrides the workflow default.
env:
Defines environment variables for a scope. Declared at the workflow, job, or step level and read back via the `env` context or as real environment variables inside `run:` scripts.
concurrency:
Limits concurrent runs that share the same group so only one is active (and at most one pending). Set at the workflow or job level to serialize deploys or cancel superseded PR builds.
uses: <workflow_call>
Reusable workflows are files that declare `on: workflow_call` and can be invoked as a job in another workflow. The caller passes typed `with:` inputs and either inherits or explicitly forwards secrets.
Jobs
jobs:
Top-level map of jobs that run in parallel by default. Each job has an ID (used by `needs:` and outputs) and either a `steps:` list or a `uses:` reference to a reusable workflow.
runs-on:
Selects the runner (or runner group) that will execute the job. Accepts a single label, an array to match multiple labels (self-hosted), or an object form for larger runners and runner groups.
needs:
Declares job dependencies so the current job waits for the listed jobs to complete successfully. Also exposes their outputs via `needs.<job_id>.outputs.<name>` and their result via `needs.<job_id>.result`.
if:
Conditional expression that controls whether a job or step runs. On a job it gates the entire job; on a step it gates only that step, and both automatically wrap the value in an implicit `${{ }}` if omitted.
outputs:
Declares values a job exposes to downstream jobs that `needs:` it. Values are usually pulled from step outputs written to `$GITHUB_OUTPUT`.
Steps
uses:
Runs a published action inside a step. The reference should include an immutable commit SHA or a version tag; inputs are passed via the `with:` block.
run:
Executes a shell command on the runner. Multi-line scripts run in a single shell invocation; the shell is chosen by `shell:` (or workflow `defaults`) and defaults to bash on Linux/macOS and pwsh on Windows.
Contexts
${{ 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.
${{ vars.* }} / ${{ inputs.* }}
`vars` exposes non-secret configuration variables defined at the repository, environment, or organization level. `inputs` exposes typed parameters passed to `workflow_dispatch`, `workflow_call`, or composite actions.
Expressions & Functions
${{ <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.
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.