evOo-local/.github/workflows/desktop-macos-screenshot.yml
cynarAI 5cd1bc906f ci: Product CI merge gate and Autopilot auto-merge (#84)
* ci: add Product CI merge gate and Autopilot auto-merge path

Aggregate lint, typecheck, builds, unit, Postgres journeys, and Web E2E
into a single Product CI check for branch protection. Soft-fail artifact
uploads and skip headless macOS screenshots so infra noise does not block
merge. Add autopilot/auto-merge workflow and MERGE_GATES.md.

Co-authored-by: cynarAI <cynarAI@users.noreply.github.com>

* fix(ci): keep autopilot auto-merge inert without label

Co-authored-by: cynarAI <cynarAI@users.noreply.github.com>

* fix(ci): run autopilot auto-merge on self-hosted runner

Co-authored-by: cynarAI <cynarAI@users.noreply.github.com>

* fix(ci): free stale E2E ports before Playwright bind on Linux

Self-hosted evoo-ci runners can retain listeners on harness ports
(3110 API, 5180 web, 4321 marketing, 3111 device control) after a
failed run, causing EADDRINUSE before the next job. Add a guarded
free-e2e-ports.sh that uses fuser on Linux only and never touches
live dev ports 3100/5173. Wire it into the Playwright workflow and
the E2E harness with clear logging.

Co-authored-by: cynarAI <cynarAI@users.noreply.github.com>

* fix(web): stabilize message More menu Escape in hover E2E

The desktop hover spec assumed Escape always closed the first page-level
menu within one keypress. On self-hosted Chromium the Copy menu could stay
open while the rail remained visible, failing getByRole('menu') count.

Wait for the Copy item to prove the menu opened, then retry Escape until
that item hides while asserting the More control stays on the hover rail.

Co-authored-by: cynarAI <cynarAI@users.noreply.github.com>

* fix(web): retry sign-up navigation in Playwright helpers

Late-suite specs can miss the sign-up heading when Vite is still
warming on self-hosted runners. Retry goto until the form renders
instead of failing once at the default timeout.

Co-authored-by: cynarAI <cynarAI@users.noreply.github.com>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: cynarAI <cynarAI@users.noreply.github.com>
2026-09-24 00:57:10 +02:00

91 lines
4.1 KiB
YAML

# Infra-only: native macOS screenshots for PR review. Never add to branch protection.
# Skips cleanly on headless runners (no display). Artifact quota failures are soft.
name: desktop-macos-screenshot
on:
push:
branches: [main]
paths: &desktop-setup-paths
- ".github/workflows/desktop-macos-screenshot.yml"
- "apps/desktop/e2e/setup.spec.ts"
- "apps/desktop/package.json"
- "apps/desktop/assets/**"
- "packages/ui-tokens/assets/**"
- "apps/desktop/scripts/copy-static.mjs"
- "apps/desktop/src/setup*"
- "apps/desktop/src/window-options.ts"
- "packages/contracts/src/desktop.ts"
pull_request:
paths: *desktop-setup-paths
permissions:
contents: read
concurrency:
group: desktop-macos-screenshot-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
jobs:
screenshot:
name: macOS setup screenshot (infra)
runs-on: [self-hosted, evoo-ci, macOS]
timeout-minutes: 20
steps:
- name: Detect interactive display
id: display
run: |
set -euo pipefail
if system_profiler SPDisplaysDataType 2>/dev/null | grep -q "Resolution:"; then
echo "available=true" >> "$GITHUB_OUTPUT"
else
echo "available=false" >> "$GITHUB_OUTPUT"
echo "::notice::No display attached on this macOS runner. Skipping infra screenshot; merge is not blocked."
fi
- uses: actions/checkout@v5
if: steps.display.outputs.available == 'true'
with:
persist-credentials: false
- uses: pnpm/action-setup@v4
if: steps.display.outputs.available == 'true'
- uses: actions/setup-node@v4
if: steps.display.outputs.available == 'true'
with:
node-version: 22
cache: pnpm
- run: pnpm install --frozen-lockfile
if: steps.display.outputs.available == 'true'
- run: pnpm --filter @rakazo/desktop build
if: steps.display.outputs.available == 'true'
- name: Verify packaged Tahoe icon and legacy fallback
if: steps.display.outputs.available == 'true'
run: |
pnpm --filter @rakazo/web build
CSC_IDENTITY_AUTO_DISCOVERY=false pnpm --filter @rakazo/desktop exec electron-builder --mac --dir --publish never -c.mac.identity=null -c.mac.notarize=false
xcrun assetutil --info apps/desktop/out/mac-arm64/Rakazo.app/Contents/Resources/Assets.car > "$RUNNER_TEMP/icon-assets.json"
jq -e 'any(.[]; .Name == "Icon" and .AssetType == "IconImageStack") and any(.[]; .Name == "Icon_Assets/orange-bot" and .AssetType == "Image")' "$RUNNER_TEMP/icon-assets.json"
iconutil -c iconset apps/desktop/out/mac-arm64/Rakazo.app/Contents/Resources/icon.icns -o "$RUNNER_TEMP/fallback.iconset"
sips -s format png "$RUNNER_TEMP/fallback.iconset/icon_128x128@2x.png" --out "$RUNNER_TEMP/fallback-decoded.png"
test -s "$RUNNER_TEMP/fallback-decoded.png"
test "$(/usr/libexec/PlistBuddy -c 'Print :CFBundleIconName' apps/desktop/out/mac-arm64/Rakazo.app/Contents/Info.plist)" = Icon
env:
RAKAZO_ALLOW_DEV_SECRETS: "1"
- name: Capture packaged macOS setup window and Dock
if: steps.display.outputs.available == 'true'
continue-on-error: true
env:
RAKAZO_E2E_EXECUTABLE: out/mac-arm64/Rakazo.app/Contents/MacOS/Rakazo
run: >-
pnpm --filter @rakazo/desktop exec playwright test
--config e2e/playwright.config.ts setup.spec.ts
--grep "first run asks whether to use a local or existing instance"
- name: Upload native macOS setup screenshot
if: always() && steps.display.outputs.available == 'true'
continue-on-error: true
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
name: desktop-e2e-macos-screenshot
path: |
apps/desktop/e2e/screenshots/08-setup-macos-native-controls.png
apps/desktop/e2e/screenshots/09-macos-dock.png
if-no-files-found: warn
retention-days: 1