Skip to content
Latchkey

Release workflow (go-delve/delve)

The Release workflow from go-delve/delve, explained and optimized by Latchkey.

B

CI health: B - good

Point runs-on at Latchkey and get 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: go-delve/delve.github/workflows/release.ymlLicense MITView source

What it does

This is the Release workflow from the go-delve/delve 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: Release

on:
  push:
    tags:
      - 'v*'
  workflow_dispatch:
    inputs:
      tag:
        description: 'Git tag to release (e.g. v1.24.0). Required for non-dry-run releases.'
        type: string
        required: false
      dry_run:
        description: 'Dry run only (snapshot build, not published to GitHub Releases)'
        type: boolean
        default: true

# Cancel in-progress runs for the same ref.
concurrency:
  group: "${{ github.ref }}-release"
  cancel-in-progress: false

permissions:
  contents: write   # create GitHub Release and upload assets
  id-token: write   # cosign OIDC for keyless signing

jobs:
  release:
    runs-on: ubuntu-latest
    steps:
      - name: Validate tag input
        if: github.event_name == 'workflow_dispatch' && inputs.dry_run == false && inputs.tag == ''
        run: |
          echo "::error::A tag must be specified for non-dry-run releases"
          exit 1

      - name: Checkout
        uses: actions/checkout@v4
        with:
          fetch-depth: 0  # full history required for goreleaser release notes
          ref: ${{ inputs.tag || github.ref }}

      - name: Set up Go
        uses: actions/setup-go@v5
        with:
          go-version: stable

      - name: Install cosign
        uses: sigstore/cosign-installer@v3

      - name: Run goreleaser (release)
        if: github.event_name == 'push' || (github.event_name == 'workflow_dispatch' && inputs.dry_run == false)
        uses: goreleaser/goreleaser-action@v6
        with:
          version: ~> v2
          args: release --clean
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          GORELEASER_CURRENT_TAG: ${{ inputs.tag || github.ref_name }}

      - name: Run goreleaser (snapshot)
        if: github.event_name == 'workflow_dispatch' && inputs.dry_run == true
        uses: goreleaser/goreleaser-action@v6
        with:
          version: ~> v2
          args: release --snapshot --clean
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

      - name: Upload snapshot artifacts
        if: github.event_name == 'workflow_dispatch' && inputs.dry_run == true
        uses: actions/upload-artifact@v4
        with:
          name: snapshot-dist
          path: dist/
          retention-days: 7

The same workflow, on Latchkey

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

name: Release
 
on:
  push:
    tags:
      - 'v*'
  workflow_dispatch:
    inputs:
      tag:
        description: 'Git tag to release (e.g. v1.24.0). Required for non-dry-run releases.'
        type: string
        required: false
      dry_run:
        description: 'Dry run only (snapshot build, not published to GitHub Releases)'
        type: boolean
        default: true
 
# Cancel in-progress runs for the same ref.
concurrency:
  group: "${{ github.ref }}-release"
  cancel-in-progress: false
 
permissions:
  contents: write   # create GitHub Release and upload assets
  id-token: write   # cosign OIDC for keyless signing
 
jobs:
  release:
    timeout-minutes: 30
    runs-on: latchkey-small
    steps:
      - name: Validate tag input
        if: github.event_name == 'workflow_dispatch' && inputs.dry_run == false && inputs.tag == ''
        run: |
          echo "::error::A tag must be specified for non-dry-run releases"
          exit 1
 
      - name: Checkout
        uses: actions/checkout@v4
        with:
          fetch-depth: 0  # full history required for goreleaser release notes
          ref: ${{ inputs.tag || github.ref }}
 
      - name: Set up Go
        uses: actions/setup-go@v5
        with:
          go-version: stable
 
      - name: Install cosign
        uses: sigstore/cosign-installer@v3
 
      - name: Run goreleaser (release)
        if: github.event_name == 'push' || (github.event_name == 'workflow_dispatch' && inputs.dry_run == false)
        uses: goreleaser/goreleaser-action@v6
        with:
          version: ~> v2
          args: release --clean
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          GORELEASER_CURRENT_TAG: ${{ inputs.tag || github.ref_name }}
 
      - name: Run goreleaser (snapshot)
        if: github.event_name == 'workflow_dispatch' && inputs.dry_run == true
        uses: goreleaser/goreleaser-action@v6
        with:
          version: ~> v2
          args: release --snapshot --clean
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
 
      - name: Upload snapshot artifacts
        if: github.event_name == 'workflow_dispatch' && inputs.dry_run == true
        uses: actions/upload-artifact@v4
        with:
          name: snapshot-dist
          path: dist/
          retention-days: 7
 

What changed

2 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.

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

Actions used in this workflow