Skip to content

Build Binary

Build Binary #10

Workflow file for this run

name: Build Binary
on:
release:
types: [created]
workflow_dispatch:
inputs:
tag:
description: 'The release tag to attach assets to (must already exist)'
required: true
jobs:
build:
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
goos: linux
goarch: amd64
arch: x86_64-unknown-linux-gnu
output_suffix: ''
- os: ubuntu-latest
goos: linux
goarch: arm64
arch: aarch64-unknown-linux-gnu
output_suffix: ''
- os: windows-latest
goos: windows
goarch: amd64
arch: x86_64-pc-windows-msvc
output_suffix: '.exe'
- os: windows-latest
goos: windows
goarch: arm64
arch: aarch64-pc-windows-msvc
output_suffix: '.exe'
- os: macos-latest
goos: darwin
goarch: amd64
arch: x86_64-apple-darwin
output_suffix: ''
- os: macos-latest
goos: darwin
goarch: arm64
arch: aarch64-apple-darwin
output_suffix: ''
runs-on: ${{ matrix.os }}
steps:
- name: Set Release Tag
id: set_release_tag
shell: bash # force bash even on windows-latest
run: |
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
echo "release_tag=${{ github.event.inputs.tag }}" >> $GITHUB_OUTPUT
else
echo "release_tag=${{ github.event.release.tag_name }}" >> $GITHUB_OUTPUT
fi
- name: Checkout Repository
uses: actions/checkout@v4
with:
ref: ${{ steps.set_release_tag.outputs.release_tag }}
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: lts/*
- uses: ipfs/aegir/actions/cache-node-modules@main # this will cache node_modules and run `npm run build`
- name: Setup Go
uses: actions/setup-go@v4
with:
go-version: '1.24'
- name: Build binary
shell: bash # force bash even on windows-latest
env:
GOOS: ${{ matrix.goos }}
GOARCH: ${{ matrix.goarch }}
run: |
echo "Building for GOOS=${GOOS} GOARCH=${GOARCH}"
go build -o service-worker-gateway-${{ matrix.arch }}${{ matrix.output_suffix }} main.go
###
# Windows signing
###
- name: Windows - Decode code-signing cert
if: runner.os == 'Windows'
shell: bash
run: |
echo "${{ secrets.WINDOWS_CERTS }}" | base64 -d > win-cert.p12
- name: Windows - Sign EXE with signtool
if: runner.os == 'Windows'
shell: powershell
env:
PFX_PWD: ${{ secrets.WINDOWS_CERTS_PASSWORD }}
run: |
# Define search order: prefer x64, then arm64, then x86
$architectures = @('x64', 'arm64', 'x86')
$sdkRoot = "${env:ProgramFiles(x86)}\Windows Kits\10\bin"
$signtool = $null
foreach ($arch in $architectures) {
$found = Get-ChildItem $sdkRoot -Recurse -Filter signtool.exe |
Where-Object { $_.FullName -match "\\$arch\\" } |
Sort-Object -Property FullName -Descending |
Select-Object -First 1
if ($found) {
$signtool = $found
Write-Host "Found $arch signtool at: $($signtool.FullName)"
break
}
}
if (-not $signtool) {
Write-Error "signtool.exe not found under $sdkRoot for any architecture"
exit 1
}
& $signtool.FullName sign `
/a `# auto-select the leaf code-signing cert`
/f win-cert.p12 /p $Env:PFX_PWD `
/fd sha256 /td sha256 /tr http://timestamp.digicert.com `
"service-worker-gateway-${{ matrix.arch }}${{ matrix.output_suffix }}"
###
# End Windows signing
###
###
# macOS signing
###
- name: macOS – Import Developer-ID cert
id: import_mac_certs
if: runner.os == 'macOS'
shell: bash
env:
MAC_CERTS: ${{ secrets.MAC_CERTS }}
MAC_CERTS_PASSWORD: ${{ secrets.MAC_CERTS_PASSWORD }}
run: |
echo "$MAC_CERTS" | base64 -d > mac-cert.p12
# 1. Throw-away keychain for this job
security create-keychain -p '' build.keychain
security import mac-cert.p12 -k build.keychain \
-P "$MAC_CERTS_PASSWORD" -T /usr/bin/codesign
# 2. Allow non-interactive use of the private key
security set-key-partition-list -S apple-tool:,apple: -s -k '' build.keychain
# 3. Make the keychain searchable and unlock it
security list-keychain -d user -s build.keychain
security unlock-keychain -p '' build.keychain
# 4. Extract Team ID (OU=XXXXXXXXXX) for notarytool
TEAM_ID=$(security find-certificate -c "Developer ID Application" -p build.keychain |
openssl x509 -noout -subject |
sed -n 's/.*OU=\([A-Z0-9]\{10\}\).*/\1/p' |
head -n1)
echo "TEAM_ID=$TEAM_ID" >>"$GITHUB_OUTPUT"
- name: macOS – Codesign Go binary
if: runner.os == 'macOS'
shell: bash
run: |
BIN="service-worker-gateway-${{ matrix.arch }}${{ matrix.output_suffix }}"
# find the exact identity (match Team ID to be safe)
IDENTITY=$(security find-identity -v -p codesigning build.keychain |
awk '/Developer ID Application/ && /${{ steps.import_mac_certs.outputs.TEAM_ID }}/ {print $2; exit}')
echo "Using identity: $IDENTITY"
codesign --force --options runtime --timestamp=none \
--sign "$IDENTITY" --verbose "$BIN"
codesign --verify -v --verbose "$BIN"
- name: macOS - Store notarization credentials
if: runner.os == 'macOS'
env:
APPLEID: ${{ secrets.APPLE_ID }}
APPLEIDPASS: ${{ secrets.APPLE_ID_PASS }}
TEAM_ID: ${{ steps.import_mac_certs.outputs.TEAM_ID }}
run: |
xcrun notarytool store-credentials AC_PASSWORD \
--apple-id "$APPLEID" \
--password "$APPLEIDPASS" \
--team-id "$TEAM_ID"
- name: macOS - Notarize & staple
if: runner.os == 'macOS'
run: |
BIN="service-worker-gateway-${{ matrix.arch }}${{ matrix.output_suffix }}"
xcrun notarytool submit "$BIN" --keychain-profile AC_PASSWORD --wait
xcrun stapler staple "$BIN"
###
# End macOS signing
###
- name: Upload release asset
if: steps.set_release_tag.outputs.release_tag != '' # safety check
uses: softprops/action-gh-release@c95fe1489396fe8a9eb87c0abf8aa5b2ef267fda # v2.2.1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ steps.set_release_tag.outputs.release_tag }}
files: |
./service-worker-gateway-${{ matrix.arch }}${{ matrix.output_suffix }}