d18ad46eee
A dmg user can also update from the terminal (hermes update) or by re-running the install one-liner; the dmg arm only routed the two app-button methods, leaving three declared cells as permanent TODOs. Port the POSIX driver's method blocks into the macos driver's update phase (hermes-update with the --yes probe, installer re-run with per-ref flag probing, the +desktop built-app assert) and open the workflow gate. The dmg bootstrap driver also learns to recover instead of waiting out its bound when a stage fails: the bootstrap parks on an error screen with a Retry button (seen live: HTTP 429 downloading install.sh under full-matrix runner load), so the driver watches the bootstrap log for real failure shapes, requires two consecutive error probes before retargeting the click at Retry's measured position, unlatches when the log goes healthy, and gives up with the true cause after three retries. Driver rule learned three times in this suite (lsof +D, git show and find piped to grep -q): under set -euo pipefail, never feed grep -q from a pipe... grep exits at first match, the producer takes SIGPIPE, and a TRUE condition reads as failure. Capture to a variable or test paths directly. Verified end to end: run 33506177130, macos slice 13/13 green.
163 lines
6.7 KiB
YAML
163 lines
6.7 KiB
YAML
# Reusable runner for ONE macOS install/update combination.
|
|
#
|
|
# Two driver arms, one runs per dispatch (the other natively skips):
|
|
#
|
|
# e2e (script arms) tests/install/installer-script-e2e.sh - the
|
|
# OS-agnostic git-redirect driver shared with
|
|
# linux. installer-script(+desktop) installs,
|
|
# script/updater/hermes-desktop-app-update
|
|
# updates.
|
|
# gui-e2e (desktop arm) tests/install/macos-desktop-e2e.sh - the
|
|
# published Hermes-Setup.dmg, mounted and run,
|
|
# then the app driven by Playwright for the
|
|
# app-update methods.
|
|
#
|
|
# Method pairs without a driver arm yet NATIVELY SKIP (grey check, no
|
|
# runner): the capability knowledge lives here, next to the drivers.
|
|
|
|
name: install-e2e macos leg
|
|
|
|
on:
|
|
workflow_call:
|
|
inputs:
|
|
install-method:
|
|
description: 'How OLD gets installed. Supported: installer-script, installer-script+desktop (curl | bash one-liner, optionally with --include-desktop) and desktop-installer@latest (the published Hermes-Setup.dmg).'
|
|
required: true
|
|
type: string
|
|
update-method:
|
|
description: 'How the install updates to HEAD. Script installs support hermes-update / installer-script / installer-script+desktop / hermes-desktop-app-update; dmg installs support open-app-update / hermes-desktop-app-update.'
|
|
required: true
|
|
type: string
|
|
install-ref:
|
|
description: 'What to install before updating: a branch, a tag, or a SHA reachable from main.'
|
|
required: false
|
|
type: string
|
|
default: refs/heads/main
|
|
tag-has-desktop:
|
|
description: "Whether install-ref ships the desktop app (apps/desktop). The caller annotates this from the tag's own tree; desktop-method legs from pre-desktop releases natively skip."
|
|
required: false
|
|
type: boolean
|
|
default: true
|
|
leg-id:
|
|
description: 'Artifact-safe matrix leg id (from generate-e2e-matrix.mjs legId). Names this leg''s logs + player artifacts so the report job can link a row to its zip.'
|
|
required: true
|
|
type: string
|
|
dmg-url:
|
|
description: 'Bootstrap dmg to install OLD with. Default: the latest published one — what a user downloads today.'
|
|
required: false
|
|
type: string
|
|
default: https://hermes-assets.nousresearch.com/Hermes-Setup.dmg
|
|
timeout-minutes:
|
|
description: 'Job timeout. App-update legs do a full Electron build.'
|
|
required: false
|
|
type: number
|
|
default: 120
|
|
|
|
permissions:
|
|
contents: read
|
|
|
|
jobs:
|
|
# ---- arm 1: script installs (the shared OS-agnostic driver) --------------
|
|
e2e:
|
|
name: install & update
|
|
if: >-
|
|
(inputs.install-method == 'installer-script'
|
|
|| (inputs.install-method == 'installer-script+desktop' && inputs.tag-has-desktop))
|
|
&& (contains(fromJSON('["hermes-update", "installer-script"]'), inputs.update-method)
|
|
|| (contains(fromJSON('["installer-script+desktop", "hermes-desktop-app-update"]'), inputs.update-method) && inputs.tag-has-desktop))
|
|
uses: ./.github/workflows/install-e2e-run.yml
|
|
with:
|
|
install-method: ${{ inputs.install-method }}
|
|
update-method: ${{ inputs.update-method }}
|
|
install-ref: ${{ inputs.install-ref }}
|
|
tag-has-desktop: ${{ inputs.tag-has-desktop }}
|
|
leg-id: ${{ inputs.leg-id }}
|
|
runner: macos-latest
|
|
timeout-minutes: ${{ inputs.timeout-minutes }}
|
|
|
|
# ---- arm 2: the published dmg, then Playwright drives the app ------------
|
|
gui-e2e:
|
|
# Short static name on purpose: name expressions render UNEXPANDED on
|
|
# skipped jobs.
|
|
name: Hermes-Setup.dmg
|
|
if: >-
|
|
inputs.install-method == 'desktop-installer@latest' && inputs.tag-has-desktop
|
|
&& contains(fromJSON('["open-app-update", "hermes-desktop-app-update", "hermes-update", "installer-script", "installer-script+desktop"]'), inputs.update-method)
|
|
runs-on: macos-latest
|
|
timeout-minutes: ${{ inputs.timeout-minutes }}
|
|
|
|
steps:
|
|
# Full history: the driver bare-clones this checkout as the repo the
|
|
# installer/updater talk to.
|
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
with:
|
|
fetch-depth: 0
|
|
|
|
- name: Start screen recording
|
|
uses: ./.github/actions/e2e-screen-record
|
|
with:
|
|
mode: start
|
|
output: ${{ runner.temp }}/e2e-logs/recording.mkv
|
|
|
|
- name: Stage serve repo (main -> ${{ inputs.install-ref }})
|
|
run: |
|
|
set -euo pipefail
|
|
tests/install/macos-desktop-e2e.sh --phase stage \
|
|
--update-method '${{ inputs.update-method }}' \
|
|
--install-ref '${{ inputs.install-ref }}' \
|
|
--dmg-url '${{ inputs.dmg-url }}'
|
|
env:
|
|
HERMES_E2E_LOG_DIR: ${{ runner.temp }}/e2e-logs
|
|
|
|
- name: Install ${{ inputs.install-ref }} via Hermes-Setup.dmg
|
|
run: |
|
|
set -euo pipefail
|
|
tests/install/macos-desktop-e2e.sh --phase install \
|
|
--update-method '${{ inputs.update-method }}' \
|
|
--install-ref '${{ inputs.install-ref }}' \
|
|
--dmg-url '${{ inputs.dmg-url }}'
|
|
env:
|
|
HERMES_E2E_LOG_DIR: ${{ runner.temp }}/e2e-logs
|
|
|
|
- name: Update ${{ inputs.install-ref }} -> HEAD (${{ inputs.update-method }})
|
|
run: |
|
|
set -euo pipefail
|
|
tests/install/macos-desktop-e2e.sh --phase update \
|
|
--update-method '${{ inputs.update-method }}' \
|
|
--install-ref '${{ inputs.install-ref }}' \
|
|
--dmg-url '${{ inputs.dmg-url }}'
|
|
env:
|
|
HERMES_E2E_LOG_DIR: ${{ runner.temp }}/e2e-logs
|
|
|
|
- name: Stop screen recording
|
|
if: always()
|
|
uses: ./.github/actions/e2e-screen-record
|
|
with:
|
|
mode: stop
|
|
output: ${{ runner.temp }}/e2e-logs/recording.mkv
|
|
|
|
- name: Remux recording for browser playback
|
|
if: always()
|
|
run: |
|
|
set -euo pipefail
|
|
if [ -f "${{ runner.temp }}/e2e-logs/recording.mkv" ]; then
|
|
ffmpeg -y -hide_banner -loglevel error -i "${{ runner.temp }}/e2e-logs/recording.mkv" \
|
|
-c copy "${{ runner.temp }}/e2e-logs/recording.mp4"
|
|
fi
|
|
|
|
# Artifact names cannot contain '/'; install-ref may be a full ref.
|
|
- name: Build artifact name
|
|
id: artifact
|
|
if: always()
|
|
run: |
|
|
echo "name=install-e2e-logs-${{ inputs.leg-id }}" >> "$GITHUB_OUTPUT"
|
|
|
|
- name: Upload logs
|
|
if: always()
|
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
with:
|
|
name: ${{ steps.artifact.outputs.name }}
|
|
path: ${{ runner.temp }}/e2e-logs
|
|
retention-days: 14
|
|
if-no-files-found: ignore
|