Level 1 — Foundations · wrap-up
Cheat sheet & self-check
Every command from this section on one page.
Workflow skeleton
.github/workflows/ci.yml | Where workflow files live |
on: { push: { branches: [main] }, pull_request: {} } | Run on pushes to main and on pull requests |
on: workflow_dispatch | Add a manual 'Run workflow' button |
on: { schedule: [ { cron: '0 3 * * 1' } ] } | Run every Monday 03:00 UTC |
needs: test | Run this job after the test job succeeds |
permissions: { contents: read } | Least privilege for the built-in GITHUB_TOKEN |
GitHub CLI
gh workflow list | Workflows in the repository |
gh workflow run ci.yml --ref main | Trigger a workflow_dispatch run |
gh run list --limit 5 | Recent runs |
gh run watch | Follow a run live |
gh run view <id> --log-failed | Only the logs of failed steps |
gh secret set REGISTRY_TOKEN < token.txt | Store a repository secret |
Structure
.github/workflows/*.yml | Where workflows live |
on: [push, pull_request, workflow_dispatch, schedule] | Events that trigger a workflow |
jobs.<id>.runs-on: ubuntu-latest | Which 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-artifact | Pass files between jobs or keep build outputs |
concurrency: { group: deploy-prod, cancel-in-progress: false } | One deployment at a time |
Reuse
on: workflow_call: { inputs: …, secrets: … } | Make a workflow callable |
jobs.x.uses: org/ci/.github/workflows/build.yml@v1 | Call it (job level) |
secrets: inherit | Pass 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.digest | Build, push, and capture the image digest |
environment: prod | Job gated by the prod environment's protection rules |
on.push.paths: [ "services/api/**" ] | Run only when relevant files change |
Key actions
docker/setup-buildx-action@v3 | Enable BuildKit/Buildx on the runner |
docker/login-action@v3 | Log in to GHCR, ECR or another registry |
docker/metadata-action@v5 | Generate tags and labels from Git refs |
docker/build-push-action@v6 | Build (multi-platform) and push; outputs the digest |
aquasecurity/trivy-action | Scan 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=max | Reuse layers between runs via the Actions cache |