agent-orchestrator/.github/workflows/testing-build.yml

124 lines
5.4 KiB
YAML

name: Testing build (all platforms)
# Unsigned testing builds for Linux + Windows + macOS in one matrix. Click
# "Run workflow" in the Actions tab, or push a 0.0.0-testing-* tag. All three jobs
# publish to a single 0.0.0-testing-<short-sha> prerelease (distinct asset names).
#
# Per OS:
# Linux -> .deb
# Windows -> Setup.exe (+ .nupkg / RELEASES)
# macOS -> .zip (arm64; dmg + signing are follow-ups)
#
# Unsigned: macOS is quarantined/Gatekeeper-blocked once downloaded
# (xattr -dr com.apple.quarantine "Agent Orchestrator.app"); Windows SmartScreen
# warns ("More info" -> "Run anyway"). Each OS builds on its own native runner so
# build-daemon.mjs compiles the bundled ao for that platform (host == target).
on:
workflow_dispatch:
push:
tags:
- "0.0.0-testing-*"
jobs:
build:
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
target: "@electron-forge/maker-deb"
- os: windows-latest
target: "@electron-forge/maker-squirrel"
- os: macos-latest
target: "@electron-forge/maker-zip"
runs-on: ${{ matrix.os }}
permissions:
contents: write
defaults:
run:
working-directory: frontend
env:
# Pure-Go sqlite (modernc) needs no cgo; on Linux this also keeps the daemon
# static and portable across glibc.
CGO_ENABLED: 0
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: npm
cache-dependency-path: frontend/package-lock.json
- uses: actions/setup-go@v5
with:
go-version-file: backend/go.mod
cache-dependency-path: backend/go.sum
- run: npm ci
- name: Build (unsigned)
# `npm run make` keeps the premake daemon build; --targets restricts to this
# platform's maker.
run: npm run make -- --targets ${{ matrix.target }}
# Smoke-install the Squirrel installer on a clean, native x64 Windows runner.
# This is a build-vs-host verdict: if it installs here it proves the artifact
# is good and a failing user machine is host-side (AV/disk/signing); if it
# fails here the build/Squirrel config is wrong. continue-on-error so a failed
# install never blocks publishing the artifacts. The runner has no real-time
# AV blocking, so a clean install here does NOT prove SmartScreen/Defender
# won't reject the unsigned binaries on end-user machines.
- name: Smoke-install the Windows installer
if: runner.os == 'Windows'
continue-on-error: true
timeout-minutes: 5
shell: pwsh
run: |
$setup = Get-ChildItem -Path out/make/squirrel.windows -Recurse -Filter '*Setup.exe' | Select-Object -First 1
if (-not $setup) { Write-Host '::error::no Setup.exe produced under out/make/squirrel.windows'; exit 1 }
Write-Host "Running $($setup.FullName) --silent"
$proc = Start-Process -FilePath $setup.FullName -ArgumentList '--silent' -PassThru -Wait
Write-Host "Setup.exe exit code: $($proc.ExitCode)"
$installDir = Join-Path $env:LOCALAPPDATA 'AgentOrchestrator'
# Update.exe writes SquirrelSetup.log into the app root dir; the Setup.exe
# bootstrapper only logs to SquirrelTemp for the earliest extraction stage.
# Grab whichever exists and copy it into the workspace for upload.
$log = @(
(Join-Path $installDir 'SquirrelSetup.log'),
(Join-Path $env:LOCALAPPDATA 'SquirrelTemp\SquirrelSetup.log')
) | Where-Object { Test-Path $_ } | Select-Object -First 1
if ($log) { Copy-Item $log squirrel-setup.log; Write-Host "captured log: $log" } else { Write-Host '::warning::no SquirrelSetup.log found in install dir or SquirrelTemp' }
if (Test-Path $installDir) {
Write-Host "INSTALL OK: $installDir created"
Get-ChildItem $installDir | Select-Object Name | Format-Table -AutoSize
} else {
Write-Host "::warning::INSTALL FAILED: $installDir was not created"
}
- name: Upload SquirrelSetup.log
if: runner.os == 'Windows'
uses: actions/upload-artifact@v4
with:
name: squirrel-setup-log-${{ github.sha }}
path: frontend/squirrel-setup.log
if-no-files-found: warn
- name: Publish to a 0.0.0-testing-<sha> prerelease
shell: bash
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
set -euo pipefail
# Tag push: use the pushed tag. Manual run: mint 0.0.0-testing-<sha>.
if [ "${GITHUB_REF_TYPE}" = "tag" ]; then
TAG="${GITHUB_REF_NAME}"
else
TAG="0.0.0-testing-${GITHUB_SHA::7}"
fi
# Matrix jobs race here; first one creates the release, the rest hit
# "already exists" which is fine (|| true). Distinct asset names + --clobber
# make uploads idempotent across re-runs.
gh release create "$TAG" --prerelease --target "$GITHUB_SHA" --title "$TAG" \
--notes "Unsigned testing build (Linux .deb / Windows Setup.exe / macOS .zip). Not signed; for testing only." \
|| true
# NUL-delimited to survive spaces in the app name ("Agent Orchestrator-...").
find out/make -type f -print0 | while IFS= read -r -d '' f; do
echo "uploading: $f"
gh release upload "$TAG" "$f" --clobber
done