Zum Inhalt springen

GitHub Actions Cheatsheet

GitHub Actions Cheatsheet

Installation & Setup

GitHub CLI (gh)

PlatformCommand
Ubuntu/Debian`curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg \
Fedora/RHELsudo dnf install gh
Arch Linuxsudo pacman -S github-cli
macOS (Homebrew)brew install gh
Windows (Chocolatey)choco install gh
Windows (WinGet)winget install --id GitHub.cli

Self-Hosted Runner Setup

PlatformSetup Commands
Linuxmkdir actions-runner && cd actions-runner && curl -o actions-runner-linux-x64-2.311.0.tar.gz -L https://github.com/actions/runner/releases/download/v2.311.0/actions-runner-linux-x64-2.311.0.tar.gz && tar xzf ./actions-runner-linux-x64-2.311.0.tar.gz
macOSmkdir actions-runner && cd actions-runner && curl -o actions-runner-osx-x64-2.311.0.tar.gz -L https://github.com/actions/runner/releases/download/v2.311.0/actions-runner-osx-x64-2.311.0.tar.gz && tar xzf ./actions-runner-osx-x64-2.311.0.tar.gz
Windowsmkdir actions-runner; cd actions-runner; Invoke-WebRequest -Uri https://github.com/actions/runner/releases/download/v2.311.0/actions-runner-win-x64-2.311.0.zip -OutFile actions-runner-win-x64-2.311.0.zip

Act (Local Testing Tool)

PlatformCommand
Linux/macOS (curl)`curl https://raw.githubusercontent.com/nektos/act/master/install.sh \
Homebrewbrew install act
Gogo install github.com/nektos/act@latest
Windows (Chocolatey)choco install act-cli
Windows (Scoop)scoop install act

Basic GitHub CLI Commands

CommandDescription
gh run listList all workflow runs in the repository
gh run view <run-id>View details of a specific workflow run
gh run watch <run-id>Watch a workflow run in real-time
gh run view <run-id> --logView logs for a specific workflow run
gh run download <run-id>Download artifacts from a workflow run
gh workflow listList all workflows in the repository
gh workflow view <workflow-name>View details of a specific workflow
gh workflow enable <workflow-name>Enable a disabled workflow
gh workflow disable <workflow-name>Disable a workflow
gh workflow run <workflow-name>Manually trigger a workflow
gh workflow run <workflow-name> -f key=valueTrigger workflow with input parameters
gh run cancel <run-id>Cancel a running workflow
gh run rerun <run-id>Rerun a completed workflow
gh run rerun <run-id> --failedRerun only failed jobs in a workflow
gh auth loginAuthenticate GitHub CLI with your account

Self-Hosted Runner Management

CommandDescription
./config.sh --url https://github.com/ORG/REPO --token TOKENConfigure a new self-hosted runner
sudo ./svc.sh installInstall runner as a system service (Linux/macOS)
sudo ./svc.sh startStart the runner service
sudo ./svc.sh stopStop the runner service
sudo ./svc.sh statusCheck runner service status
sudo ./svc.sh uninstallUninstall runner service
./config.sh remove --token TOKENRemove runner from repository
./run.shRun the runner interactively (not as service)
gh api repos/:owner/:repo/actions/runnersList all self-hosted runners via API
gh api -X DELETE repos/:owner/:repo/actions/runners/RUNNER_IDRemove runner via API

Local Testing with Act

CommandDescription
act -lList all workflows and jobs available locally
actRun the default event (push) locally
act pushRun workflows triggered by push event
act pull_requestRun workflows triggered by pull request event
act -j job-nameRun a specific job by name
act -s GITHUB_TOKEN=tokenRun with a secret value
act -s SECRET_NAMEPrompt for secret value interactively
act --secret-file .secretsLoad secrets from a file
act -P ubuntu-latest=nektos/act-environments-ubuntu:18.04Use specific Docker image for runner
act -nDry run - show what would be executed
act -vVerbose output for debugging
act --container-architecture linux/amd64Specify container architecture
act -W .github/workflows/ci.ymlRun specific workflow file
act --env-file .envLoad environment variables from file

Advanced GitHub CLI Commands

CommandDescription
gh run list --workflow=ci.ymlList runs for a specific workflow
gh run list --branch=main --limit=20List runs for specific branch with limit
gh run view --log-failedView only failed job logs
gh run view --job=12345View specific job within a run
gh workflow run deploy.yml -f environment=production -f version=1.2.3Trigger workflow with multiple inputs
gh api repos/:owner/:repo/actions/runs/:run_id/logsDownload run logs via API
gh api repos/:owner/:repo/actions/workflowsList workflows via API
gh api repos/:owner/:repo/actions/secretsList repository secrets
gh secret set SECRET_NAME < secret.txtSet a repository secret from file
gh secret set SECRET_NAME --body "value"Set a repository secret from string
gh secret listList all repository secrets
gh secret remove SECRET_NAMERemove a repository secret
gh api repos/:owner/:repo/actions/cachesList workflow caches
gh api -X DELETE repos/:owner/:repo/actions/caches/:cache_idDelete a specific cache
gh run download <run-id> -n artifact-nameDownload specific artifact by name

Workflow File Structure

Basic Workflow Template

name: CI Pipeline

# Trigger configuration
on:
  push:
    branches: [ main, develop ]
    paths:
      - 'src/**'
      - '**.js'
  pull_request:
    branches: [ main ]
  workflow_dispatch:  # Manual trigger
    inputs:
      environment:
        description: 'Environment to deploy'
        required: true
        default: 'staging'

# Environment variables
env:
  NODE_VERSION: '18'
  CACHE_KEY: v1

# Jobs definition
jobs:
  build:
    runs-on: ubuntu-latest
    timeout-minutes: 30
    
    steps:
      - name: Checkout code
        uses: actions/checkout@v4
        with:
          fetch-depth: 0
      
      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: ${{ env.NODE_VERSION }}
          cache: 'npm'
      
      - name: Install dependencies
        run: npm ci
      
      - name: Run tests
        run: npm test
        env:
          CI: true
      
      - name: Build application
        run: npm run build

Matrix Strategy

jobs:
  test:
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os: [ubuntu-latest, windows-latest, macos-latest]
        node-version: [16, 18, 20]
        include:
          - os: ubuntu-latest
            node-version: 20
            experimental: true
        exclude:
          - os: macos-latest
            node-version: 16
      fail-fast: false
      max-parallel: 3
    
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node-version }}
      - run: npm test

Conditional Execution

jobs:
  deploy:
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/main' && github.event_name == 'push'
    
    steps:
      - name: Deploy to staging
        if: contains(github.event.head_commit.message, '[staging]')
        run: ./deploy.sh staging
      
      - name: Deploy to production
        if: startsWith(github.ref, 'refs/tags/v')
        run: ./deploy.sh production
      
      - name: Conditional step with multiple conditions
        if: |
          success() &&
          github.actor == 'dependabot[bot]' &&
          contains(github.event.pull_request.labels.*.name, 'automerge')
        run: echo "Auto-merging PR"

Caching Configuration

steps:
  # Cache npm dependencies
  - name: Cache node modules
    uses: actions/cache@v3
    with:
      path: ~/.npm
      key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
      restore-keys: |
        ${{ runner.os }}-node-
  
  # Cache pip dependencies
  - name: Cache pip
    uses: actions/cache@v3
    with:
      path: ~/.cache/pip
      key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
      restore-keys: |
        ${{ runner.os }}-pip-
  
  # Cache Gradle dependencies
  - name: Cache Gradle
    uses: actions/cache@v3
    with:
      path: |
        ~/.gradle/caches
        ~/.gradle/wrapper
      key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
  
  # Cache Docker layers
  - name: Cache Docker layers
    uses: actions/cache@v3
    with:
      path: /tmp/.buildx-cache
      key: ${{ runner.os }}-buildx-${{ github.sha }}
      restore-keys: |
        ${{ runner.os }}-buildx-

Artifacts Management

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Build application
        run: npm run build
      
      # Upload artifacts
      - name: Upload build artifacts
        uses: actions/upload-artifact@v3
        with:
          name: build-output
          path: |
            dist/
            build/
            !dist/**/*.map
          retention-days: 30
          if-no-files-found: error
      
      # Upload test results
      - name: Upload test results
        if: always()
        uses: actions/upload-artifact@v3
        with:
          name: test-results-${{ matrix.os }}
          path: test-results/
  
  deploy:
    needs: build
    runs-on: ubuntu-latest
    steps:
      # Download artifacts
      - name: Download build artifacts
        uses: actions/download-artifact@v3
        with:
          name: build-output
          path: ./artifacts
      
      - name: Deploy artifacts
        run: ./deploy.sh ./artifacts

Environment and Secrets

jobs:
  deploy:
    runs-on: ubuntu-latest
    environment:
      name: production
      url: https://example.com
    
    env:
      NODE_ENV: production
      API_URL: https://api.example.com
    
    steps:
      - name: Deploy with secrets
        run: |
          echo "Deploying to $NODE_ENV"
          ./deploy.sh
        env:
          DEPLOY_KEY: ${{ secrets.DEPLOY_KEY }}
          AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
          AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
      
      - name: Use GitHub token
        run: |
          gh api user
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

Composite Actions

File: .github/actions/setup-project/action.yml

name: 'Setup Project'
description: 'Setup Node.js and install dependencies'
inputs:
  node-version:
    description: 'Node.js version'
    required: false
    default: '18'
  cache-key:
    description: 'Cache key prefix'
    required: false
    default: 'v1'
outputs:
  cache-hit:
    description: 'Whether cache was hit'
    value: ${{ steps.cache.outputs.cache-hit }}

runs:
  using: 'composite'
  steps:
    - name: Setup Node.js
      uses: actions/setup-node@v4
      with:
        node-version: ${{ inputs.node-version }}
    
    - name: Cache dependencies
      id: cache
      uses: actions/cache@v3
      with:
        path: node_modules
        key: ${{ inputs.cache-key }}-${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
    
    - name: Install dependencies
      if: steps.cache.outputs.cache-hit != 'true'
      run: npm ci
      shell: bash

Using composite action:

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - name: Setup project
        uses: ./.github/actions/setup-project
        with:
          node-version: '20'
          cache-key: 'v2'
      
      - name: Build
        run: npm run build

Reusable Workflows

File: .github/workflows/reusable-deploy.yml

name: Reusable Deploy Workflow

on:
  workflow_call:
    inputs:
      environment:
        required: true
        type: string
      version:
        required: false
        type: string
        default: 'latest'
    secrets:
      deploy-key:
        required: true
    outputs:
      deployment-url:
        description: "Deployment URL"
        value: ${{ jobs.deploy.outputs.url }}

jobs:
  deploy:
    runs-on: ubuntu-latest
    environment: ${{ inputs.environment }}
    outputs:
      url: ${{ steps.deploy.outputs.url }}
    
    steps:
      - uses: actions/checkout@v4
      
      - name: Deploy
        id: deploy
        run: |
          ./deploy.sh ${{ inputs.environment }} ${{ inputs.version }}
          echo "url=https://${{ inputs.environment }}.example.com" >> $GITHUB_OUTPUT
        env:
          DEPLOY_KEY: ${{ secrets.deploy-key }}

Calling reusable workflow:

jobs:
  deploy-staging:
    uses: ./.github/workflows/reusable-deploy.yml
    with:
      environment: staging
      version: '1.2.3'
    secrets:
      deploy-key: ${{ secrets.STAGING_DEPLOY_KEY }}
  
  deploy-production:
    needs: deploy-staging
    uses: ./.github/workflows/reusable-deploy.yml
    with:
      environment: production
      version: '1.2.3'
    secrets:
      deploy-key: ${{ secrets.PROD_DEPLOY_KEY }}

Common Workflow Triggers

TriggerDescriptionExample
pushOn push to brancheson: push: branches: [main]
pull_requestOn PR eventson: pull_request: types: [opened, synchronize]
workflow_dispatchManual triggeron: workflow_dispatch: inputs: ...
scheduleCron scheduleon: schedule: - cron: '0 0 * * *'
releaseOn release eventson: release: types: [published]
issuesOn issue eventson: issues: types: [opened, labeled]
issue_commentOn issue commentson: issue_comment: types: [created]
repository_dispatchExternal webhookon: repository_dispatch: types: [deploy]
workflow_runAfter another workflowon: workflow_run: workflows: [CI]
pull_request_targetPR from forks (careful!)on: pull_request_target

Context Variables

ContextDescriptionExample Usage
github.actorUser who triggered workflow${{ github.actor }}
github.event_nameEvent that triggered workflow${{ github.event_name }}
github.refBranch or tag ref${{ github.ref }}
github.shaCommit SHA${{ github.sha }}
github.repositoryOwner/repo name${{ github.repository }}
github.workspaceWorkspace directory path${{ github.workspace }}
runner.osOperating system${{ runner.os }}
runner.tempTemp directory path${{ runner.temp }}
secrets.GITHUB_TOKENAuto-generated token${{ secrets.GITHUB_TOKEN }}
env.VAR_NAMEEnvironment variable${{ env.NODE_VERSION }}
matrix.valueMatrix value${{ matrix.node-version }}
needs.job.outputs.varOutput from previous job${{ needs.build.outputs.version }}
steps.step_id.outputs.varOutput from step${{ steps.build.outputs.artifact }}
job.statusJob status${{ job.status }}

Common Use Cases

Use Case 1: Node.js CI/CD Pipeline

name: Node.js CI/CD

on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        node-version: [16, 18, 20]
    
    steps:
      - uses: actions/checkout@v4
      
      - name: Setup Node.js ${{ matrix.node-version }}
        uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node-version }}
          cache: 'npm'
      
      - name: Install dependencies
        run: npm ci
      
      - name: Run linter
        run: npm run lint
      
      - name: Run tests
        run: npm test -- --coverage
      
      - name: Upload coverage
        uses: codecov/codecov-action@v3
        with:
          files: ./coverage/lcov.info
  
  build:
    needs: test
    runs-on: ubuntu-latest
    if: github.event_name == 'push'
    
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: '18'
          cache: 'npm'
      
      - run: npm ci
      - run: npm run build
      
      - name: Upload build artifacts
        uses: actions/upload-artifact@v3
        with:
          name: dist
          path: dist/
  
  deploy:
    needs: build
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/main'
    environment:
      name: production
      url: https://example.com
    
    steps:
      - name: Download artifacts
        uses: actions/download-artifact@v3
        with:
          name: dist
          path: dist/
      
      - name: Deploy to production
        run: |
          # Deploy commands here
          echo "Deploying to production..."

Use Case 2: Docker Build and Push

name: Docker Build and Push

on:
  push:
    branches: [ main ]
    tags: [ 'v*' ]

env:
  REGISTRY: ghcr.io
  IMAGE_NAME: ${{ github.repository }}

jobs:
  build-and-push:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      packages: write
    
    steps:
      - name: Checkout code
        uses: actions/checkout@v4
      
      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3
      
      - name: Log in to Container Registry
        uses: docker/login-action@v3
        with:
          registry: ${{ env.REGISTRY }}
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}
      
      - name: Extract metadata
        id: meta
        uses: docker/metadata-action@v5
        with:
          images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
          tags: |
            type=ref,event=branch
            type=semver,pattern={{version}}
            type=semver,pattern={{major}}.{{minor}}
            type=sha
      
      - name: Build and push
        uses: docker/build-push-action@v5
        with:
          context: .
          push: true
          tags: ${{ steps.meta.outputs.tags }}
          labels: ${{ steps.meta.outputs.labels }}
          cache-from: type=gha
          cache-to: type=gha,mode=max

Use Case 3: Multi-Cloud Deployment

name: Multi-Cloud Deploy

on:
  workflow_dispatch:
    inputs:
      environment:
        type: choice
        description: 'Deployment environment'
        options:
          - staging
          - production
        required: true

jobs:
  deploy-aws:
    runs-on: ubuntu-latest
    environment: ${{ github.event.inputs.environment }}
    
    steps:
      - uses: actions/checkout@v4
      
      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v4
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-