mirror of
https://github.com/jkdansereau/goldeneye-pc-port.git
synced 2026-10-24 00:02:45 +02:00
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
201 lines
8.8 KiB
YAML
201 lines
8.8 KiB
YAML
# Self-hosted runtime (ROM-gated)
|
|
#
|
|
# Runs the build + the 21-level headless sweep (tools_pc/verify.sh) on the
|
|
# self-hosted runner "corpyvt6agent01", the one machine that has a legal ROM.
|
|
# This is the job class ci.yml explicitly does NOT do: CI is build-only, no
|
|
# ROM, so runtime checks live here. Setup + rollout plan (gitignored, local):
|
|
# docs/dev/notes/SELFHOSTED-RUNNER-PLAN.md
|
|
#
|
|
# 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 -> 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
|
|
# registers the `msys2 {0}` shell wrapper), but with
|
|
# `release: false` and update/install both omitted — verified
|
|
# against the action's source to do no pacman -Syu / pacman -S
|
|
# / network round-trip, just a fast reuse of the existing
|
|
# C:\msys64. Package presence is checked (not installed) by
|
|
# tools_pc/check-selfhosted-deps.sh, which fails fast with
|
|
# exact install instructions if something's missing.
|
|
#
|
|
# Trigger gating (non-negotiable):
|
|
# - workflow_dispatch ONLY for now. Flip on `push: branches: [main]` once
|
|
# the first manual runs are reliably green.
|
|
# - NEVER add `pull_request`: unreviewed fork code must not be routable to
|
|
# a runner that can see the ROM.
|
|
#
|
|
# Leak rules (docs/dev/notes/AGENT-VM-FORGEJO-PLAN.md checklist):
|
|
# - 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.
|
|
|
|
name: Self-hosted runtime
|
|
|
|
on:
|
|
workflow_dispatch:
|
|
inputs:
|
|
levels:
|
|
description: "Sweep subset, SWEEP_LEVELS format (blank = all 21)"
|
|
required: false
|
|
default: ""
|
|
type: string
|
|
|
|
permissions:
|
|
contents: read
|
|
|
|
# One ROM job at a time per ref; never cancel an in-flight sweep out from
|
|
# under itself (the sweep is serialized by its own lockdir + watchdog). Group
|
|
# + cancel-in-progress:false is what actually serializes runs — GitHub
|
|
# Actions' workflow-level `concurrency` has no `max-parallel` key (that only
|
|
# exists under a job's `strategy:` for matrix jobs); a stray one here is a
|
|
# hard parse error that blocks every dispatch.
|
|
concurrency:
|
|
group: selfhosted-${{ github.ref }}
|
|
cancel-in-progress: false
|
|
|
|
env:
|
|
GE_ROM_SEED_DIR: ${{ vars.GE_ROM_SEED_DIR }}
|
|
|
|
jobs:
|
|
build-and-sweep:
|
|
runs-on: [ self-hosted, windows ]
|
|
defaults:
|
|
run:
|
|
shell: msys2 {0}
|
|
env:
|
|
CCACHE_DIR: ${{ github.workspace }}/.ccache
|
|
CCACHE_MAXSIZE: 500M
|
|
steps:
|
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
with:
|
|
persist-credentials: false
|
|
|
|
# `release: false` reuses the box's own C:\msys64 as-is instead of
|
|
# downloading/installing MSYS2 fresh (verified against the action's
|
|
# source: with this set, and update/install both omitted, it does
|
|
# exactly one `uname -a` + a pacman.conf sed tweak — no pacman -Syu,
|
|
# 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@ec48f7c5447b3140e2b088413ae3a55687bccb6e # v2.33.0
|
|
with:
|
|
msystem: MINGW64
|
|
release: false
|
|
|
|
# Packages themselves are hand-maintained on the box (never installed
|
|
# by this workflow) — fails fast with exact install instructions if
|
|
# one's missing, instead of a confusing failure deeper in the build.
|
|
- name: Check self-hosted dependencies
|
|
run: tools_pc/check-selfhosted-deps.sh
|
|
|
|
# --- ROM + sidecars: runner-local seed dir (never actions/cache) ------
|
|
# {runner_home} = two levels up from RUNNER_WORKSPACE ({home}/_work/{repo}).
|
|
# The seed dir is the only copy the workflow uses; it is never deleted.
|
|
- name: Stage ROM + sidecars (runner seed dir)
|
|
run: |
|
|
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 "staged ROM store from $seed"
|
|
|
|
- name: Verify ROM integrity (committed US sha1)
|
|
run: |
|
|
cd data
|
|
want="$(cut -d' ' -f1 ../ge007.u.sha1)"
|
|
got="$(sha1sum ge007.ntsc-final.z64 | cut -d' ' -f1)"
|
|
[ "$want" = "$got" ] || { echo "ROM hash mismatch: want $want got $got" >&2; exit 2; }
|
|
echo "ROM sha1 ok: $got"
|
|
|
|
# --- build -------------------------------------------------------------
|
|
# 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@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
|
|
with:
|
|
path: ${{ env.CCACHE_DIR }}
|
|
key: ccache-selfhosted-${{ hashFiles('CMakeLists.txt') }}-${{ github.sha }}
|
|
restore-keys: |
|
|
ccache-selfhosted-${{ hashFiles('CMakeLists.txt') }}-
|
|
ccache-selfhosted-
|
|
|
|
- name: Regenerate ROM-asset symbol file (US)
|
|
run: python scripts/gen_romassets.py u
|
|
|
|
- name: Build (ntsc-final)
|
|
run: ./build-pc.sh ntsc-final
|
|
|
|
# verify.sh: build-if-stale -> headless GE_PCDUMP per level -> crash
|
|
# 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: |
|
|
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
|
|
exit $rc
|
|
|
|
# Pull the JSON verdict array out of the mixed stdout for easy review.
|
|
- name: Extract JSON verdict
|
|
if: always()
|
|
run: |
|
|
python -c "
|
|
import json, sys
|
|
s = open('sweep.log', encoding='utf-8', errors='replace').read()
|
|
i = s.rfind('[{')
|
|
out = '[]'
|
|
if i >= 0:
|
|
d, _ = json.JSONDecoder().raw_decode(s[i:])
|
|
out = json.dumps(d, indent=1)
|
|
open('sweep-verdict.json', 'w').write(out + '\n')
|
|
print(out)
|
|
"
|
|
|
|
# Console logs + verdict only — no frames, no ROM bytes (leak rules).
|
|
- name: Upload sweep report
|
|
if: always()
|
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
with:
|
|
name: selfhosted-sweep-${{ github.run_number }}
|
|
path: |
|
|
sweep.log
|
|
sweep-verdict.json
|
|
ge007.crash.log
|
|
if-no-files-found: ignore
|
|
retention-days: 14
|