Skip to content
Latchkey

release-binary-docker-images workflow (controlplaneio/simulator)

The release-binary-docker-images workflow from controlplaneio/simulator, 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: controlplaneio/simulator.github/workflows/release.yamlLicense Apache-2.0View source

What it does

This is the release-binary-docker-images workflow from the controlplaneio/simulator repository, a real project running GitHub Actions. It is shown here with attribution under its Apache-2.0 license.

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

The workflow

workflow (.yml)
name: release-binary-docker-images

on:
  push:
    tags:
      - "v[0-9]+.[0-9]+.[0-9]+"
      - "v2.0.0-alpha1"

permissions:
  contents: write

jobs:
  build-push-docker-images:
    runs-on: ubuntu-latest
    steps:
      - name: Cache container layers
        uses: actions/cache@v3
        with:
          path: /tmp/.buildx-cache
          key: ${{ runner.os }}${{ matrix.containers.suffix }}-buildx-${{ github.sha }}
          restore-keys: |
            ${{ runner.os }}${{ matrix.containers.suffix }}-buildx-

      - name: Checkout source code
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Set up QEMU
        uses: docker/setup-qemu-action@v3

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3

      - name: Login to Docker Hub
        uses: docker/login-action@v2
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}

      - name: Build and tag dev image
        uses: docker/build-push-action@v5
        with:
          context: .
          file: ./Dockerfile.dev
          tags: |
            controlplane/simulator:dev
          load: true
          push: false

      - name: Run Trivy vulnerability scanner on the dev image
        uses: aquasecurity/trivy-action@0.16.0
        with:
          image-ref: 'controlplane/simulator:dev'
          format: 'table'
          exit-code: '1'
          vuln-type: 'os,library'
          severity: 'CRITICAL,HIGH'
          trivyignores: './.trivy-config/.trivyignore'

      - name: Build and tag simulator image
        uses: docker/build-push-action@v5
        with:
          context: .
          file: ./Dockerfile
          tags: controlplane/simulator:${{ github.ref_name }}
          load: true
          push: false

      - name: Run Trivy vulnerability scanner on simulator image
        uses: aquasecurity/trivy-action@0.16.0
        with:
          image-ref: controlplane/simulator:${{ github.ref_name }}
          format: 'table'
          exit-code: '1'
          vuln-type: 'os,library'
          severity: 'CRITICAL,HIGH'
          trivyignores: './.trivy-config/.trivyignore'

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3
        with:
          platforms: linux/amd64,linux/arm64

      - name: Build and push dev image ## should use cache image from the previous step
        uses: docker/build-push-action@v5
        with:
          context: .
          file: ./Dockerfile.dev
          tags: 'controlplane/simulator:dev'
          load: false ## push and load cannot be set at the same time
          push: true

      - name: pull dev image
        run: |
          docker images ls
          docker pull controlplane/simulator:dev
          docker images ls

      - name: Build and push simulator image ## should use cache image from the previous step
        uses: docker/build-push-action@v5
        with:
          context: .
          file: ./Dockerfile
          tags: |
            controlplane/simulator:${{ github.ref_name }}
            controlplane/simulator:latest
          load: false
          push: true

  goreleaser:
    runs-on: ubuntu-latest
    name: goreleaser
    needs: build-push-docker-images
    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Setup Go
        uses: actions/setup-go@v4
        with:
          go-version-file: go.mod

      - run: go version

      - uses: anchore/sbom-action/download-syft@v0
      - name: Run GoReleaser
        uses: goreleaser/goreleaser-action@v5
        with:
          distribution: goreleaser
          args: release --clean
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

The same workflow, on Latchkey

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

name: release-binary-docker-images
 
on:
  push:
    tags:
      - "v[0-9]+.[0-9]+.[0-9]+"
      - "v2.0.0-alpha1"
 
permissions:
  contents: write
 
concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true
 
jobs:
  build-push-docker-images:
    timeout-minutes: 30
    runs-on: latchkey-small
    steps:
      - name: Cache container layers
        uses: actions/cache@v3
        with:
          path: /tmp/.buildx-cache
          key: ${{ runner.os }}${{ matrix.containers.suffix }}-buildx-${{ github.sha }}
          restore-keys: |
            ${{ runner.os }}${{ matrix.containers.suffix }}-buildx-
 
      - name: Checkout source code
        uses: actions/checkout@v4
        with:
          fetch-depth: 0
 
      - name: Set up QEMU
        uses: docker/setup-qemu-action@v3
 
      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3
 
      - name: Login to Docker Hub
        uses: docker/login-action@v2
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}
 
      - name: Build and tag dev image
        uses: docker/build-push-action@v5
        with:
          context: .
          file: ./Dockerfile.dev
          tags: |
            controlplane/simulator:dev
          load: true
          push: false
 
      - name: Run Trivy vulnerability scanner on the dev image
        uses: aquasecurity/trivy-action@0.16.0
        with:
          image-ref: 'controlplane/simulator:dev'
          format: 'table'
          exit-code: '1'
          vuln-type: 'os,library'
          severity: 'CRITICAL,HIGH'
          trivyignores: './.trivy-config/.trivyignore'
 
      - name: Build and tag simulator image
        uses: docker/build-push-action@v5
        with:
          context: .
          file: ./Dockerfile
          tags: controlplane/simulator:${{ github.ref_name }}
          load: true
          push: false
 
      - name: Run Trivy vulnerability scanner on simulator image
        uses: aquasecurity/trivy-action@0.16.0
        with:
          image-ref: controlplane/simulator:${{ github.ref_name }}
          format: 'table'
          exit-code: '1'
          vuln-type: 'os,library'
          severity: 'CRITICAL,HIGH'
          trivyignores: './.trivy-config/.trivyignore'
 
      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3
        with:
          platforms: linux/amd64,linux/arm64
 
      - name: Build and push dev image ## should use cache image from the previous step
        uses: docker/build-push-action@v5
        with:
          context: .
          file: ./Dockerfile.dev
          tags: 'controlplane/simulator:dev'
          load: false ## push and load cannot be set at the same time
          push: true
 
      - name: pull dev image
        run: |
          docker images ls
          docker pull controlplane/simulator:dev
          docker images ls
 
      - name: Build and push simulator image ## should use cache image from the previous step
        uses: docker/build-push-action@v5
        with:
          context: .
          file: ./Dockerfile
          tags: |
            controlplane/simulator:${{ github.ref_name }}
            controlplane/simulator:latest
          load: false
          push: true
 
  goreleaser:
    timeout-minutes: 30
    runs-on: latchkey-small
    name: goreleaser
    needs: build-push-docker-images
    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          fetch-depth: 0
 
      - name: Setup Go
        uses: actions/setup-go@v4
        with:
          go-version-file: go.mod
 
      - run: go version
 
      - uses: anchore/sbom-action/download-syft@v0
      - name: Run GoReleaser
        uses: goreleaser/goreleaser-action@v5
        with:
          distribution: goreleaser
          args: release --clean
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
 

What changed

7 third-party actions are referenced by a movable tag. Pin them to the commit SHA (Latchkey resolves and applies this automatically) so a repointed tag cannot change what runs.

What Latchkey heals here

This workflow has steps that commonly fail on transient issues (network, registries, flaky browsers). On Latchkey managed runners they are detected, retried, and self-healed instead of failing your build:

This workflow runs 2 jobs per trigger. On Latchkey the same minutes cost up to 58% less than GitHub-hosted, with zero queue time.

Actions used in this workflow