mirror of
https://github.com/jkdansereau/goldeneye-pc-port.git
synced 2026-10-24 00:02:45 +02:00
* ci: route windows-build to self-hosted runner (G2); land ROM-gated sweep workflow (G1)
G2: windows-build now runs on the self-hosted box (corpyvt6agent01) for
push/workflow_dispatch, using local ccache instead of the actions/cache
round-trip and skipping msys2/setup-msys2's install once packages are
already present. pull_request always stays on windows-latest — fork PRs
must never reach a box that will hold a ROM.
G1: adds .github/workflows/selfhosted.yml, a dispatch-only workflow that
builds + runs the 21-level headless sweep (tools_pc/verify.sh sweep --json)
against a runner-cached ROM. Inert until manually dispatched.
Still pending (manual, physical steps on the box — not done by this
commit, see docs/dev/notes/SELFHOSTED-RUNNER-PLAN.md rollout table):
- register corpyvt6agent01 as a runner against this repo
- confirm MSYS2 at C:\msys64 with the required mingw64 package set
- one-time ROM seed into {runner_home}/_rom-seed/
- first workflow_dispatch sweep + parity check against a local run
- flip G1 from workflow_dispatch to push:[main] once green
Claude-Session: https://claude.ai/code/session_01J5PZ3sTHiuW6MdQnepasSU
* fix(selfhosted.yml): remove invalid concurrency.max-parallel key
Found by testing: dispatching the workflow failed with a hard parse
error (HTTP 422, "Unexpected value 'max-parallel'"). GitHub Actions'
workflow-level `concurrency` block only supports `group` and
`cancel-in-progress` — `max-parallel` is a job `strategy:` key for
matrix jobs, not a concurrency-block key. Serialization was already
achieved via group + cancel-in-progress:false; the stray key just
blocked every dispatch.
Claude-Session: https://claude.ai/code/session_01J5PZ3sTHiuW6MdQnepasSU
* fix(selfhosted.yml): register the msys2 shell wrapper (setup-msys2 step)
Found by testing: the first fixed dispatch failed every msys2-shell step
with "msys2: command not found". Unlike ci.yml's windows-build, this
workflow used `shell: msys2 {0}` without ever running msys2/setup-msys2,
which is what registers that shell alias for the runner — MSYS2 being
pre-installed on the box doesn't help if Actions doesn't know the shell
exists. Adds the same setup-msys2 step ci.yml uses, with update:false
since the packages are expected already present (fast no-op per plan).
Claude-Session: https://claude.ai/code/session_01J5PZ3sTHiuW6MdQnepasSU
* ci: stop reinstalling MSYS2 per run on the self-hosted box
The self-hosted paths (selfhosted.yml; ci.yml windows-build's push/
dispatch route) no longer call msys2/setup-msys2 or pacman -S at all.
MSYS2 + the mingw64 package set are now assumed hand-maintained on
corpyvt6agent01 (docs/dev/notes/SELFHOSTED-RUNNER-PLAN.md), invoked by
calling its bash directly (`C:\msys64\usr\bin\bash.exe -leo pipefail
"{0}"`, the same invocation setup-msys2's generated wrapper uses) with
MSYSTEM=MINGW64 so /etc/profile still puts mingw64/bin on PATH.
Adds tools_pc/check-selfhosted-deps.sh: a fast, install-free check that
exits 0 immediately when the required packages (toolchain, cmake,
SDL2, zlib, python, ccache, zip, unzip) are present, or fails with the
exact `pacman -S --needed ...` line to run otherwise — so a missing
package on the box surfaces immediately with a clear fix, instead of
as a confusing failure deeper in the build.
ci.yml's windows-latest (PR) path is unchanged: ephemeral runners still
get a full msys2/setup-msys2 install every time, since there's nothing
to persist there.
Claude-Session: https://claude.ai/code/session_01J5PZ3sTHiuW6MdQnepasSU
* fix: use msys2/setup-msys2 release:false instead of a raw bash-path shell
The previous attempt (invoking C:\msys64\usr\bin\bash.exe directly as a
custom `shell:` command) failed on the actual runner with "Second path
fragment must not be a drive or UNC name" — a real limitation, not a
typo; it failed identically in both files, including the one with a
static (non-templated) shell string, so it wasn't the ${{ }} expression
either.
Root-caused by reading msys2/setup-msys2's actual source: `release:
false` makes it reuse the existing C:\msys64 as-is (hardcoded path in
that branch, confirmed in main.js) instead of downloading+installing a
fresh copy, and — verified in the same source — omitting `update` and
`install` skips every pacman call entirely (just one `uname -a` + a
pacman.conf sed tweak, no network). This is the officially documented
mechanism for self-hosted runners with a pre-existing MSYS2 install
(see the action's README, "release" section).
ci.yml's windows-build now runs setup-msys2 unconditionally but with
release/update/install all keyed off github.event_name: full install on
windows-latest (PR, ephemeral), reuse-only on the self-hosted box
(push/dispatch). selfhosted.yml always uses release:false. Both then
run tools_pc/check-selfhosted-deps.sh to verify the box's hand-
maintained packages are actually present.
Claude-Session: https://claude.ai/code/session_01J5PZ3sTHiuW6MdQnepasSU
* fix(selfhosted.yml): cp -r for the ROM sidecar directories
Found by testing with the ROM seed actually in place: pcmodels-ntsc-final
and pccg-ntsc-final are directories (not single files, unlike
ge007.ntsc-final.z64), so a plain `cp` failed with "omitting directory"
and left the seed step failing on every run even with the seed populated.
Claude-Session: https://claude.ai/code/session_01J5PZ3sTHiuW6MdQnepasSU
* ci: drive MSYS2 MINGW64 directly via ci-shell.cmd, drop msys2 shell shim
The self-hosted runs were dying with 'msys2: command not found' because the
msys2/setup-msys2 action's shell shim was never registered on the box. Replace
the dependency on that shim with a small committed launcher (tools_pc/ci-shell.cmd)
that headlessly reproduces the local 'MSYS2 MINGW64' terminal:
- MSYSTEM=MINGW64 + /mingw64/bin on PATH
- NON-login bash, so it keeps the workspace cwd (a login shell cd's to $HOME
and would break every relative path in the workflow)
- -e -o pipefail for GitHub-style error propagation
Both workflows now set defaults.run.shell to C:\msys64\ci-shell.cmd {0}; a
bootstrap step (shell: cmd) refreshes the launcher from the repo into C:\msys64
each run. selfhosted.yml drops setup-msys2 entirely; ci.yml keeps it only for
the ephemeral windows-latest PR path (which installs MSYS2 at C:\msys64).
.gitattributes: force CRLF for *.cmd so cmd.exe parses the launcher correctly.
* Revert "ci: drive MSYS2 MINGW64 directly via ci-shell.cmd, drop msys2 shell shim"
This reverts commit a976b2589c.
* docs(D244): log self-hosted-runner link failure — undefined reference to objectiveGetStatus_WEAK
First real build attempt on the reinstalled corpyvt6agent01 box (run
34707798707) fails at link with an unresolved #pragma weak alias. A local
repro of the identical alias pattern links fine on current MSYS2
(gcc 16.2.0/binutils 2.47); the box reports gcc 16.1.0 — likely a stale
toolchain, consistent with rollout step 2's earlier package-hygiene gap.
Claude-Session: https://claude.ai/code/session_01CUFSnpgrAyQSDVHoQQ6Sx3
* fix(verify.sh): surface run.log tail on NO-FRAMES instead of silently discarding it
sweep mode's per-level run.log (the game process's own stdout/stderr, where
an SDL/GL init failure would show up) was captured into a mktemp capdir but
unconditionally rm -rf'd with no diagnostic ever printed for the NO-FRAMES
(no-crash) case -- every level failed this way on the self-hosted runner's
first real sweep attempt with zero clue why.
Claude-Session: https://claude.ai/code/session_01CUFSnpgrAyQSDVHoQQ6Sx3
* fix(selfhosted.yml): stop deleting the ROM seed dir -- cache save silently fails on this box
actions/cache/save has been failing to persist the ROM cache entry on
corpyvt6agent01 (WARNING annotation, tar.exe exit code 2) but doesn't fail
the step -- by design, a cache-save failure is non-fatal, so the workflow
carried on and the now-unconditional "Delete one-time seed dir" step wiped
the only copy of the ROM every single run. Every dispatch since has failed
at "Seed ROM cache" with an empty seed dir and an empty cache -- exactly
the user-reported "it wipes out the ROM data each run".
Fix: don't delete the seed dir. It's cheap disk (three files, a few hundred
MB) and the existing restore-then-seed-if-missing logic already treats it as
the fallback source whenever the cache comes back empty, so leaving it in
place is safe and makes the workflow tolerant of the cache-save bug until
that's root-caused separately.
Claude-Session: https://claude.ai/code/session_01CUFSnpgrAyQSDVHoQQ6Sx3
* fix(verify.sh): sweep --json never actually produced a verdict array; fix NO-FRAMES diagnostic clipping it further
Two bugs, found together while chasing the self-hosted runner's first real
sweep attempt:
1. sweep mode's `out=$(verify_level ...); echo "$out" | head -1` always
discarded emit_verdict's second (--json) output line -- RESULTS_JSON was
declared for assembling a verdict array but never populated or printed,
so `sweep --json` has never produced anything but `[]` for the
workflow's "Extract JSON verdict" step. Now builds and prints a real
`[{...}, {...}]` array before the RC exit.
2. My own D244-session addition (printing a NO-FRAMES level's run.log tail)
wrote to stdout, which the same `out=$(...)/head -1` capture turned into
the *new* first line, clipping the real verdict summary. Moved to stderr,
which bypasses that capture.
Claude-Session: https://claude.ai/code/session_01CUFSnpgrAyQSDVHoQQ6Sx3
* docs: regenerate findings-index.csv for D244
Claude-Session: https://claude.ai/code/session_01CUFSnpgrAyQSDVHoQQ6Sx3
354 lines
15 KiB
YAML
354 lines
15 KiB
YAML
name: CI
|
|
|
|
on:
|
|
push:
|
|
branches: [ main, master ]
|
|
tags: [ 'v*' ]
|
|
# No paths-ignore here: tag pushes must always build so a release can be
|
|
# cut even when the tagged commit only touched docs, and a workflow that
|
|
# never triggers would leave a required status check pending forever.
|
|
# Docs-only branch pushes are instead skipped by the `changes` job below,
|
|
# which reports the build jobs as "skipped" (green for branch protection).
|
|
pull_request:
|
|
# No paths-ignore here either: a docs-only PR must still trigger the
|
|
# workflow so the required checks report a status. The `changes` job
|
|
# below diffs the PR against its base and, for a docs-only PR, reports
|
|
# the build jobs as "skipped" — which branch protection accepts as
|
|
# success. With paths-ignore the workflow never ran and the required
|
|
# checks stayed "expected" forever, wedging every docs PR (M-44).
|
|
workflow_dispatch:
|
|
|
|
# Minimal token: CI only reads the repo and uploads build artifacts, neither of
|
|
# which needs write access. Fork PRs run untrusted build scripts on the runner,
|
|
# so keep the granted scope as small as possible and never expose secrets here.
|
|
permissions:
|
|
contents: read
|
|
|
|
concurrency:
|
|
group: ci-${{ github.ref }}
|
|
cancel-in-progress: true
|
|
|
|
# Jobs:
|
|
#
|
|
# linux-build — ubuntu, system GCC. Actually compiles + links (unlike
|
|
# validate), then packages the Linux bundle (exe + README +
|
|
# licenses + prepare-assets, NO ROM / assets / bundled libs)
|
|
# via tools_pc/bundle-linux.sh and uploads it. Surfaces
|
|
# GCC-on-Linux strictness gaps MinGW misses. Not a runtime
|
|
# claim; not a required check yet.
|
|
#
|
|
# validate — ubuntu, configure-only. Byte-compiles the tooling,
|
|
# regenerates the US ROM-asset symbol file, and CMake-
|
|
# configures ntsc-final (REGION_DEFS, the source list, and
|
|
# that SDL2 / zlib / OpenGL are discoverable). No ROM is used.
|
|
# Does NOT compile; running on ubuntu is NOT a claim the port
|
|
# works on Linux.
|
|
#
|
|
# windows-build — windows/MSYS2, the real supported platform. Compiles and
|
|
# links the full executable, then packages the distributable
|
|
# bundle (exe + runtime DLLs + README + licenses, NO ROM /
|
|
# assets) via tools_pc/bundle-win.sh and uploads it. Neither
|
|
# the ROM nor extracted assets are needed to BUILD (they are
|
|
# runtime-only), so CI builds but never runs the port.
|
|
#
|
|
# release — tags only (v*). Downloads the Windows + Linux bundles and
|
|
# attaches both to a DRAFT pre-release for that tag. Draft, so
|
|
# a human does the ROM smoke-test on each platform and hits
|
|
# Publish. This is the only job granted contents: write.
|
|
|
|
jobs:
|
|
# Did this change touch anything outside docs / licenses? No workflow-level
|
|
# paths-ignore exists (see the `on:` comments), so this job is the single
|
|
# place a docs-only push OR pull request is filtered out — a PR is diffed
|
|
# against its base sha, a branch push against `github.event.before`. Tag
|
|
# builds always run. Docs globs: **.md, docs/**, LICENSE, NOTICE.
|
|
changes:
|
|
runs-on: ubuntu-22.04
|
|
outputs:
|
|
code: ${{ steps.filter.outputs.code }}
|
|
steps:
|
|
- uses: actions/checkout@v7
|
|
with:
|
|
persist-credentials: false
|
|
fetch-depth: 0
|
|
|
|
- id: filter
|
|
run: |
|
|
if [ "${{ github.event_name }}" = "pull_request" ]; then
|
|
base='${{ github.event.pull_request.base.sha }}'
|
|
head='${{ github.event.pull_request.head.sha }}'
|
|
elif [ "${{ github.event_name }}" != "push" ] || [ "${GITHUB_REF_TYPE}" = "tag" ]; then
|
|
echo "code=true" >> "$GITHUB_OUTPUT"; exit 0
|
|
else
|
|
base='${{ github.event.before }}'
|
|
head='${{ github.sha }}'
|
|
fi
|
|
if ! git cat-file -e "${base}^{commit}" 2>/dev/null || ! git cat-file -e "${head}^{commit}" 2>/dev/null; then
|
|
echo "no usable base ${base}/head ${head} — building to be safe"
|
|
echo "code=true" >> "$GITHUB_OUTPUT"; exit 0
|
|
fi
|
|
changed="$(git diff --name-only "$base" "$head")"
|
|
echo "Changed files:"; echo "$changed"
|
|
if echo "$changed" | grep -qvE '(\.md$|^docs/|^LICENSE$|^NOTICE$)'; then
|
|
echo "code=true" >> "$GITHUB_OUTPUT"
|
|
else
|
|
echo "docs-only push — skipping build"
|
|
echo "code=false" >> "$GITHUB_OUTPUT"
|
|
fi
|
|
|
|
validate:
|
|
needs: changes
|
|
if: needs.changes.outputs.code == 'true'
|
|
runs-on: ubuntu-22.04
|
|
steps:
|
|
- uses: actions/checkout@v7
|
|
with:
|
|
persist-credentials: false
|
|
|
|
- name: Install dependencies
|
|
run: |
|
|
sudo apt-get update
|
|
sudo apt-get install -y cmake python3 libsdl2-dev zlib1g-dev libgl1-mesa-dev
|
|
|
|
- name: Byte-compile Python tooling
|
|
run: python3 -m compileall -q scripts tools_pc
|
|
|
|
# Generated dev-docs stay in sync with the tree (speed-ups plan Step 4).
|
|
- name: Check generated dev indexes are current
|
|
run: |
|
|
python3 tools_pc/gen_findings_index.py --check
|
|
python3 tools_pc/gen_env_probes.py --check
|
|
|
|
# US only. gen_romassets.py resolves every symbol for the US region from
|
|
# the committed CSVs with no ROM present; PAL/JP each need a handful of
|
|
# region-specific prop/font offsets that only come from that region's ROM
|
|
# (see docs/building.md — PAL/JP builders generate romassets_e/j.s
|
|
# locally). No ROM is used or required here.
|
|
- name: Regenerate ROM-asset symbol file (US)
|
|
run: |
|
|
python3 scripts/gen_romassets.py u
|
|
git diff --stat -- port/src/romassets_u.s
|
|
|
|
- name: CMake configure (ntsc-final)
|
|
run: cmake -S . -B build-ntsc -DROMID=ntsc-final
|
|
|
|
# Linux (Ubuntu, system GCC) compile job. Unlike `validate` this actually
|
|
# runs `cmake --build`, so it surfaces the GCC-on-Linux strictness gaps that
|
|
# MinGW does not flag. The port has never been run on Linux — a green build
|
|
# here is a "does it compile + link" signal only, not a runtime claim.
|
|
# Not a required check yet; flip it to required once it is reliably green.
|
|
#
|
|
# Toolchain: ubuntu-24.04 + gcc-14. The port is developed on MinGW GCC 16;
|
|
# pinning a recent GCC here keeps the first bring-up focused on real
|
|
# portability gaps rather than a decade of accumulated old-GCC pedantry.
|
|
# (A "does it build on the GCC a typical distro ships" pass can come later.)
|
|
linux-build:
|
|
runs-on: ubuntu-24.04
|
|
env:
|
|
CC: gcc-14
|
|
CXX: g++-14
|
|
# CMakeLists.txt opt-in enables CMAKE_{C,CXX}_COMPILER_LAUNCHER=ccache
|
|
# when ccache is on PATH (b4de1c68, speed-ups plan Step 5). Game
|
|
# sources are frozen (1:1 with the decomp), so after the first run only
|
|
# touched port/ files miss cache -- near-total hit rate.
|
|
CCACHE_DIR: ${{ github.workspace }}/.ccache
|
|
CCACHE_MAXSIZE: 500M
|
|
steps:
|
|
- uses: actions/checkout@v7
|
|
with:
|
|
persist-credentials: false
|
|
|
|
- name: Install dependencies
|
|
run: |
|
|
sudo apt-get update
|
|
sudo apt-get install -y build-essential gcc-14 g++-14 cmake python3 \
|
|
libsdl2-dev zlib1g-dev libgl1-mesa-dev ccache
|
|
|
|
- name: Restore ccache
|
|
uses: actions/cache@v4
|
|
with:
|
|
path: ${{ env.CCACHE_DIR }}
|
|
key: ccache-linux-${{ hashFiles('CMakeLists.txt') }}-${{ github.sha }}
|
|
restore-keys: |
|
|
ccache-linux-${{ hashFiles('CMakeLists.txt') }}-
|
|
ccache-linux-
|
|
|
|
- name: Regenerate ROM-asset symbol file (US)
|
|
run: python3 scripts/gen_romassets.py u
|
|
|
|
- name: Configure (ntsc-final)
|
|
run: cmake -S . -B build-linux -DROMID=ntsc-final
|
|
-DCMAKE_C_COMPILER=gcc-14 -DCMAKE_CXX_COMPILER=g++-14
|
|
|
|
- name: Build (ntsc-final)
|
|
run: cmake --build build-linux -j"$(nproc)"
|
|
|
|
- name: ccache stats
|
|
run: ccache -s
|
|
|
|
- name: Show binary
|
|
run: |
|
|
ls -la build-linux/ge007* || true
|
|
file build-linux/ge007* || true
|
|
|
|
# Package the Linux bundle on every run so the release path stays
|
|
# exercised. No shared libs are bundled — the README tells the user to
|
|
# install SDL2 / zlib / libGL from their distro. Same ROM / size guards
|
|
# as the Windows bundle.
|
|
- name: Package Linux bundle
|
|
run: |
|
|
if [ "${GITHUB_REF_TYPE}" = "tag" ]; then
|
|
V="${GITHUB_REF_NAME}"
|
|
else
|
|
V="0.0.0-ci.${GITHUB_SHA::7}"
|
|
fi
|
|
tools_pc/bundle-linux.sh "$V"
|
|
|
|
- name: Upload bundle
|
|
uses: actions/upload-artifact@v7
|
|
with:
|
|
name: goldeneye-pc-port-linux-x86_64
|
|
path: |
|
|
dist/*.tar.gz
|
|
dist/*.tar.gz.sha256
|
|
if-no-files-found: error
|
|
retention-days: 14
|
|
|
|
# Real Windows (MSYS2 MINGW64) build — the only platform the port is
|
|
# developed and tested on. This compiles and LINKS the full executable.
|
|
#
|
|
# No ROM and no extracted assets are needed to build: the compiled asset set
|
|
# is a handful of committed pure-data .c files plus the generated
|
|
# address-constant romassets_<region>.s. The ROM (.z64) and the ROM-derived
|
|
# blobs are runtime-only dependencies — CI cannot run the game, only build it.
|
|
windows-build:
|
|
needs: changes
|
|
if: needs.changes.outputs.code == 'true'
|
|
# Self-hosted for push/workflow_dispatch (fast, local ccache); fork PRs
|
|
# always stay on windows-latest — untrusted PR code must never reach a
|
|
# box that will later hold a ROM (docs/dev/notes/SELFHOSTED-RUNNER-PLAN.md §G2).
|
|
runs-on: ${{ github.event_name == 'pull_request' && 'windows-latest' || fromJSON('["self-hosted", "windows"]') }}
|
|
defaults:
|
|
run:
|
|
shell: msys2 {0}
|
|
env:
|
|
# Same opt-in ccache CMakeLists.txt already wires up (Step 5). Note:
|
|
# this cache path is read/written by the JS actions/cache step outside
|
|
# the msys2 shell too, so it stays a plain workspace-relative path
|
|
# rather than an msys /c/... form.
|
|
CCACHE_DIR: ${{ github.workspace }}/.ccache
|
|
CCACHE_MAXSIZE: 500M
|
|
steps:
|
|
- uses: actions/checkout@v7
|
|
with:
|
|
persist-credentials: false
|
|
|
|
# windows-latest (PR) is ephemeral: full install + update every run.
|
|
# Self-hosted (push/dispatch): `release: false` reuses the box's own
|
|
# C:\msys64 as-is and, with update/install both empty here, does no
|
|
# pacman -Syu / pacman -S at all (verified against the action's source)
|
|
# — it only registers the `msys2 {0}` shell wrapper every job needs.
|
|
# Packages themselves are hand-maintained on the box; the dependency
|
|
# check below (not this step) is what verifies they're present.
|
|
- uses: msys2/setup-msys2@v2
|
|
with:
|
|
msystem: MINGW64
|
|
release: ${{ github.event_name == 'pull_request' }}
|
|
update: ${{ github.event_name == 'pull_request' }}
|
|
install: ${{ github.event_name == 'pull_request' && 'mingw-w64-x86_64-toolchain mingw-w64-x86_64-cmake mingw-w64-x86_64-SDL2 mingw-w64-x86_64-zlib mingw-w64-x86_64-python mingw-w64-x86_64-ccache zip unzip' || '' }}
|
|
|
|
# Self-hosted only: fails fast with exact install instructions if the
|
|
# box's hand-maintained MSYS2 is missing a required package, instead of
|
|
# a confusing failure deeper in the build. windows-latest just installed
|
|
# everything above, so this would be redundant there.
|
|
- name: Check self-hosted dependencies
|
|
if: github.event_name != 'pull_request'
|
|
run: tools_pc/check-selfhosted-deps.sh
|
|
|
|
- name: Restore ccache
|
|
uses: actions/cache@v4
|
|
with:
|
|
path: ${{ env.CCACHE_DIR }}
|
|
key: ccache-windows-${{ hashFiles('CMakeLists.txt') }}-${{ github.sha }}
|
|
restore-keys: |
|
|
ccache-windows-${{ hashFiles('CMakeLists.txt') }}-
|
|
ccache-windows-
|
|
|
|
- name: Regenerate ROM-asset symbol file (US)
|
|
run: python scripts/gen_romassets.py u
|
|
|
|
- name: Build (ntsc-final)
|
|
run: ./build-pc.sh ntsc-final
|
|
|
|
- name: ccache stats
|
|
run: ccache -s
|
|
|
|
# Package the distributable bundle on every run so the release path is
|
|
# always exercised. On a tag build VERSION is the tag; otherwise it is a
|
|
# throwaway CI string. bundle-win.sh hard-fails if a ROM image or an
|
|
# oversized blob ends up inside the bundle.
|
|
- name: Package Windows bundle
|
|
run: |
|
|
if [ "${GITHUB_REF_TYPE}" = "tag" ]; then
|
|
V="${GITHUB_REF_NAME}"
|
|
else
|
|
V="0.0.0-ci.${GITHUB_SHA::7}"
|
|
fi
|
|
tools_pc/bundle-win.sh "$V"
|
|
|
|
- name: Upload bundle
|
|
uses: actions/upload-artifact@v7
|
|
with:
|
|
name: goldeneye-pc-port-win64
|
|
path: |
|
|
dist/*.zip
|
|
dist/*.zip.sha256
|
|
if-no-files-found: error
|
|
retention-days: 14
|
|
|
|
# CI builds and packages the executable but does not run it — running the
|
|
# port needs a ROM, which CI does not provide. Runtime checks (the
|
|
# -level_09 soak, a golden-frame diff) would run on a self-hosted runner
|
|
# instead. Not planned.
|
|
|
|
# Tags only. Attach the packaged Windows + Linux bundles to a DRAFT
|
|
# pre-release so a human can do the ROM smoke-test on each platform before
|
|
# publishing. This job — and only this job — gets contents: write.
|
|
release:
|
|
if: github.ref_type == 'tag'
|
|
needs: [ changes, validate, windows-build, linux-build ]
|
|
runs-on: ubuntu-22.04
|
|
permissions:
|
|
contents: write
|
|
steps:
|
|
- uses: actions/checkout@v7
|
|
with:
|
|
persist-credentials: false
|
|
|
|
- uses: actions/download-artifact@v7
|
|
with:
|
|
name: goldeneye-pc-port-win64
|
|
path: dist
|
|
|
|
- uses: actions/download-artifact@v7
|
|
with:
|
|
name: goldeneye-pc-port-linux-x86_64
|
|
path: dist
|
|
|
|
- name: Create or update draft pre-release
|
|
env:
|
|
GH_TOKEN: ${{ github.token }}
|
|
run: |
|
|
TAG="${GITHUB_REF_NAME}"
|
|
ASSETS=(dist/*.zip dist/*.zip.sha256 dist/*.tar.gz dist/*.tar.gz.sha256)
|
|
if gh release view "$TAG" >/dev/null 2>&1; then
|
|
gh release upload "$TAG" "${ASSETS[@]}" --clobber
|
|
else
|
|
NOTES="$(mktemp)"
|
|
sed "s/<version>/${TAG}/g" .github/release-notes.md > "$NOTES"
|
|
gh release create "$TAG" "${ASSETS[@]}" \
|
|
--draft --prerelease \
|
|
--title "GoldenEye 007 PC Port $TAG" \
|
|
--notes-file "$NOTES"
|
|
fi
|