Snippets target the current syntax. Reach for actions/checkout@v4,
actions/setup-*@v5,
actions/cache@v4 — older versions either run on the deprecated
Node 16 runtime or have known security issues. Pin third-party actions by full commit SHA, not branch /
tag.
files · toolingSetup
.github/workflows/*.yml
Workflow definitions. One file per workflow.
.github/actions/<name>/action.yml
Repo-local composite / JS action.
gh workflow list / run / view
CLI inspect + trigger.
gh run rerun <id>
Re-run failed jobs from the CLI.
act -W .github/workflows/ci.yml
Run workflows locally in Docker.
actionlint .github/workflows/*.yml
Static lint. Catches expressions + matrix bugs.
VS Code: GitHub Actions extension
Inline schema + autocomplete.
top-level structureWorkflows
name: CI
Display name in the UI.
on: push / pull_request / schedule / workflow_dispatch
Trigger list.
permissions: { … }
Token scope. Default to least privilege.
env: { KEY: val }
Workflow-wide env. Job + step env: override.
defaults.run.shell / working-directory
Apply to every run: step.
concurrency: { group, cancel-in-progress }
Coalesce duplicate / superseded runs.
jobs: { id: { … } }
Run in parallel by default. Use needs: for dependencies.
lint · test · build · publishEnd-to-end · Release pipeline
Concurrency-gated workflow: lint, then a reusable test job, then a tag-only Docker build to GHCR with
BuildKit cache. The shape most CI/CD-on-Actions setups converge on.
Default permissions: { contents: read }.
The default token has broad write scope. Drop it at the workflow level; opt back into id-token: write
or packages: write only on the job that needs it.
Pin third-party actions by SHA.
Tags can be moved; SHAs can’t. Dependabot will open PRs to bump SHA + comment with the tag for review.
Wire concurrency to cancel stale PR runs.
Two pushes to the same PR shouldn’t both run to completion. cancel-in-progress: true
on pull_request saves real minutes.
Common trapsWatch out for
pull_request_target on forks is dangerous.
It runs with full repo permissions on PRs from forks — including malicious code if you check out the
head SHA. Don’t check out untrusted refs in that context.
Inline secrets in run: commands leak via process trees.run: curl -H "Authorization: Bearer ${{ secrets.X }}" may end up in
logs / ps output. Set it as env: and reference $X.
Matrix expansion is implicit.
Without fail-fast: false a single broken combo cancels its siblings —
you lose visibility on whether the rest would have passed.
GitHub Actions is GitHub's built-in CI/CD platform. It runs automated workflows — tests, builds, deployments, and custom automations — triggered by repository events like push, pull_request, or schedule. Workflows are defined as YAML files in .github/workflows/.
What is the difference between a job and a step in GitHub Actions?
A job is a unit of work that runs on a single runner (virtual machine). Each job is composed of steps, which are individual shell commands or actions that run sequentially inside that runner. Jobs run in parallel by default; add needs: [other-job] to create dependencies between them.
How do I use secrets in GitHub Actions?
Add secrets in your repo or org settings under Settings > Secrets and variables > Actions. Reference them in your workflow as ${{ secrets.MY_SECRET }}. Secrets are masked in logs and not passed to workflows triggered by forks (pull_request from forks). Use environments for deployment secrets with required reviewers.
What is a matrix strategy in GitHub Actions?
A matrix strategy lets you run a job across multiple combinations of variables — for example, testing against Python 3.10, 3.11, and 3.12 at once. Define it with strategy.matrix, reference values with ${{ matrix.python-version }}, and use exclude or include to fine-tune which combinations run.
How does caching work in GitHub Actions?
Use actions/cache to save and restore directories (e.g., node_modules, pip cache, Maven .m2) between workflow runs. Specify a key (usually built from a hash of your lockfile) and restore-keys for fallback. Cache hits are restored before your steps run; a miss writes the cache at the end of the job.
What are reusable workflows in GitHub Actions?
Reusable workflows let you call one workflow from another using uses: org/repo/.github/workflows/deploy.yml@main. The called workflow defines inputs and secrets it accepts; the caller passes them. This avoids duplicating pipeline logic across multiple repos — useful for org-wide deploy or release patterns.