DEV Community

Huseyn
Huseyn

Posted on

GitHub Actions Cheatsheet and Workflow Analysis

GitHub Actions Cheatsheet

GitHub Actions is a CI/CD platform for automating tasks in GitHub repositories. Workflows are defined in YAML files stored in the .github/workflows/ directory. Below is a cheatsheet of all major components and their roles.

1. Workflow

  • Definition: A workflow is an automated process defined in a YAML file, containing one or more jobs triggered by events.
  • Key Attributes:
    • name: Workflow name displayed in the GitHub Actions UI.
    • on: Specifies events that trigger the workflow (e.g., push, pull_request, schedule).
    • jobs: Defines one or more jobs to execute.
    • env: Workflow-level environment variables.
    • concurrency: Controls concurrent workflow runs to prevent conflicts.
  • Example:
  name: CI Pipeline
  on:
    push:
      branches: [main]
  env:
    GLOBAL_VAR: value
Enter fullscreen mode Exit fullscreen mode

2. Events (on)

  • Definition: Events trigger workflows. Defined under the on key.
  • Common Triggers:
    • push: On code push to specified branches.
    • pull_request: On pull request actions (e.g., opened, synchronized).
    • schedule: Cron-based scheduling (e.g., 0 0 * * * for daily runs).
    • workflow_dispatch: Manual trigger via GitHub UI or API.
    • issue_comment, release, repository_dispatch, etc.
  • Example:
  on:
    push:
      branches: [main, dev/*]
    pull_request:
      branches: [main]
    schedule:
      - cron: '0 0 * * *'
Enter fullscreen mode Exit fullscreen mode

3. Jobs

  • Definition: A job is a set of tasks (steps) running on a single runner (virtual machine or container).
  • Key Attributes:
    • runs-on: Specifies the runner (e.g., ubuntu-latest, windows-latest, macos-latest, or self-hosted).
    • steps: List of tasks to execute.
    • needs: Defines job dependencies for sequential execution.
    • env: Job-level environment variables.
    • if: Conditional execution (e.g., if: github.event_name == 'push').
    • services: Defines Docker containers for external dependencies (e.g., databases).
    • strategy: For matrix builds (run job with multiple configurations, e.g., different Go versions).
  • Example:
  jobs:
    build:
      runs-on: ubuntu-latest
      needs: [test]
      steps: []
Enter fullscreen mode Exit fullscreen mode

4. Steps

  • Definition: Individual tasks within a job, executed sequentially on the same runner.
  • Key Attributes:
    • name: Step name for UI display.
    • uses: References an action (e.g., actions/checkout@v4).
    • run: Executes a shell command (e.g., npm install).
    • env: Step-level environment variables.
    • if: Conditional execution.
    • with: Inputs for actions.
    • id: Unique identifier for step outputs.
    • continue-on-error: Allows subsequent steps to run even if the step fails.
  • Example:
  steps:
    - name: Checkout
      uses: actions/checkout@v4
    - name: Run script
      run: echo "Hello, World!"
      env:
        MY_VAR: value
Enter fullscreen mode Exit fullscreen mode

5. Actions

  • Definition: Reusable units of code that perform specific tasks (e.g., checking out code, setting up environments).
  • Key Attributes:
    • Hosted in GitHub Marketplace or custom repositories.
    • Used via uses (e.g., uses: actions/setup-go@v5).
    • Supports inputs (with) and outputs.
  • Example:
  - uses: actions/setup-go@v5
    with:
      go-version: '1.21'
Enter fullscreen mode Exit fullscreen mode

6. Services

  • Definition: Docker containers running alongside a job to provide dependencies (e.g., databases, caches).
  • Key Attributes:
    • Defined under jobs.<job_id>.services.
    • Specifies image, ports, env, and options (e.g., health checks).
    • Accessible via localhost or service name.
  • Example:
  services:
    redis:
      image: redis:latest
      ports:
        - 6379:6379
Enter fullscreen mode Exit fullscreen mode

Checkout the PPT . Credit goes to: TechSchool

7. Runners

  • Definition: Virtual machines or containers that execute jobs.
  • Types:
    • GitHub-hosted: ubuntu-latest, windows-latest, macos-latest.
    • Self-hosted: Custom runners on your infrastructure.
  • Example:
  runs-on: ubuntu-latest
Enter fullscreen mode Exit fullscreen mode

8. Environment Variables

  • Definition: Variables available to steps, jobs, or workflows.
  • Levels: Workflow (env), job (env), step (env).
  • Secrets: Securely stored variables accessed via ${{ secrets.NAME }}.
  • Example:
  env:
    API_KEY: ${{ secrets.API_KEY }}
Enter fullscreen mode Exit fullscreen mode

9. Matrix Strategy

  • Definition: Runs a job multiple times with different configurations (e.g., multiple versions of a language).
  • Key Attributes:
    • strategy.matrix: Defines variables (e.g., go-version: ['1.21', '1.22']).
    • strategy.fail-fast: Stops matrix on first failure (default: true).
  • Example:
  strategy:
    matrix:
      go-version: ['1.21', '1.22']
Enter fullscreen mode Exit fullscreen mode

10. Artifacts and Outputs

  • Artifacts: Files stored after a job (e.g., build outputs).
    • Use actions/upload-artifact@v4 and actions/download-artifact@v4.
  • Outputs: Data passed between steps or jobs via ::set-output.
  • Example:
  - name: Upload artifact
    uses: actions/upload-artifact@v4
    with:
      name: my-artifact
      path: ./build/
Enter fullscreen mode Exit fullscreen mode

11. Concurrency and Permissions

  • Concurrency: Prevents multiple workflow runs from conflicting.
    • Use concurrency.group and concurrency.cancel-in-progress.
  • Permissions: Control workflow access to repository resources.
    • Use permissions (e.g., contents: read).
  • Example:
  concurrency:
    group: ${{ github.workflow }}-${{ github.ref }}
    cancel-in-progress: true
  permissions:
    contents: write
Enter fullscreen mode Exit fullscreen mode

12. Common Actions

  • actions/checkout@v4: Clones the repository.
  • actions/setup-<language>@vX: Sets up languages (e.g., setup-go, setup-node).
  • actions/upload-artifact@v4: Uploads files.
  • actions/download-artifact@v4: Downloads files.
  • actions/cache@v4: Caches dependencies for faster builds.

13. Expressions and Contexts

  • Expressions: Use ${{ <expression> }} for dynamic values (e.g., ${{ github.sha }}).
  • Contexts: Predefined objects like github, env, secrets, matrix.
  • Example:
  if: ${{ github.event_name == 'push' }}
Enter fullscreen mode Exit fullscreen mode

14. Best Practices

  • Use specific action versions (e.g., @v4 instead of @main).
  • Store sensitive data in GitHub Secrets.
  • Break workflows into modular jobs for clarity.
  • Use continue-on-error for non-critical steps.
  • Leverage caching to speed up workflows (actions/cache@v4).

For more details, see the GitHub Actions Documentation.

Analysis of the Provided Go Workflow YAML

The provided YAML file defines a GitHub Actions workflow named unit-test for a Go project with a PostgreSQL database. Below is a detailed breakdown of the workflow, referencing the cheatsheet components.

YAML File

# This workflow will build a golang project
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-go

name: unit-test

on:
  push:
    branches: ["main", "dev/sajjad/users"]
  pull_request:
    branches: ["main"]

jobs:
  test:
    name: Test
    runs-on: ubuntu-latest

    services:
      postgres:
        image: postgres:latest
        # Provide the password for postgres
        env:
          POSTGRES_USER: root
          POSTGRES_PASSWORD: root
          POSTGRES_DB: simple_bank
        ports:
          - 5432:5432
        options: >-
          --health-cmd pg_isready
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5

    steps:
      - name: Set up Go
        uses: actions/setup-go@v4
        with:
          go-version: "1.24.3"

      - name: Check out code to runner
        uses: actions/checkout@v4

      - name: Install go-migrate
        run: |
          $ curl -L https://github.com/golang-migrate/migrate/releases/download/v4.18.3/migrate.linux-amd64.tar.gz | tar xvz
          sudo mv migrate.linux-amd64 /usr/bin/migrate
          which Migrate

      - name: Run migrations
        run: make migrateup

      - name: Test
        run: make test
Enter fullscreen mode Exit fullscreen mode

Component Breakdown

  1. Workflow:

    • Name: unit-test
    • Purpose: Automates unit testing for a Go project with a PostgreSQL database.
    • File Location: Stored in .github/workflows/ (not specified in the YAML but implied).
  2. Events (on):

    • Triggers:
      • push: branches: ["main", "dev/sajjad/users"]: Runs on pushes to the main branch and the dev/sajjad/users branch.
      • pull_request: branches: ["main"]: Runs on pull requests targeting the main branch.
    • Explanation: This ensures the workflow runs for code changes to specific branches and pull requests, supporting both development and production workflows.
  3. Jobs:

    • Job Name: test
    • Runner: runs-on: ubuntu-latest
      • Uses a GitHub-hosted Ubuntu virtual machine (latest version).
    • Purpose: Executes the test-related tasks for the Go project.
  4. Services:

    • Service Name: postgres
    • Configuration:
      • image: postgres:latest: Uses the latest PostgreSQL Docker image.
      • env:
      • POSTGRES_USER: root: Database user.
      • POSTGRES_PASSWORD: root: Database password.
      • POSTGRES_DB: simple_bank: Database name.
      • ports: - 5432:5432: Maps port 5432 for access via localhost:5432.
      • options: Health checks ensure the database is ready:
      • --health-cmd pg_isready: Checks if PostgreSQL is accepting connections.
      • --health-interval 10s, --health-timeout 5s, --health-retries 5: Retries 5 times every 10 seconds with a 5-second timeout.
    • Explanation: The PostgreSQL service provides a database for testing and migrations, accessible by the job’s steps.
  5. Steps:

    • Step 1: Set up Go
      • uses: actions/setup-go@v4
      • with: go-version: "1.24.3": Installs Go version 1.24.3.
      • Explanation: Sets up the Go environment required for building and testing.
    • Step 2: Check out code to runner
      • uses: actions/checkout@v4
      • Explanation: Clones the repository to the runner, making the code available for subsequent steps.
    • Step 3: Install go-migrate
      • run: Downloads and installs go-migrate分散
       curl -L https://github.com/golang-migrate/migrate/releases/download/v4.18.3/migrate.linux-amd64.tar.gz | tar xvz
       sudo mv migrate.linux-amd64 /usr/bin/migrate
       which Migrate
    
 - **Explanation**: Installs the `go-migrate` CLI (version 4.18.3) to manage database migrations.
Enter fullscreen mode Exit fullscreen mode
  • Step 4: Run migrations
    • run: make migrateup
    • Explanation: Runs the migrateup Makefile target to apply database migrations to the PostgreSQL database.
  • Step 5: Test
    • run: make test
    • Explanation: Runs the test Makefile target to execute the Go tests, likely using the PostgreSQL database.

How the Workflow Works

  1. Trigger: The workflow runs on:
    • Pushes to the main or dev/sajjad/users branches.
    • Pull requests targeting the main branch.
  2. Runner Setup: An ubuntu-latest virtual machine is provisioned.
  3. Service Startup: The postgres service starts a PostgreSQL container with the simple_bank database, accessible at localhost:5432.
  4. Step Execution:
    • Installs Go 1.24.3.
    • Clones the repository.
    • Installs the go-migrate CLI.
    • Runs database migrations using make migrateup.
    • Executes tests using make test.
  5. Completion: The workflow completes, marking success or failure in the GitHub Actions UI. The PostgreSQL container is terminated.

Key Notes

  • Makefile Integration: The workflow uses make commands (migrateup, test), indicating the project has a Makefile to simplify task execution.
  • Security: Hardcoded POSTGRES_USER and POSTGRES_PASSWORD (root) are used for simplicity. In production, use GitHub Secrets for sensitive data.
  • Health Checks: The PostgreSQL service uses health checks to ensure readiness, preventing steps from running before the database is available.
  • Potential Improvement: The go-migrate installation command has an extra $ before curl, which may cause errors. It should be:
  curl -L https://github.com/golang-migrate/migrate/releases/download/v4.18.3/migrate.linux-amd64.tar.gz | tar xvz
Enter fullscreen mode Exit fullscreen mode

Additional Tips for This Workflow

  • Add Environment Variables: Explicitly define DATABASE_URL for clarity:
  env:
    DATABASE_URL: postgres://root:root@localhost:5432/simple_bank?sslmode=disable
Enter fullscreen mode Exit fullscreen mode

in the Run migrations and Test steps.

  • Caching: Use actions/cache@v4 to cache Go modules for faster builds:
  - name: Cache Go modules
    uses: actions/cache@v4
    with:
      path: ~/go/pkg/mod
      key: ${{ runner.os }}-go-${{ hashFiles('**/go.mod') }}
Enter fullscreen mode Exit fullscreen mode
  • Matrix Testing: Test multiple Go versions:
  strategy:
    matrix:
      go-version: ['1.21', '1.22', '1.24.3']
Enter fullscreen mode Exit fullscreen mode

For further customization, refer to the GitHub Actions Documentation and go-migrate Documentation.

Top comments (0)