v0.4.1 sync: build and CI fixes, settings presets D440-D447, outside PRs

build-pc.sh Windows temp-dir re-exec fixes; CI pin actions and no-cache ROM
handling; original-N64 and Deck presets; D440 preset labelling; D442 All
unlocked as a RAM/query-time override; D443 settings values (MSAA 16x,
Restart game); D444 front-end Previous/Next paging; D447 Original-aspect
pillarbox/letterbox. Outside contributions by dolent: PRs #120 and #121 (relabelled D445,
D446), merged as dolent's original commits.

Refs: D440 D441 D442 D443 D444 D445 D446 D447 D387 D283 #120 #121
This commit is contained in:
James Dansereau committed 2026-10-06 18:35:39 -04:00
72 files changed
+2228 -2080

No files matched your search

+42 -76
View File
@@ -9,16 +9,19 @@
# Persistence model — everything lives under the runner's own paths, managed
# by the pipeline; no hand-maintained directories:
# - ccache -> actions/cache (stored by the runner under _work/_temp)
# - ROM -> actions/cache, key ge-rom-data-ntsc-v1. Bootstrap: copy the
# three files into {runner_home}/_rom-seed/ on the box; a run
# with an empty cache copies them in and attempts to save the
# cache entry. The seed dir is kept (NOT deleted) rather than
# treated as one-time -- actions/cache/save has been silently
# failing to persist on this box (warning, not a hard step
# failure; root cause open, see SELFHOSTED-RUNNER-PLAN.md), so
# the seed is the durable fallback every run re-copies from
# until that's fixed. Integrity is re-verified every run
# against the committed ge007.u.sha1 (repo-tracked US ROM hash).
# - ROM -> copied every run from a seed dir on the runner:
# {runner_home}/_rom-seed/, or the repo variable
# GE_ROM_SEED_DIR. Bootstrap: put ge007.ntsc-final.z64,
# pcmodels-ntsc-final/ and pccg-ntsc-final/ there once.
# Integrity is re-verified every run against the committed
# ge007.u.sha1 (repo-tracked US ROM hash).
# The ROM is deliberately NOT stored in actions/cache (it
# used to be, key ge-rom-data-ntsc-v1). Cache entries live on
# GitHub's side, and pull_request workflows, including ci.yml
# runs from fork PRs, can restore caches created on the base
# branch, so a PR could read the ROM out of the cache. (The
# old save never actually persisted on this box, so no entry
# was ever created; checked 2026-09-30.)
# - MSYS2 -> machine-level install at C:\msys64 (verify.sh hardcodes the
# prefix), installed and its packages maintained BY HAND on
# the box. msys2/setup-msys2 still runs every job (it's what
@@ -37,8 +40,8 @@
# a runner that can see the ROM.
#
# Leak rules (docs/dev/notes/AGENT-VM-FORGEJO-PLAN.md checklist):
# - The ROM + sidecars live in the runner-managed cache only; nothing in
# this workflow uploads from data/.
# - The ROM + sidecars live only in the runner's local seed dir (never in
# actions/cache); nothing in this workflow uploads from data/.
# - Artifacts here are console logs + a JSON verdict only. Rendered frames
# (ppm/) are ROM-derived content and are NOT uploaded.
@@ -67,7 +70,7 @@ concurrency:
cancel-in-progress: false
env:
ROM_CACHE_KEY: ge-rom-data-ntsc-v1
GE_ROM_SEED_DIR: ${{ vars.GE_ROM_SEED_DIR }}
jobs:
build-and-sweep:
@@ -79,7 +82,7 @@ jobs:
CCACHE_DIR: ${{ github.workspace }}/.ccache
CCACHE_MAXSIZE: 500M
steps:
- uses: actions/checkout@v7
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
@@ -90,7 +93,7 @@ jobs:
# no pacman -S, no network round-trip). This step still has to run
# every time — it's what registers the `msys2 {0}` shell wrapper
# above — but does no install/update work.
- uses: msys2/setup-msys2@v2
- uses: msys2/setup-msys2@ec48f7c5447b3140e2b088413ae3a55687bccb6e # v2.33.0
with:
msystem: MINGW64
release: false
@@ -101,71 +104,26 @@ jobs:
- name: Check self-hosted dependencies
run: tools_pc/check-selfhosted-deps.sh
# --- ROM + sidecars: runner-managed cache, one-time seed --------------
- name: Restore ROM + sidecars (runner cache)
uses: actions/cache/restore@v4
with:
path: |
data/ge007.ntsc-final.z64
data/pcmodels-ntsc-final
data/pccg-ntsc-final
key: ${{ env.ROM_CACHE_KEY }}
- name: Check ROM store presence
id: romcheck
run: |
present=true
for f in ge007.ntsc-final.z64 pcmodels-ntsc-final pccg-ntsc-final; do
if [ ! -f "data/$f" ]; then echo "missing from cache: $f"; present=false; fi
done
echo "present=$present" >> "$GITHUB_OUTPUT"
# --- ROM + sidecars: runner-local seed dir (never actions/cache) ------
# {runner_home} = two levels up from RUNNER_WORKSPACE ({home}/_work/{repo}).
# NOT deleted after the cache save below (see that step's comment) --
# kept as a durable fallback source until the cache save is proven to
# actually round-trip on this box.
- name: Seed ROM cache (from durable seed dir)
if: steps.romcheck.outputs.present == 'false'
# The seed dir is the only copy the workflow uses; it is never deleted.
- name: Stage ROM + sidecars (runner seed dir)
run: |
seed="$(dirname "$(dirname "$RUNNER_WORKSPACE")")/_rom-seed"
[ -d "$seed" ] || {
echo "ROM cache is empty and no seed found at $seed." >&2
echo "One-time bootstrap: copy ge007.ntsc-final.z64, pcmodels-ntsc-final," >&2
echo "and pccg-ntsc-final into that directory on the runner, then re-run." >&2
exit 2
}
seed="${GE_ROM_SEED_DIR:-$(dirname "$(dirname "$RUNNER_WORKSPACE")")/_rom-seed}"
for f in ge007.ntsc-final.z64 pcmodels-ntsc-final pccg-ntsc-final; do
[ -e "$seed/$f" ] || {
echo "missing $seed/$f" >&2
echo "One-time bootstrap: copy ge007.ntsc-final.z64, pcmodels-ntsc-final/" >&2
echo "and pccg-ntsc-final/ into $seed (or set the repo variable GE_ROM_SEED_DIR)." >&2
exit 2
}
done
mkdir -p data
# -r: pcmodels-*/pccg-* are directories, not single files (found by
# testing — a plain cp failed with "omitting directory").
cp -r "$seed/ge007.ntsc-final.z64" "$seed/pcmodels-ntsc-final" \
"$seed/pccg-ntsc-final" data/
echo "seeded ROM store from $seed"
# Explicit save (restore alone never saves): persist the seeded store
# immediately, before the build/sweep can fail out from under it.
# KNOWN ISSUE (2026-09-12): this reliably logs a WARNING annotation
# ("Failed to save: ... tar.exe failed with exit code 2") on this box
# and never actually persists anything to the cache -- but
# actions/cache/save treats a save failure as non-fatal by design, so
# the step still reports success and the job carries on. Root cause not
# yet found (see docs/dev/notes/SELFHOSTED-RUNNER-PLAN.md). Consequence:
# do NOT delete the seed dir after this step (previously done, and it
# meant a *silent* cache-save failure combined with the delete wiped
# the only copy of the ROM every run -- exactly what broke rollout
# step 5's repeated dispatches). The seed dir now stays in place
# indefinitely as a durable fallback; "Check ROM store presence" /
# "Seed ROM cache" above already re-copy from it whenever the cache
# comes back empty, so this is safe to leave as a no-op once the cache
# save is fixed for real.
- name: Save ROM cache
if: steps.romcheck.outputs.present == 'false'
uses: actions/cache/save@v4
with:
path: |
data/ge007.ntsc-final.z64
data/pcmodels-ntsc-final
data/pccg-ntsc-final
key: ${{ env.ROM_CACHE_KEY }}
echo "staged ROM store from $seed"
- name: Verify ROM integrity (committed US sha1)
run: |
@@ -179,7 +137,7 @@ jobs:
# Same opt-in ccache CMakeLists.txt wires up (speed-ups plan Step 5);
# persisted via actions/cache like ci.yml's windows-build.
- name: Restore ccache
uses: actions/cache/restore@v4
uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
with:
path: ${{ env.CCACHE_DIR }}
key: ccache-selfhosted-${{ hashFiles('CMakeLists.txt') }}-${{ github.sha }}
@@ -197,8 +155,16 @@ jobs:
# symbolication -> pixcount -> framediff vs tools_pc/golden/. Serialized
# + watchdog + one retry by design (D117: not frame-deterministic).
- name: Level sweep (all 21, or dispatch subset)
env:
INPUT_LEVELS: ${{ inputs.levels }}
run: |
[ -n "${{ inputs.levels }}" ] && export SWEEP_LEVELS='${{ inputs.levels }}'
if [ -n "$INPUT_LEVELS" ]; then
if ! printf '%s' "$INPUT_LEVELS" | grep -Eq '^[A-Za-z0-9]+:[0-9]+( [A-Za-z0-9]+:[0-9]+)*$'; then
echo "levels input must be space-separated Name:NN entries, e.g. 'Dam:33 Facility:34'" >&2
exit 1
fi
export SWEEP_LEVELS="$INPUT_LEVELS"
fi
tools_pc/verify.sh sweep --json > sweep.log 2>&1
rc=$?
cat sweep.log
@@ -223,7 +189,7 @@ jobs:
# Console logs + verdict only — no frames, no ROM bytes (leak rules).
- name: Upload sweep report
if: always()
uses: actions/upload-artifact@v7
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: selfhosted-sweep-${{ github.run_number }}
path: |