Skip to content
Latchkey

CI workflow (spf13/viper)

The CI workflow from spf13/viper, explained and optimized by Latchkey.

C

CI health: C - fair

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

Grade your own workflow free or run it on Latchkey →
Source: spf13/viper.github/workflows/ci.yamlLicense MITView source

What it does

This is the CI workflow from the spf13/viper 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: CI

on:
  push:
    branches: [master]
  pull_request:

permissions:
  contents: read

jobs:
  build:
    name: Build
    runs-on: ubuntu-latest

    strategy:
      fail-fast: false
      matrix:
        include:
          - goos: js
            goarch: wasm
          - goos: aix
            goarch: ppc64

    steps:
      - name: Checkout repository
        uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2

      - name: Set up Go
        uses: actions/setup-go@3041bf56c941b39c61721a86cd11f3bb1338122a # v5.2.0
        with:
          go-version: "1.25"

      - name: Build
        run: go build .
        env:
          GOOS: ${{ matrix.goos }}
          GOARCH: ${{ matrix.goarch }}

  test:
    name: Test
    runs-on: ${{ matrix.os }}

    strategy:
      # Fail fast is disabled because there are Go version specific features and tests
      # that should be able to fail independently.
      fail-fast: false
      matrix:
        os: [ubuntu-latest, macos-latest, windows-latest]
        go: ["1.23", "1.24", "1.25"]
        tags: ["", "viper_finder", "viper_bind_struct"]

    steps:
      - name: Checkout repository
        uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2

      - name: Set up Go
        uses: actions/setup-go@3041bf56c941b39c61721a86cd11f3bb1338122a # v5.2.0
        with:
          go-version: ${{ matrix.go }}

      - name: Test
        run: go test -race -v -tags '${{ matrix.tags }}' -shuffle=on ./...
        if: runner.os != 'Windows'

      - name: Test (without race detector)
        run: go test -v -tags '${{ matrix.tags }}' -shuffle=on ./...
        if: runner.os == 'Windows'

  lint:
    name: Lint
    runs-on: ubuntu-latest

    steps:
      - name: Checkout repository
        uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2

      - name: Set up Go
        uses: actions/setup-go@3041bf56c941b39c61721a86cd11f3bb1338122a # v5.2.0
        with:
          go-version: "1.25"

      - name: Lint
        uses: golangci/golangci-lint-action@4afd733a84b1f43292c63897423277bb7f4313a9 # v8.0.0
        with:
          version: v2.4.0

  dev:
    name: Developer environment
    runs-on: ubuntu-latest

    steps:
      - name: Checkout repository
        uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2

      - name: Set up Nix
        uses: cachix/install-nix-action@3715ab1a11cac9e991980d7b4a28d80c7ebdd8f9 # v27
        with:
          extra_nix_config: |
            access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}

      - name: Check
        run: nix flake check --impure

      - name: Dev shell
        run: nix develop --impure

  dependency-review:
    name: Dependency review
    runs-on: ubuntu-latest
    if: github.event_name == 'pull_request'

    steps:
      - name: Checkout repository
        uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2

      - name: Dependency Review
        uses: actions/dependency-review-action@3b139cfc5fae8b618d3eae3675e383bb1769c019 # v4.5.0

The same workflow, on Latchkey

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

name: CI
 
on:
  push:
    branches: [master]
  pull_request:
 
permissions:
  contents: read
 
concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true
 
jobs:
  build:
    timeout-minutes: 30
    name: Build
    runs-on: latchkey-small
 
    strategy:
      fail-fast: false
      matrix:
        include:
          - goos: js
            goarch: wasm
          - goos: aix
            goarch: ppc64
 
    steps:
      - name: Checkout repository
        uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
 
      - name: Set up Go
        uses: actions/setup-go@3041bf56c941b39c61721a86cd11f3bb1338122a # v5.2.0
        with:
          go-version: "1.25"
 
      - name: Build
        run: go build .
        env:
          GOOS: ${{ matrix.goos }}
          GOARCH: ${{ matrix.goarch }}
 
  test:
    timeout-minutes: 30
    name: Test
    runs-on: ${{ matrix.os }}
 
    strategy:
      # Fail fast is disabled because there are Go version specific features and tests
      # that should be able to fail independently.
      fail-fast: false
      matrix:
        os: [ubuntu-latest, macos-latest, windows-latest]
        go: ["1.23", "1.24", "1.25"]
        tags: ["", "viper_finder", "viper_bind_struct"]
 
    steps:
      - name: Checkout repository
        uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
 
      - name: Set up Go
        uses: actions/setup-go@3041bf56c941b39c61721a86cd11f3bb1338122a # v5.2.0
        with:
          go-version: ${{ matrix.go }}
 
      - name: Test
        run: go test -race -v -tags '${{ matrix.tags }}' -shuffle=on ./...
        if: runner.os != 'Windows'
 
      - name: Test (without race detector)
        run: go test -v -tags '${{ matrix.tags }}' -shuffle=on ./...
        if: runner.os == 'Windows'
 
  lint:
    timeout-minutes: 30
    name: Lint
    runs-on: latchkey-small
 
    steps:
      - name: Checkout repository
        uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
 
      - name: Set up Go
        uses: actions/setup-go@3041bf56c941b39c61721a86cd11f3bb1338122a # v5.2.0
        with:
          go-version: "1.25"
 
      - name: Lint
        uses: golangci/golangci-lint-action@4afd733a84b1f43292c63897423277bb7f4313a9 # v8.0.0
        with:
          version: v2.4.0
 
  dev:
    timeout-minutes: 30
    name: Developer environment
    runs-on: latchkey-small
 
    steps:
      - name: Checkout repository
        uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
 
      - name: Set up Nix
        uses: cachix/install-nix-action@3715ab1a11cac9e991980d7b4a28d80c7ebdd8f9 # v27
        with:
          extra_nix_config: |
            access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
 
      - name: Check
        run: nix flake check --impure
 
      - name: Dev shell
        run: nix develop --impure
 
  dependency-review:
    timeout-minutes: 30
    name: Dependency review
    runs-on: latchkey-small
    if: github.event_name == 'pull_request'
 
    steps:
      - name: Checkout repository
        uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
 
      - name: Dependency Review
        uses: actions/dependency-review-action@3b139cfc5fae8b618d3eae3675e383bb1769c019 # v4.5.0
 

What changed

This workflow runs 5 jobs (31 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