jobs
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.
if: ${{ <expression> }} # or bare expression Common values / subkeys
| Value / Subkey | Purpose |
|---|---|
| success() | Default — all previous steps/needs succeeded |
| always() | Run even on failure/cancellation |
| failure() | Run only if a previous step/need failed |
| cancelled() | Run only when the workflow was cancelled |
Examples
if: github.ref == 'refs/heads/main' Branch guard (implicit expression, no braces required)
if: ${{ github.event_name == 'pull_request' && !github.event.pull_request.draft }} Only non-draft PRs
if: ${{ always() }} Always run — useful for cleanup/notify
if: ${{ needs.build.result == 'success' && inputs.deploy }} Depend on upstream result and an input
Gotcha
Without `always()` / `failure()` / `!cancelled()`, `if:` implicitly ANDs with `success()`, so a bare expression won't run after a failure; on jobs, `steps.*`, `env`, and `matrix` are unavailable — only `needs`, `github`, `inputs`, `vars`, and `secrets` can be referenced from job-level `if:`.
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.
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`.
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.
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.