GitHub Actions — Level by Level›Level 1 · Cheat sheet & self-check

Level 1 — Foundations · wrap-up

Cheat sheet & self-check

Every command from this section on one page.

01 · Workflows, events and your first pipeline

Workflow skeleton

.github/workflows/ci.ymlWhere workflow files live
on: { push: { branches: [main] }, pull_request: {} }Run on pushes to main and on pull requests
on: workflow_dispatchAdd a manual 'Run workflow' button
on: { schedule: [ { cron: '0 3 * * 1' } ] }Run every Monday 03:00 UTC
needs: testRun this job after the test job succeeds
permissions: { contents: read }Least privilege for the built-in GITHUB_TOKEN

GitHub CLI

gh workflow listWorkflows in the repository
gh workflow run ci.yml --ref mainTrigger a workflow_dispatch run
gh run list --limit 5Recent runs
gh run watchFollow a run live
gh run view <id> --log-failedOnly the logs of failed steps
gh secret set REGISTRY_TOKEN < token.txtStore a repository secret

02 · The execution model

Structure

.github/workflows/*.ymlWhere workflows live
on: [push, pull_request, workflow_dispatch, schedule]Events that trigger a workflow
jobs.<id>.runs-on: ubuntu-latestWhich runner (label) runs the job
jobs.<id>.needs: [build]Run after another job (otherwise jobs run in parallel)
permissions: { contents: read }Least-privilege GITHUB_TOKEN

Data & speed

${{ github.sha }} ${{ secrets.X }} ${{ vars.Y }} ${{ needs.build.outputs.digest }}Contexts in expressions
echo "name=value" >> "$GITHUB_OUTPUT"Set a step output
actions/cache / setup-* with cache:Reuse dependencies between runs
actions/upload-artifact / download-artifactPass files between jobs or keep build outputs
concurrency: { group: deploy-prod, cancel-in-progress: false }One deployment at a time

03 · Real pipelines

Reuse

on: workflow_call: { inputs: …, secrets: … }Make a workflow callable
jobs.x.uses: org/ci/.github/workflows/build.yml@v1Call it (job level)
secrets: inheritPass the caller's secrets (same org/enterprise)
action.yml → runs: { using: composite, steps: … }A composite action (reusable steps)

Build & deploy

strategy: { matrix: { python: ["3.11","3.12"] }, fail-fast: false }Test several versions
docker/build-push-action → outputs.digestBuild, push, and capture the image digest
environment: prodJob gated by the prod environment's protection rules
on.push.paths: [ "services/api/**" ]Run only when relevant files change

04 · Build, test and publish container images

Key actions

docker/setup-buildx-action@v3Enable BuildKit/Buildx on the runner
docker/login-action@v3Log in to GHCR, ECR or another registry
docker/metadata-action@v5Generate tags and labels from Git refs
docker/build-push-action@v6Build (multi-platform) and push; outputs the digest
aquasecurity/trivy-actionScan the image; fail on severities you choose

Useful expressions

${{ steps.build.outputs.digest }}The pushed image digest
${{ github.sha }}The commit SHA being built
cache-from: type=gha / cache-to: type=gha,mode=maxReuse layers between runs via the Actions cache