Command Palette

Search for a command to run...

GitHubGitHub

GitHub Actions Setup Guide

Set up GitHub Actions with the current action versions, run your first workflow, configure GitHub-hosted and self-hosted runners and secure your pipelines with OIDC.

GitHub Actions runs your CI/CD pipelines directly from your repository. This guide takes you from an empty repository to a working, secured pipeline using the current action versions and the current runner release.

Requirements

  • A GitHub account with write access to the repository
  • A repository with the code you want to build, test and deploy
  • contents: read permission for the workflow (the default for most events)
  • Optional: self-hosted runners for custom hardware, private networks or specific OS versions

How Actions Work

ConceptWhat it is
WorkflowA YAML file in .github/workflows/ that defines one or more jobs
EventWhat triggers the workflow — push, pull_request, schedule, workflow_dispatch
JobA set of steps that run on a single runner, optionally in parallel with a matrix
StepOne action or shell command inside a job
RunnerThe machine that executes the job — GitHub-hosted or self-hosted

Your First Workflow

Create .github/workflows/ci.yml in your repository:

name: CI
 
on:
  push:
    branches: [main]
  pull_request:
    branches: [main]
  workflow_dispatch: # Adds a "Run workflow" button in the Actions tab
 
permissions:
  contents: read
 
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Check out the repository
        uses: actions/checkout@v7
 
      - name: Set up Node.js
        uses: actions/setup-node@v7
        with:
          node-version: '24'
          cache: 'npm'
 
      - run: npm ci
      - run: npm run build --if-present
      - run: npm test

Push the file and watch the run in the Actions tab of your repository.

Runner Types

GitHub-Hosted Runners

GitHub provides the virtual machine. Pick an image with runs-on:

runs-on: ubuntu-24.04    # Ubuntu (ubuntu-latest currently resolves to 24.04)
runs-on: windows-latest   # Windows Server
runs-on: macos-latest     # macOS (Apple silicon on macos-14+)
runs-on: ubuntu-24.04-arm # ARM64 Linux — free for public repositories

Standard runners give you 2 CPU cores, 7 GB RAM and 14 GB of SSD. They are billed per minute; GitHub-hosted minutes are free for public repositories.

Common Workflows

Caching Dependencies

actions/setup-node can cache npm, pnpm and Yarn caches for you:

- uses: actions/setup-node@v7
  with:
    node-version: '24'
    cache: 'npm'
    cache-dependency-path: '**/package-lock.json'

For anything else, use actions/cache:

- uses: actions/cache@v6
  with:
    path: |
      ~/.cache/pip
      ~/.cache/uv
    key: ${{ runner.os }}-python-${{ hashFiles('**/requirements.txt') }}
    restore-keys: |
      ${{ runner.os }}-python-

Security Best Practices

  1. Set the least-privilege permissions on every workflow

    permissions:
      contents: read
  2. Pin third-party actions to a commit SHA

    - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v7.0.1

    Tags can be moved to a malicious commit; a SHA cannot.

  3. Use OIDC instead of long-lived cloud credentials

    permissions:
      id-token: write
      contents: read
      steps:
        - uses: aws-actions/configure-aws-credentials@v6
          with:
            role-to-assume: arn:aws:iam::123456789012:role/gha-deploy

    GitHub mints a short-lived token per job — there is no secret to leak or rotate.

  4. Protect the GITHUB_TOKEN — it is a secret that expires with the job and can be scoped down per workflow.

  5. Sign and attest your builds

    - uses: actions/attest-build-provenance@v4
      with:
        subject-name: ghcr.io/${{ github.repository }}
        subject-digest: sha256:${{ steps.build.outputs.digest }}
        push-to-registry: true
  6. Scan with CodeQL

    - uses: github/codeql-action@v4
      with:
        languages: javascript-typescript

Troubleshooting

Best Practices

  1. Pin actions to commit SHAs in production pipelines and let Dependabot keep them updated.
  2. Set permissions explicitly on every workflow — never rely on the default.
  3. Use environments for anything that touches production.
  4. Cache dependencies, not build outputs — build outputs change on every commit.
  5. Keep workflows small and composable — use reusable workflows and composite actions.
  6. Use concurrency to cancel superseded runs and save minutes.
  7. Scan with CodeQL and dependency review on every pull request.
  8. Treat the GITHUB_TOKEN as a secret — never print it in logs.

Next Steps