GitHub Actions Cheat Sheet
Reference for GitHub Actions workflow YAML syntax, triggers, jobs, matrix builds, and reusable actions.
Basic Workflow
Minimal CI workflow triggered on push and pull_request.
name: CIon: push: branches: [main] pull_request: branches: [main]jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: '20' - run: npm ci - run: npm test
Matrix Strategy
Run a job across multiple versions/OSes in parallel.
jobs: test: strategy: matrix: node: [18, 20, 22] os: [ubuntu-latest, macos-latest] runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: ${{ matrix.node }} - run: npm test
Common Triggers & Contexts
Frequently used event triggers and context expressions.
- on.push- Runs when commits are pushed to matching branches/tags
- on.pull_request- Runs on PR open, sync, or reopen against target branches
- on.workflow_dispatch- Enables manual triggering from the Actions UI with optional inputs
- on.schedule- Cron-based trigger, e.g. cron: '0 0 * * *'
- ${{ github.sha }}- Commit SHA that triggered the workflow
- ${{ secrets.NAME }}- Access repository or org secrets securely
- ${{ needs.job_id.outputs.x }}- Reference output from a dependent job
Reusable Workflow
Call a shared workflow from another repo/workflow.
jobs: call-shared: uses: my-org/shared-workflows/.github/workflows/deploy.yml@main with: environment: production secrets: DEPLOY_TOKEN: ${{ secrets.DEPLOY_TOKEN }}
Composite Action
Package a sequence of steps into a reusable local or published action.
# action.ymlname: 'Setup and Lint'description: 'Installs deps and runs lint'inputs: node-version: description: 'Node version' default: '20'runs: using: 'composite' steps: - uses: actions/setup-node@v4 with: node-version: ${{ inputs.node-version }} - run: npm ci shell: bash - run: npm run lint shell: bash# usage in a workflow:# - uses: ./.github/actions/setup-and-lint# with:# node-version: '22'
Concurrency & Protected Environments
Cancel superseded runs and require approval before deploying to a protected environment.
concurrency: group: deploy-${{ github.ref }} cancel-in-progress: truejobs: deploy: runs-on: ubuntu-latest environment: name: production url: https://app.example.com steps: - uses: actions/checkout@v4 - run: ./deploy.sh
OIDC Cloud Authentication
Exchange a short-lived OIDC token for cloud credentials instead of storing long-lived secrets.
permissions: id-token: write contents: readjobs: deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: arn:aws:iam::123456789012:role/gha-deploy-role aws-region: us-east-1 - run: aws s3 sync ./dist s3://my-bucket/
Dependency Caching & Artifacts
Speed up installs with a keyed cache and pass build output between jobs.
jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/cache@v4 with: path: ~/.npm key: npm-${{ runner.os }}-${{ hashFiles('**/package-lock.json') }} restore-keys: npm-${{ runner.os }}- - run: npm ci && npm run build - uses: actions/upload-artifact@v4 with: name: dist path: dist/ retention-days: 5
Expression Functions & Status Checks
Built-in functions for the ${{ }} expression syntax used in if/with fields.
- contains(list, item)- True if item is found in a string or array
- fromJSON(str) / toJSON(val)- Parse a JSON string into an object, or serialize a value to a JSON string
- hashFiles(pattern...)- Returns a SHA-256 hash of matching file contents, commonly used in cache keys
- always()- Step/job condition that runs regardless of prior failure or cancellation
- failure()- True only if a previous step or dependent job failed
- cancelled()- True if the workflow run was cancelled
- format('{0}-{1}', a, b)- Interpolates positional placeholders into a string
Pin third-party actions to a full commit SHA (not just a version tag) to protect against supply-chain attacks where a tag is force-moved to malicious code.