Skip to content
Latchkey

Test workflow (rubenv/sql-migrate)

The Test workflow from rubenv/sql-migrate, explained and optimized by Latchkey.

C

CI health: C - fair

Point runs-on at Latchkey and get run de-duplication, job timeouts, SHA-pinned actions, self-healing for flaky steps, and up to 58% lower cost, applied automatically.

Grade your own workflow free or run it on Latchkey →
Source: rubenv/sql-migrate.github/workflows/test.ymlLicense MITView source

What it does

This is the Test workflow from the rubenv/sql-migrate repository, a real project running GitHub Actions. It is shown here with attribution under its MIT license.

Below, Latchkey shows a faster, safer version produced by its optimization engine.

The workflow

workflow (.yml)
name: Test
on:
  push:
    branches:
      - master
  pull_request:
jobs:
  test:
    strategy:
      fail-fast: true
      matrix:
        go-version: ["1.23", "1.24"]
    runs-on: ubuntu-latest
    steps:
      - name: checkout
        uses: actions/checkout@v4
      - name: setup-go
        uses: actions/setup-go@v5
        with:
          go-version: ${{ matrix.go-version }}
          cache: true
          cache-dependency-path: go.sum
      - name: go build
        run: go build -o ./bin/sql-migrate ./sql-migrate && ./bin/sql-migrate --help
      - name: go test
        run: go test ./...
  lint:
    runs-on: ubuntu-latest
    steps:
      - name: checkout
        uses: actions/checkout@v4
      - name: setup-go
        uses: actions/setup-go@v5
        with:
          go-version: "1.24"
          cache: true
          cache-dependency-path: go.sum
      - name: golangci-lint
        uses: golangci/golangci-lint-action@v7
        with:
          version: v2.1
      - name: go mod tidy
        run: go mod tidy
      - name: check for any changes
        run: |
          [[ $(git status --porcelain) == "" ]] || (echo "changes detected" && exit 1)
  integration:
    needs:
      - test
      - lint
    runs-on: ubuntu-latest
    strategy:
      fail-fast: true
      matrix:
        go-version: ["1.23", "1.24"]
    services:
      mysql:
        image: mysql:8.0
        env:
          MYSQL_ALLOW_EMPTY_PASSWORD: "1"
          MYSQL_ROOT_PASSWORD: ""
          MYSQL_DATABASE: "test"
        ports:
          - 3306:3306
        options: >-
          --health-cmd="mysqladmin ping"
          --health-interval=10s
          --health-timeout=5s
          --health-retries=3
      postgres:
        image: postgres:15
        env:
          POSTGRES_PASSWORD: "password"
        ports:
          - 5432:5432
        options: >-
          --health-cmd pg_isready
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5
    env:
      MYSQL_HOST: "127.0.0.1"
      PGHOST: "127.0.0.1"
      PGUSER: "postgres"
      PGPASSWORD: "password"
    steps:
      - name: checkout
        uses: actions/checkout@v4
      - name: setup-go
        uses: actions/setup-go@v5
        with:
          go-version: ${{ matrix.go-version }}
          cache: true
          cache-dependency-path: go.sum
      - name: setup databases
        run: |
          mysql --user=root -e 'CREATE DATABASE IF NOT EXISTS test;'
          mysql --user=root -e 'CREATE DATABASE IF NOT EXISTS test_env;'
          psql -U postgres -c 'CREATE DATABASE test;'
      - name: install sql-migrate
        run: go install ./...
      - name: postgres
        run: bash ./test-integration/postgres.sh
      - name: mysql
        run: bash ./test-integration/mysql.sh
      - name: mysql-flag
        run: bash ./test-integration/mysql-flag.sh
      - name: mysql-env
        run: bash ./test-integration/mysql-env.sh
      - name: sqlite
        run: bash ./test-integration/sqlite.sh

The same workflow, on Latchkey

Removes redundant runs and caps runaway jobs. Added and changed lines are highlighted.

name: Test
on:
  push:
    branches:
      - master
  pull_request:
concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true
 
jobs:
  test:
    timeout-minutes: 30
    strategy:
      fail-fast: true
      matrix:
        go-version: ["1.23", "1.24"]
    runs-on: latchkey-small
    steps:
      - name: checkout
        uses: actions/checkout@v4
      - name: setup-go
        uses: actions/setup-go@v5
        with:
          go-version: ${{ matrix.go-version }}
          cache: true
          cache-dependency-path: go.sum
      - name: go build
        run: go build -o ./bin/sql-migrate ./sql-migrate && ./bin/sql-migrate --help
      - name: go test
        run: go test ./...
  lint:
    timeout-minutes: 30
    runs-on: latchkey-small
    steps:
      - name: checkout
        uses: actions/checkout@v4
      - name: setup-go
        uses: actions/setup-go@v5
        with:
          go-version: "1.24"
          cache: true
          cache-dependency-path: go.sum
      - name: golangci-lint
        uses: golangci/golangci-lint-action@v7
        with:
          version: v2.1
      - name: go mod tidy
        run: go mod tidy
      - name: check for any changes
        run: |
          [[ $(git status --porcelain) == "" ]] || (echo "changes detected" && exit 1)
  integration:
    timeout-minutes: 30
    needs:
      - test
      - lint
    runs-on: latchkey-small
    strategy:
      fail-fast: true
      matrix:
        go-version: ["1.23", "1.24"]
    services:
      mysql:
        image: mysql:8.0
        env:
          MYSQL_ALLOW_EMPTY_PASSWORD: "1"
          MYSQL_ROOT_PASSWORD: ""
          MYSQL_DATABASE: "test"
        ports:
          - 3306:3306
        options: >-
          --health-cmd="mysqladmin ping"
          --health-interval=10s
          --health-timeout=5s
          --health-retries=3
      postgres:
        image: postgres:15
        env:
          POSTGRES_PASSWORD: "password"
        ports:
          - 5432:5432
        options: >-
          --health-cmd pg_isready
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5
    env:
      MYSQL_HOST: "127.0.0.1"
      PGHOST: "127.0.0.1"
      PGUSER: "postgres"
      PGPASSWORD: "password"
    steps:
      - name: checkout
        uses: actions/checkout@v4
      - name: setup-go
        uses: actions/setup-go@v5
        with:
          go-version: ${{ matrix.go-version }}
          cache: true
          cache-dependency-path: go.sum
      - name: setup databases
        run: |
          mysql --user=root -e 'CREATE DATABASE IF NOT EXISTS test;'
          mysql --user=root -e 'CREATE DATABASE IF NOT EXISTS test_env;'
          psql -U postgres -c 'CREATE DATABASE test;'
      - name: install sql-migrate
        run: go install ./...
      - name: postgres
        run: bash ./test-integration/postgres.sh
      - name: mysql
        run: bash ./test-integration/mysql.sh
      - name: mysql-flag
        run: bash ./test-integration/mysql-flag.sh
      - name: mysql-env
        run: bash ./test-integration/mysql-env.sh
      - name: sqlite
        run: bash ./test-integration/sqlite.sh
 

What changed

1 third-party action is referenced by a movable tag. Pin it to the commit SHA (Latchkey resolves and applies this automatically) so a repointed tag cannot change what runs.

This workflow runs 3 jobs (5 with the matrix expanded) per trigger. On Latchkey the same minutes cost up to 58% less than GitHub-hosted, with zero queue time.

Actions used in this workflow