Skip to content
Latchkey

Build Binaries workflow (gnmyt/MySpeed)

The Build Binaries workflow from gnmyt/MySpeed, 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: gnmyt/MySpeed.github/workflows/build-binaries.ymlLicense MITView source

What it does

This is the Build Binaries workflow from the gnmyt/MySpeed 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: Build Binaries

on:
  workflow_call:
    inputs:
      version:
        required: true
        type: string
      release_id:
        required: true
        type: string

jobs:
  build-windows:
    name: "Windows (x64)"
    runs-on: windows-latest
    steps:
      - name: Checkout project
        uses: actions/checkout@v4

      - name: Setup Bun
        uses: oven-sh/setup-bun@v2
        with:
          bun-version: latest

      - name: Install client dependencies
        working-directory: client
        run: bun install

      - name: Build client
        working-directory: client
        run: bun run build

      - name: Move build folder
        run: Move-Item -Path client/build -Destination .

      - name: Install server dependencies
        run: bun install

      - name: Generate migrations
        run: bun run generate-migrations

      - name: Generate integrations
        run: bun run generate-integrations

      - name: Generate client embed
        run: bun run generate-client-embed

      - name: Compile binary
        run: bun build --compile --compile-autoload-package-json --external pg-hstore --external pg --target=bun-windows-x64 server/index.js --outfile MySpeed.exe

      - name: Upload to Release
        uses: actions/github-script@v7
        with:
          script: |
            const fs = require('fs');
            await github.rest.repos.uploadReleaseAsset({
              owner: context.repo.owner,
              repo: context.repo.repo,
              release_id: ${{ inputs.release_id }},
              name: 'MySpeed-windows-x64.exe',
              data: fs.readFileSync('MySpeed.exe')
            });

      - name: Upload artifact for MSI
        uses: actions/upload-artifact@v4
        with:
          name: MySpeed-windows-x64.exe
          path: MySpeed.exe

      - name: Upload build folder for MSI
        uses: actions/upload-artifact@v4
        with:
          name: build-folder
          path: build

  build-linux:
    name: "Linux (${{ matrix.arch }})"
    runs-on: ${{ matrix.runner }}
    strategy:
      fail-fast: false
      matrix:
        include:
          - arch: x64
            target: bun-linux-x64
            runner: ubuntu-latest
            artifact_name: MySpeed-linux-x64
          - arch: arm64
            target: bun-linux-arm64
            runner: ubuntu-24.04-arm
            artifact_name: MySpeed-linux-arm64

    steps:
      - name: Checkout project
        uses: actions/checkout@v4

      - name: Setup Bun
        uses: oven-sh/setup-bun@v2
        with:
          bun-version: latest

      - name: Install client dependencies
        working-directory: client
        run: bun install

      - name: Build client
        working-directory: client
        run: bun run build

      - name: Move build folder
        run: mv client/build .

      - name: Install server dependencies
        run: bun install

      - name: Generate migrations
        run: bun run generate-migrations

      - name: Generate integrations
        run: bun run generate-integrations

      - name: Generate client embed
        run: bun run generate-client-embed

      - name: Compile binary
        run: bun build --compile --compile-autoload-package-json --external pg-hstore --external pg --target=${{ matrix.target }} server/index.js --outfile MySpeed

      - name: Rename binary
        run: mv MySpeed ${{ matrix.artifact_name }}

      - name: Upload to Release
        uses: actions/github-script@v7
        with:
          script: |
            const fs = require('fs');
            await github.rest.repos.uploadReleaseAsset({
              owner: context.repo.owner,
              repo: context.repo.repo,
              release_id: ${{ inputs.release_id }},
              name: '${{ matrix.artifact_name }}',
              data: fs.readFileSync('${{ matrix.artifact_name }}')
            });

  build-macos:
    name: "macOS (${{ matrix.arch }})"
    runs-on: macos-latest
    strategy:
      fail-fast: false
      matrix:
        include:
          - arch: x64
            target: bun-darwin-x64
            artifact_name: MySpeed-macos-x64
          - arch: arm64
            target: bun-darwin-arm64
            artifact_name: MySpeed-macos-arm64

    steps:
      - name: Checkout project
        uses: actions/checkout@v4

      - name: Setup Bun
        uses: oven-sh/setup-bun@v2
        with:
          bun-version: latest

      - name: Install client dependencies
        working-directory: client
        run: bun install

      - name: Build client
        working-directory: client
        run: bun run build

      - name: Move build folder
        run: mv client/build .

      - name: Install server dependencies
        run: bun install

      - name: Generate migrations
        run: bun run generate-migrations

      - name: Generate integrations
        run: bun run generate-integrations

      - name: Generate client embed
        run: bun run generate-client-embed

      - name: Compile binary
        run: bun build --compile --compile-autoload-package-json --external pg-hstore --external pg --target=${{ matrix.target }} server/index.js --outfile MySpeed

      - name: Rename binary
        run: mv MySpeed ${{ matrix.artifact_name }}

      - name: Upload to Release
        uses: actions/github-script@v7
        with:
          script: |
            const fs = require('fs');
            await github.rest.repos.uploadReleaseAsset({
              owner: context.repo.owner,
              repo: context.repo.repo,
              release_id: ${{ inputs.release_id }},
              name: '${{ matrix.artifact_name }}',
              data: fs.readFileSync('${{ matrix.artifact_name }}')
            });

  build-zip:
    name: "Source ZIP"
    runs-on: ubuntu-latest
    steps:
      - name: Checkout project
        uses: actions/checkout@v4

      - name: Setup Bun
        uses: oven-sh/setup-bun@v2
        with:
          bun-version: latest

      - name: Install client dependencies
        working-directory: client
        run: bun install

      - name: Build client
        working-directory: client
        run: bun run build

      - name: Move build folder
        run: mv client/build .

      - name: Install server dependencies
        run: bun install

      - name: Generate migrations
        run: bun run generate-migrations

      - name: Generate integrations
        run: bun run generate-integrations

      - name: Create zip archive
        run: zip -r MySpeed.zip build server package.json

      - name: Upload to Release
        uses: actions/github-script@v7
        with:
          script: |
            const fs = require('fs');
            await github.rest.repos.uploadReleaseAsset({
              owner: context.repo.owner,
              repo: context.repo.repo,
              release_id: ${{ inputs.release_id }},
              name: 'MySpeed.zip',
              data: fs.readFileSync('MySpeed.zip')
            });

The same workflow, on Latchkey

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

name: Build Binaries
 
on:
  workflow_call:
    inputs:
      version:
        required: true
        type: string
      release_id:
        required: true
        type: string
 
jobs:
  build-windows:
    timeout-minutes: 30
    name: "Windows (x64)"
    runs-on: windows-latest
    steps:
      - name: Checkout project
        uses: actions/checkout@v4
 
      - name: Setup Bun
        uses: oven-sh/setup-bun@v2
        with:
          bun-version: latest
 
      - name: Install client dependencies
        working-directory: client
        run: bun install
 
      - name: Build client
        working-directory: client
        run: bun run build
 
      - name: Move build folder
        run: Move-Item -Path client/build -Destination .
 
      - name: Install server dependencies
        run: bun install
 
      - name: Generate migrations
        run: bun run generate-migrations
 
      - name: Generate integrations
        run: bun run generate-integrations
 
      - name: Generate client embed
        run: bun run generate-client-embed
 
      - name: Compile binary
        run: bun build --compile --compile-autoload-package-json --external pg-hstore --external pg --target=bun-windows-x64 server/index.js --outfile MySpeed.exe
 
      - name: Upload to Release
        uses: actions/github-script@v7
        with:
          script: |
            const fs = require('fs');
            await github.rest.repos.uploadReleaseAsset({
              owner: context.repo.owner,
              repo: context.repo.repo,
              release_id: ${{ inputs.release_id }},
              name: 'MySpeed-windows-x64.exe',
              data: fs.readFileSync('MySpeed.exe')
            });
 
      - name: Upload artifact for MSI
        uses: actions/upload-artifact@v4
        with:
          name: MySpeed-windows-x64.exe
          path: MySpeed.exe
 
      - name: Upload build folder for MSI
        uses: actions/upload-artifact@v4
        with:
          name: build-folder
          path: build
 
  build-linux:
    timeout-minutes: 30
    name: "Linux (${{ matrix.arch }})"
    runs-on: ${{ matrix.runner }}
    strategy:
      fail-fast: false
      matrix:
        include:
          - arch: x64
            target: bun-linux-x64
            runner: ubuntu-latest
            artifact_name: MySpeed-linux-x64
          - arch: arm64
            target: bun-linux-arm64
            runner: ubuntu-24.04-arm
            artifact_name: MySpeed-linux-arm64
 
    steps:
      - name: Checkout project
        uses: actions/checkout@v4
 
      - name: Setup Bun
        uses: oven-sh/setup-bun@v2
        with:
          bun-version: latest
 
      - name: Install client dependencies
        working-directory: client
        run: bun install
 
      - name: Build client
        working-directory: client
        run: bun run build
 
      - name: Move build folder
        run: mv client/build .
 
      - name: Install server dependencies
        run: bun install
 
      - name: Generate migrations
        run: bun run generate-migrations
 
      - name: Generate integrations
        run: bun run generate-integrations
 
      - name: Generate client embed
        run: bun run generate-client-embed
 
      - name: Compile binary
        run: bun build --compile --compile-autoload-package-json --external pg-hstore --external pg --target=${{ matrix.target }} server/index.js --outfile MySpeed
 
      - name: Rename binary
        run: mv MySpeed ${{ matrix.artifact_name }}
 
      - name: Upload to Release
        uses: actions/github-script@v7
        with:
          script: |
            const fs = require('fs');
            await github.rest.repos.uploadReleaseAsset({
              owner: context.repo.owner,
              repo: context.repo.repo,
              release_id: ${{ inputs.release_id }},
              name: '${{ matrix.artifact_name }}',
              data: fs.readFileSync('${{ matrix.artifact_name }}')
            });
 
  build-macos:
    timeout-minutes: 30
    name: "macOS (${{ matrix.arch }})"
    runs-on: macos-latest
    strategy:
      fail-fast: false
      matrix:
        include:
          - arch: x64
            target: bun-darwin-x64
            artifact_name: MySpeed-macos-x64
          - arch: arm64
            target: bun-darwin-arm64
            artifact_name: MySpeed-macos-arm64
 
    steps:
      - name: Checkout project
        uses: actions/checkout@v4
 
      - name: Setup Bun
        uses: oven-sh/setup-bun@v2
        with:
          bun-version: latest
 
      - name: Install client dependencies
        working-directory: client
        run: bun install
 
      - name: Build client
        working-directory: client
        run: bun run build
 
      - name: Move build folder
        run: mv client/build .
 
      - name: Install server dependencies
        run: bun install
 
      - name: Generate migrations
        run: bun run generate-migrations
 
      - name: Generate integrations
        run: bun run generate-integrations
 
      - name: Generate client embed
        run: bun run generate-client-embed
 
      - name: Compile binary
        run: bun build --compile --compile-autoload-package-json --external pg-hstore --external pg --target=${{ matrix.target }} server/index.js --outfile MySpeed
 
      - name: Rename binary
        run: mv MySpeed ${{ matrix.artifact_name }}
 
      - name: Upload to Release
        uses: actions/github-script@v7
        with:
          script: |
            const fs = require('fs');
            await github.rest.repos.uploadReleaseAsset({
              owner: context.repo.owner,
              repo: context.repo.repo,
              release_id: ${{ inputs.release_id }},
              name: '${{ matrix.artifact_name }}',
              data: fs.readFileSync('${{ matrix.artifact_name }}')
            });
 
  build-zip:
    timeout-minutes: 30
    name: "Source ZIP"
    runs-on: latchkey-small
    steps:
      - name: Checkout project
        uses: actions/checkout@v4
 
      - name: Setup Bun
        uses: oven-sh/setup-bun@v2
        with:
          bun-version: latest
 
      - name: Install client dependencies
        working-directory: client
        run: bun install
 
      - name: Build client
        working-directory: client
        run: bun run build
 
      - name: Move build folder
        run: mv client/build .
 
      - name: Install server dependencies
        run: bun install
 
      - name: Generate migrations
        run: bun run generate-migrations
 
      - name: Generate integrations
        run: bun run generate-integrations
 
      - name: Create zip archive
        run: zip -r MySpeed.zip build server package.json
 
      - name: Upload to Release
        uses: actions/github-script@v7
        with:
          script: |
            const fs = require('fs');
            await github.rest.repos.uploadReleaseAsset({
              owner: context.repo.owner,
              repo: context.repo.repo,
              release_id: ${{ inputs.release_id }},
              name: 'MySpeed.zip',
              data: fs.readFileSync('MySpeed.zip')
            });
 

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 4 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