From c7a48fa417144fa45b5cecf14f80b13653a644c0 Mon Sep 17 00:00:00 2001 From: Ryan L'Italien Date: Wed, 26 Aug 2026 18:50:25 -0400 Subject: [PATCH] unreal: distill the Windows host-mode CI learnings (2026-08-25) Items 13-14 in section B, distilled from the private repo's unreal LEARNINGS 17-18: native-Windows host-mode runner as the working path for Win64 BuildCookRun (warm shared DDC), plus the six Windows/ps1 CI traps (ssh-killed runner daemons, PowerShell exit-code lies, ephemeral host-mode workspaces, upload-artifact v4 GHES gate, artifact retention, node-bearing GPU images). Also update DISTILLING.md step 8: distill passes now land as distill/* branch PRs for human review, never direct pushes to main. Co-Authored-By: Claude Fable 5 --- DISTILLING.md | 7 +++++-- unreal/LEARNINGS.md | 26 ++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/DISTILLING.md b/DISTILLING.md index bb20115..e9c0c59 100644 --- a/DISTILLING.md +++ b/DISTILLING.md @@ -199,8 +199,11 @@ Do: 6. Do NOT touch unreal/fixtures/ - those are handled separately. 7. Do NOT modify the private working repo. Read-only there, always. 8. Commit with a clear message (temp file + `git commit -F`, ending with - "Co-Authored-By: Claude Fable 5 ", no em dashes) and - push to this repo's main. + "Co-Authored-By: Claude Fable 5 ", no em dashes) on a + `distill/-` branch, push the branch, and open a PR against + main for human review. Never push distilled content directly to main. If an + open `distill/*` PR already exists, add to that branch instead of opening a + second PR. Report: which entries were distilled, before/after line counts for any file you changed, anything you excluded and why, and any secret/credential values you diff --git a/unreal/LEARNINGS.md b/unreal/LEARNINGS.md index 65b45ec..9fa638c 100644 --- a/unreal/LEARNINGS.md +++ b/unreal/LEARNINGS.md @@ -144,3 +144,29 @@ No secrets - reference credential *locations*, never paste them. `%ProgramData%\ssh\administrators_authorized_keys`; a per-user key is silently ignored and fails as a plain `Permission denied (publickey)`. That file also needs inheritance removed and its ACL limited to SYSTEM + Administrators. +13. **Win64 `BuildCookRun` in CI wants a native-Windows host-mode runner** (verified on a + real project, 2026-08-25): jobs run directly on the box that already has the engine, + the VS toolchain, and the shared DDC. Keep the build logic in a repo script (a + one-command `tools\build_windows.ps1` that locates the engine and calls + `RunUAT.bat BuildCookRun`); the workflow step just invokes it. A warm shared DDC is + why CI packaged in ~5 minutes - budget an hour cold. *(⤳skill: `unreal-build` should + know CI-on-host means the engine, toolchain, and DDC are the host's own.)* +14. **Windows/PowerShell CI traps (each cost a debug cycle):** + - A CI runner daemon started over ssh dies with the ssh session (item 10's lesson + again, in runner form) and fails *silently*: it stays registered, jobs sit in + `waiting` forever. Run it from a scheduled task (`schtasks`, ONLOGON, a start.bat + that sets the working directory). + - `powershell -File script.ps1` returns **0 even when RunUAT fails** - + `$ErrorActionPreference = "Stop"` does not catch native-command exit codes. End the + build script with `if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }` or CI lies green. + - Host-mode job workspaces (`~/.cache/act//hostexecutor`) are **deleted at job + end**, build output included. A green build produces nothing unless an + upload-artifact step runs. + - `actions/upload-artifact@v4` **hard-refuses non-github.com servers** (GHES gate); + use **@v3** on Forgejo/Gitea. Same for download-artifact. + - A packaged Win64 artifact is ~370 MB compressed per build; set `retention-days` or + builds eat the CI server's disk. + - GPU jobs in docker-mode runners need a **node-bearing image** (`actions/checkout` + is a node action; bare `nvidia/cuda` images die on step one). catthehacker + act-22.04 + the NVIDIA container toolkit + `container.options: "--gpus all"` works; + driver injection gives nvidia-smi-level access, CUDA only if the image adds it.