Files
hermes-agent/tests/install/e2e-assets/record-stop.ps1
T
ethernet cdaf0cf091 ci(install-e2e): one screen-recording mechanism on every runner, Xvfb for headless linux
The composite action .github/actions/e2e-screen-record owns setup and
lifecycle on all three OSes: ffmpeg via apt/brew-verify/winget+cache,
capture via x11grab/gdigrab/avfoundation, mkv at 15fps stopped by 'q'
on live stdin with kill fallback. Linux runners have no display, so
start brings up a dedicated Xvfb :99 and exports DISPLAY - one display
serves both the recorder and any app a later step launches.

Recording moves out of the GUI driver into workflow infrastructure -
that is what makes it uniform - and a missing ffmpeg or a zero-frame
file now FAILS the leg instead of skipping silently: the graceful-skip
path is how the windows leg shipped no recording.mkv while green.

Lifecycle proven locally: start against lavfi testsrc, q-stop, ffprobe
duration check (record-start.sh/record-stop.sh under nix ffmpeg).
2026-08-12 04:15:24 -04:00

54 lines
2.2 KiB
PowerShell

# Stop a recording started by record-start.ps1 and verify the file is real.
#
# Usage: powershell -File record-stop.ps1 -OutFile recording.mkv
#
# Drops the STOP marker the holder watches for (it writes 'q' to ffmpeg's
# live stdin), waits for the holder to exit, then asserts the output exists
# and has a decodable duration - a zero-frame recording is the classic
# silent failure.
#Requires -Version 5.1
param(
[Parameter(Mandatory = $true)][string]$OutFile
)
$ErrorActionPreference = "Stop"
$stateFile = "$OutFile.state"
if (-not (Test-Path -LiteralPath $stateFile)) {
Write-Host "record-stop: no state at $stateFile (was record-start run?)"
exit 1
}
$state = (Get-Content -LiteralPath $stateFile -Raw).Trim() -split " ", 2
$holderPid = [int]$state[0]
$stopMarker = $state[1]
Set-Content -LiteralPath $stopMarker -Value "stop"
try {
$holder = Get-Process -Id $holderPid -ErrorAction SilentlyContinue
if ($holder) { $holder.WaitForExit(20000) | Out-Null }
} catch {}
# Belt and braces: if ffmpeg outlived the holder, kill it directly.
$ffpidFile = "$OutFile.ffpid"
if (Test-Path -LiteralPath $ffpidFile) {
$ffpid = [int](Get-Content -LiteralPath $ffpidFile -Raw).Trim()
try { Stop-Process -Id $ffpid -Force -ErrorAction SilentlyContinue } catch {}
}
Remove-Item -LiteralPath $stateFile, $stopMarker, $ffpidFile, "$OutFile.holder.ps1" -Force -ErrorAction SilentlyContinue
if (-not (Test-Path -LiteralPath $OutFile) -or (Get-Item -LiteralPath $OutFile).Length -eq 0) {
Write-Host "record-stop: $OutFile missing or empty"
exit 1
}
if (Get-Command ffprobe -ErrorAction SilentlyContinue) {
$prevEap = $ErrorActionPreference; $ErrorActionPreference = "Continue"
$dur = (& ffprobe -v error -show_entries format=duration -of csv=p=0 $OutFile 2>&1 | Out-String).Trim()
$ErrorActionPreference = $prevEap
if (-not $dur -or $dur -eq "0" -or $dur -like "0.0*") {
Write-Host "record-stop: $OutFile has no duration (zero-frame recording)"
exit 1
}
Write-Host "record-stop: $OutFile finalized (${dur}s)"
} else {
Write-Host "record-stop: $OutFile finalized (ffprobe absent; size $((Get-Item -LiteralPath $OutFile).Length) bytes)"
}