Skip to content
Latchkey

Core Build and Release workflow (SurgeDM/Surge)

The Core Build and Release workflow from SurgeDM/Surge, 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: SurgeDM/Surge.github/workflows/core-build.ymlLicense MITView source

What it does

This is the Core Build and Release workflow from the SurgeDM/Surge 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: Core Build and Release

on:
  push:
    branches:
      - main
    tags:
      - "v*"
      - "!ext-v*"
  pull_request:
    branches:
      - main
    paths-ignore:
      - "extension/**"

permissions:
  contents: write
  pull-requests: write

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

jobs:
  test:
    name: Test and Check (${{ matrix.os }})
    strategy:
      fail-fast: false
      matrix:
        os: [ubuntu-latest, macos-latest, windows-latest]
    runs-on: ${{ matrix.os }}
    steps:
      - uses: actions/checkout@v4
      - name: Set up Go
        uses: actions/setup-go@v5
        with:
          go-version: "1.25.0"
          check-latest: false
      - name: Install gotestsum
        run: go install gotest.tools/gotestsum@latest
      - name: Build
        shell: bash
        run: go build -v ./...

      - name: Test
        shell: bash
        run: |
          cover_arg=""
          if [ "$RUNNER_OS" = "Linux" ]; then
            cover_arg="-coverprofile=coverage.out"
          fi
          gotestsum --junitfile test-results.xml --format testdox -- -race $cover_arg ./...
      - name: Comment Test Failures
        if: always() && github.event_name == 'pull_request'
        uses: actions/github-script@v7
        with:
          script: |
            const fs = require('fs');
            const signature = '<!-- core-build-test-failures-${{ matrix.os }} -->';
            
            // 1. Delete previous comments
            try {
              const comments = await github.paginate(github.rest.issues.listComments, {
                issue_number: context.issue.number,
                owner: context.repo.owner,
                repo: context.repo.repo,
              });
              
              for (const comment of comments) {
                if (comment.user?.type === 'Bot' && comment.body.includes(signature)) {
                  await github.rest.issues.deleteComment({
                    comment_id: comment.id,
                    owner: context.repo.owner,
                    repo: context.repo.repo,
                  });
                }
              }
            } catch (err) {
              core.warning(`Could not delete old comments: ${err.message}`);
            }

            // 2. Post new comment if there are failures
            if (!fs.existsSync('test-results.xml')) return;
            const content = fs.readFileSync('test-results.xml', 'utf8');
            const regex = /<testcase classname="([^"]+)" name="([^"]+)"[^>]*>\s*<(?:failure|error)/g;
            let match;
            const failures = [];
            while ((match = regex.exec(content)) !== null) {
              failures.push(`- **${match[1]}**: \`${match[2]}\``);
            }
            if (failures.length > 0) {
              const body = `${signature}\n### ❌ Test Failures on \`${{ matrix.os }}\`\n` + failures.join('\n');
              try {
                await github.rest.issues.createComment({
                  issue_number: context.issue.number,
                  owner: context.repo.owner,
                  repo: context.repo.repo,
                  body: body
                });
              } catch (err) {
                // Fork PRs have a read-only token; log but don't fail the step.
                core.warning(`Could not post comment (fork PR?): ${err.message}`);
              }
            }
      - name: Upload coverage reports to Codecov
        uses: codecov/codecov-action@v5
        if: matrix.os == 'ubuntu-latest' && success() && hashFiles('coverage.out') != ''
        with:
          token: ${{ secrets.CODECOV_TOKEN }}

  release:
    name: Release
    runs-on: ubuntu-latest
    needs: test
    # Extra guard: only core tags (v*), never extension tags (ext-v*)
    if: startsWith(github.ref, 'refs/tags/v') && !startsWith(github.ref, 'refs/tags/ext-v')
    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          fetch-depth: 0
      - name: Set up Go
        uses: actions/setup-go@v5
        with:
          go-version: "1.25.0"
      - name: Run GoReleaser
        uses: goreleaser/goreleaser-action@v6
        with:
          distribution: goreleaser-pro
          version: latest
          args: release --clean
        env:
          GORELEASER_KEY: ${{ secrets.GORELEASER_KEY }}
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          HOMEBREW_TAP_GITHUB_TOKEN: ${{ secrets.HOMEBREW_TAP_GITHUB_TOKEN }}

The same workflow, on Latchkey

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

name: Core Build and Release
 
on:
  push:
    branches:
      - main
    tags:
      - "v*"
      - "!ext-v*"
  pull_request:
    branches:
      - main
    paths-ignore:
      - "extension/**"
 
permissions:
  contents: write
  pull-requests: write
 
concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true
 
jobs:
  test:
    timeout-minutes: 30
    name: Test and Check (${{ matrix.os }})
    strategy:
      fail-fast: false
      matrix:
        os: [ubuntu-latest, macos-latest, windows-latest]
    runs-on: ${{ matrix.os }}
    steps:
      - uses: actions/checkout@v4
      - name: Set up Go
        uses: actions/setup-go@v5
        with:
          go-version: "1.25.0"
          check-latest: false
      - name: Install gotestsum
        run: go install gotest.tools/gotestsum@latest
      - name: Build
        shell: bash
        run: go build -v ./...
 
      - name: Test
        shell: bash
        run: |
          cover_arg=""
          if [ "$RUNNER_OS" = "Linux" ]; then
            cover_arg="-coverprofile=coverage.out"
          fi
          gotestsum --junitfile test-results.xml --format testdox -- -race $cover_arg ./...
      - name: Comment Test Failures
        if: always() && github.event_name == 'pull_request'
        uses: actions/github-script@v7
        with:
          script: |
            const fs = require('fs');
            const signature = '<!-- core-build-test-failures-${{ matrix.os }} -->';
            
            // 1. Delete previous comments
            try {
              const comments = await github.paginate(github.rest.issues.listComments, {
                issue_number: context.issue.number,
                owner: context.repo.owner,
                repo: context.repo.repo,
              });
              
              for (const comment of comments) {
                if (comment.user?.type === 'Bot' && comment.body.includes(signature)) {
                  await github.rest.issues.deleteComment({
                    comment_id: comment.id,
                    owner: context.repo.owner,
                    repo: context.repo.repo,
                  });
                }
              }
            } catch (err) {
              core.warning(`Could not delete old comments: ${err.message}`);
            }
 
            // 2. Post new comment if there are failures
            if (!fs.existsSync('test-results.xml')) return;
            const content = fs.readFileSync('test-results.xml', 'utf8');
            const regex = /<testcase classname="([^"]+)" name="([^"]+)"[^>]*>\s*<(?:failure|error)/g;
            let match;
            const failures = [];
            while ((match = regex.exec(content)) !== null) {
              failures.push(`- **${match[1]}**: \`${match[2]}\``);
            }
            if (failures.length > 0) {
              const body = `${signature}\n### ❌ Test Failures on \`${{ matrix.os }}\`\n` + failures.join('\n');
              try {
                await github.rest.issues.createComment({
                  issue_number: context.issue.number,
                  owner: context.repo.owner,
                  repo: context.repo.repo,
                  body: body
                });
              } catch (err) {
                // Fork PRs have a read-only token; log but don't fail the step.
                core.warning(`Could not post comment (fork PR?): ${err.message}`);
              }
            }
      - name: Upload coverage reports to Codecov
        uses: codecov/codecov-action@v5
        if: matrix.os == 'ubuntu-latest' && success() && hashFiles('coverage.out') != ''
        with:
          token: ${{ secrets.CODECOV_TOKEN }}
 
  release:
    timeout-minutes: 30
    name: Release
    runs-on: latchkey-small
    needs: test
    # Extra guard: only core tags (v*), never extension tags (ext-v*)
    if: startsWith(github.ref, 'refs/tags/v') && !startsWith(github.ref, 'refs/tags/ext-v')
    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          fetch-depth: 0
      - name: Set up Go
        uses: actions/setup-go@v5
        with:
          go-version: "1.25.0"
      - name: Run GoReleaser
        uses: goreleaser/goreleaser-action@v6
        with:
          distribution: goreleaser-pro
          version: latest
          args: release --clean
        env:
          GORELEASER_KEY: ${{ secrets.GORELEASER_KEY }}
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          HOMEBREW_TAP_GITHUB_TOKEN: ${{ secrets.HOMEBREW_TAP_GITHUB_TOKEN }}
 

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 2 jobs (4 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