Skip to content
This repository was archived by the owner on Oct 13, 2026. It is now read-only.
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
191 changes: 191 additions & 0 deletions .github/workflows/workbench-functional-smoke.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
name: Workbench Functional Smoke

permissions:
contents: read

on:
workflow_dispatch:
inputs:
ref:
description: Git ref to build
required: true
default: evaos/beta-rc-20260612
type: string
run_guardrails:
description: Run evaOS guardrail audits before packaging
required: false
default: true
type: boolean

concurrency:
group: workbench-functional-smoke-${{ github.event.inputs.ref }}
cancel-in-progress: true

env:
BUN_INSTALL_REGISTRY: https://registry.npmjs.org/
CI: true
CSC_IDENTITY_AUTO_DISCOVERY: false
EVAOS_BETA_PUBLIC_RELEASE: 'false'
EVAOS_BETA_REQUIRE_SIGNING: 'false'
EVAOS_FINALIZE_MAC_DMG: 'false'
EVAOS_DMG_CODESIGN: 'false'
ELECTRON_BUILDER_COMPRESSION_LEVEL: '1'

jobs:
macos-arm64-app:
name: macOS arm64 unpacked app
runs-on: macos-14
timeout-minutes: 45

steps:
- name: Checkout
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10
with:
ref: ${{ inputs.ref }}
Comment thread
coderabbitai[bot] marked this conversation as resolved.
persist-credentials: false

- name: Commit info
id: commit
shell: bash
run: |
set -euo pipefail
SHORT="$(git rev-parse --short HEAD)"
{
echo "short=$SHORT"
echo "sha=$(git rev-parse HEAD)"
} >> "$GITHUB_OUTPUT"

- name: Setup Node.js
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020
with:
node-version: '22'

- name: Setup bun
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6
with:
bun-version: 1.3.13

Comment thread
coderabbitai[bot] marked this conversation as resolved.
- name: Setup Python
uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065
with:
python-version: '3.12'

- name: Cache Electron artifacts
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830
with:
path: |
${{ runner.temp }}/.cache/electron
${{ runner.temp }}/.cache/electron-builder
~/.cache/electron
~/.cache/electron-builder
key: workbench-functional-smoke-electron-arm64-${{ hashFiles('package.json', 'bun.lock') }}
restore-keys: |
workbench-functional-smoke-electron-arm64-

- name: Install dependencies
uses: nick-fields/retry@ce71cc2ab81d554ebbe88c79ab5975992d79ba08
with:
timeout_minutes: 10
max_attempts: 3
retry_wait_seconds: 30
command: bun install --frozen-lockfile

- name: Run postinstall
run: bun run postinstall || true

- name: Rebuild native modules for Electron
run: bunx electron-builder install-app-deps
env:
npm_config_runtime: electron
npm_config_disturl: https://electronjs.org/headers
ELECTRON_CACHE: ${{ runner.temp }}/.cache/electron
ELECTRON_BUILDER_CACHE: ${{ runner.temp }}/.cache/electron-builder

- name: evaOS guardrail audit
if: ${{ inputs.run_guardrails }}
shell: bash
run: |
set -euo pipefail
node scripts/evaosBetaReleaseGate.js audit-config
node scripts/evaosUpstreamGuardrailAudit.js

- name: Build unpacked app only
shell: bash
run: |
set -euo pipefail
node scripts/build-with-builder.js arm64 --mac dir --arm64

- name: Verify functional-smoke artifact shape
id: verify
shell: bash
env:
SMOKE_REF: ${{ inputs.ref }}
SMOKE_SHA: ${{ steps.commit.outputs.sha }}
run: |
set -euo pipefail
APP_PATH="$(find out -type d -name '*.app' -print -quit)"
if [ -z "$APP_PATH" ]; then
echo "::error::No .app produced under out/"
find out -maxdepth 3 -print || true
exit 1
fi

BRIDGE="$APP_PATH/Contents/Resources/Bridge/evaos-desktop-bridge"
BRIDGE_MANIFEST="$APP_PATH/Contents/Resources/Bridge/manifest.json"
AIONCORE_DIR="$APP_PATH/Contents/Resources/bundled-aioncore"
HUB_DIR="$APP_PATH/Contents/Resources/hub"

test -x "$BRIDGE"
test -f "$BRIDGE_MANIFEST"
test -d "$AIONCORE_DIR"
test -d "$HUB_DIR"

BUNDLE_ID="$(/usr/libexec/PlistBuddy -c 'Print :CFBundleIdentifier' "$APP_PATH/Contents/Info.plist")"
VERSION="$(/usr/libexec/PlistBuddy -c 'Print :CFBundleShortVersionString' "$APP_PATH/Contents/Info.plist")"
BRIDGE_VERSION="$(node -e "const fs=require('fs'); const m=JSON.parse(fs.readFileSync(process.argv[1], 'utf8')); console.log(m.version || m.commit || 'unknown')" "$BRIDGE_MANIFEST")"

{
echo "app_path=$APP_PATH"
echo "bundle_id=$BUNDLE_ID"
echo "version=$VERSION"
echo "bridge_version=$BRIDGE_VERSION"
} >> "$GITHUB_OUTPUT"

{
echo "## Workbench Functional Smoke"
echo
echo "- Ref: \`$SMOKE_REF\`"
echo "- SHA: \`$SMOKE_SHA\`"
echo "- App path: \`$APP_PATH\`"
Comment thread
coderabbitai[bot] marked this conversation as resolved.
echo "- Version: \`$VERSION\`"
echo "- Bundle ID: \`$BUNDLE_ID\`"
echo "- Bridge manifest: \`$BRIDGE_VERSION\`"
echo
echo "This artifact is intentionally unsigned/unnotarized and contains no DMG or release metadata."
echo "Use it for functional proof only. Public release still requires the normal signed/notarized gate."
echo
echo "### Size"
echo '```'
du -sh "$APP_PATH" out
echo '```'
} >> "$GITHUB_STEP_SUMMARY"

- name: Archive unpacked app
shell: bash
env:
APP_PATH: ${{ steps.verify.outputs.app_path }}
COMMIT_SHORT: ${{ steps.commit.outputs.short }}
run: |
set -euo pipefail
ARTIFACT="workbench-functional-smoke-${COMMIT_SHORT}-mac-arm64.zip"
ditto -c -k --sequesterRsrc --keepParent "$APP_PATH" "$ARTIFACT"
shasum -a 256 "$ARTIFACT" | tee "$ARTIFACT.sha256"

- name: Upload functional-smoke artifact
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02
with:
name: workbench-functional-smoke-macos-arm64-${{ steps.commit.outputs.short }}
path: |
workbench-functional-smoke-${{ steps.commit.outputs.short }}-mac-arm64.zip
workbench-functional-smoke-${{ steps.commit.outputs.short }}-mac-arm64.zip.sha256
retention-days: 7
Loading