Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 66 additions & 4 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,26 @@ jobs:
if (-not (Test-Path $p)) { throw "Missing release artifact: $n" }
}

# The bare hub archive (docs/RELEASES.md): the flat hub prefix
# scripts/build-local.ps1 writes, built as THIS release, then archived and
# gated by scripts/package_bare_hub.py (the archived hub must run and report
# this version). A second build of the hub, in its own tree, so the
# installer above is untouched.
- name: Package bare hub archive
shell: pwsh
run: |
./scripts/build-local.ps1 -ReleaseVersion "${{ needs.version.outputs.version }}" `
-Out (Join-Path $PWD "out\flat") -Build (Join-Path $PWD "build-flat")
if ($LASTEXITCODE -ne 0) { throw "build-local.ps1 failed" }
python scripts/package_bare_hub.py `
--version "${{ needs.version.outputs.version }}" `
--platform windows-x86_64 `
--commit "$env:GITHUB_SHA" `
--prefix (Join-Path $PWD "out\flat") `
--out dist-hub
if ($LASTEXITCODE -ne 0) { throw "package_bare_hub.py failed" }
Get-ChildItem dist-hub

- uses: actions/upload-artifact@v7
with:
name: windows-x64
Expand All @@ -410,6 +430,13 @@ jobs:
dist/Retro-Launcher-windows-x64-setup.exe
retention-days: 5

- uses: actions/upload-artifact@v7
with:
name: windows-x86_64-hub
path: dist-hub/*
if-no-files-found: error
retention-days: 5

macos:
needs: version
strategy:
Expand Down Expand Up @@ -501,13 +528,35 @@ jobs:
exit 1
fi

# The bare hub archive (docs/RELEASES.md): the flat hub prefix
# scripts/build-local.sh writes, built as THIS release, archived and gated
# by scripts/package_bare_hub.py.
- name: Package bare hub archive
run: |
./scripts/build-local.sh --release-version "${{ needs.version.outputs.version }}" \
--out "$PWD/out/flat" --build "$PWD/build-flat"
python3 scripts/package_bare_hub.py \
--version "${{ needs.version.outputs.version }}" \
--platform "macos-${{ matrix.arch }}" \
--commit "${GITHUB_SHA}" \
--prefix "$PWD/out/flat" \
--out dist-hub
ls -lah dist-hub/

- uses: actions/upload-artifact@v7
with:
name: macos-${{ matrix.arch }}
path: |
dist/Retro-Launcher-macos-${{ matrix.arch }}.dmg
retention-days: 5

- uses: actions/upload-artifact@v7
with:
name: macos-${{ matrix.arch }}-hub
path: dist-hub/*
if-no-files-found: error
retention-days: 5

android:
needs: version
uses: ./.github/workflows/android.yml
Expand Down Expand Up @@ -550,18 +599,31 @@ jobs:
- name: Bare hub archive + manifest
run: |
set -euo pipefail
HUB=artifacts/linux-x86_64-hub
cp -v "${HUB}"/retro-hub-*.tar.gz "${HUB}"/retro-hub-*.tar.gz.sha256 dist/
# One bare archive per platform: linux-x86_64, windows-x86_64 and
# macos-{arm64,x86_64}. hub_manifest.py refuses a release in which they
# disagree on version, commit or the Direct-mode contract.
PLATFORMS="linux-x86_64 windows-x86_64 macos-arm64 macos-x86_64"
ENTRIES=()
for p in ${PLATFORMS}; do
HUB="artifacts/${p}-hub"
test -d "${HUB}" || { echo "::error::no bare hub archive artifact for ${p}" >&2; exit 1; }
cp -v "${HUB}"/retro-hub-*.tar.gz "${HUB}"/retro-hub-*.zip dist/ 2>/dev/null || true
cp -v "${HUB}"/retro-hub-*.sha256 dist/
ENTRIES+=("${HUB}"/retro-hub-*.json)
done
python3 scripts/hub_manifest.py \
--version "${{ needs.version.outputs.version }}" \
--tag "${{ needs.version.outputs.tag }}" \
--repo "${GITHUB_REPOSITORY}" \
--expect linux-x86_64 \
--expect "${PLATFORMS// /,}" \
--out dist \
"${HUB}"/retro-hub-*.json
"${ENTRIES[@]}"
# Every archive must still match the hash its build recorded.
(cd dist && sha256sum -c SHA256SUMS)
test -f "dist/retro-hub-${{ needs.version.outputs.version }}-linux-x86_64.tar.gz"
test -f "dist/retro-hub-${{ needs.version.outputs.version }}-windows-x86_64.zip"
test -f "dist/retro-hub-${{ needs.version.outputs.version }}-macos-arm64.tar.gz"
test -f "dist/retro-hub-${{ needs.version.outputs.version }}-macos-x86_64.tar.gz"
test -f dist/hub-manifest.json

- name: Ensure release tag exists
Expand Down
26 changes: 19 additions & 7 deletions docs/RELEASES.md
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,7 @@ module ABI, or a package that records none, is not second-guessed.
| Game | the newest release of title.json `update.github` | nothing: the game package is generated from the player's ROM and is never published. A newer release is reported with a link to it, to rebuild the app from. | -- |
| Core | n64lle's `n64lle-release-manifest.json` ([n64lle docs/RELEASES.md](https://github.com/RetroPortingToolKit/n64lle/blob/main/docs/RELEASES.md) §5), for a title whose core is n64lle's generic core | `<data dir>/core/<version>/`: the core library, its `.rcore.toml` and `installed.json` (module ABI), taken from the release prefix | after a restart |
| Runner | Retro-Runtime's `runtime-manifest.json` (the runtime updater, unchanged rules) | `<data dir>/runtime/<version>/` | from the next Play |
| Hub | this repo's `hub-manifest.json` (below), Linux only for now | `<data dir>/hub/<version>/`, the bare hub archive | after a restart |
| Hub | this repo's `hub-manifest.json` (below) | `<data dir>/hub/<version>/`, the bare hub archive | after a restart |

Every manifest is the **newest release's, pre-releases included**, found from
`https://github.com/<repo>/releases.atom` (n64lle docs/RELEASES.md §2), with the
Expand Down Expand Up @@ -385,9 +385,21 @@ which picks the newest of everything once more.

## The bare hub archive

For a tool that runs the hub in Direct mode, such as n64lle's new-project
scaffolder in "release" mode. So far only the Linux job packages one; on
Windows and macOS the hub (with Direct mode) ships inside the installers.
For a tool that runs the hub in Direct mode, or makes a title app, such as
n64lle's new-project scaffolder in "release" mode and its `tools/build_app.sh
--platform`. One archive per platform: `retro-hub-<version>-linux-x86_64.tar.gz`,
`-windows-x86_64.zip`, `-macos-arm64.tar.gz` and `-macos-x86_64.tar.gz`; each has
an entry in `hub-manifest.json`. The Linux one is built by
`scripts/package_hub_archive.sh`; Windows and macOS by `scripts/package_bare_hub.py`
from the flat hub prefix `scripts/build-local.{sh,ps1} --release-version <v>`
writes, with the same gates in spirit (the archived hub is extracted to a clean
directory and must run and report this release). The tables below describe the
Linux archive; on Windows the hub's DLLs (SDL3, curl, zlib) and
`retcomm-portable.exe` (the kit's stub) sit beside `retro-hub.exe`, and on macOS
the hub keeps its dylib install names (the title-app kit's `bundle_dylibs.sh`
copies them into the app). `requires` and `system_libraries` are empty off
Linux. **Windows and macOS archives: written 2026-10-13, run only on Linux
against a stand-in prefix; the first release is their first real test.**

Everything is flat at the archive root, so it extracts straight into one
directory:
Expand Down Expand Up @@ -467,9 +479,9 @@ Its shape follows Retro-Runtime's `runtime-manifest.json`:
"system_libraries": ["libGLX.so.0", "libOpenGL.so.0", "libc.so.6", "libcurl.so.4", "…"]
},
"linux-arm64": { "unavailable": "not built yet" },
"windows-x86_64": { "unavailable": "no bare archive is built for this platform yet; …" },
"macos-arm64": { "unavailable": "no bare archive is built for this platform yet; …" },
"macos-x86_64": { "unavailable": "no bare archive is built for this platform yet; …" }
"windows-x86_64": { "archive": "retro-hub-<v>-windows-x86_64.zip", "executable": "retro-hub.exe", "…": "…" },
"macos-arm64": { "archive": "retro-hub-<v>-macos-arm64.tar.gz", "…": "…" },
"macos-x86_64": { "archive": "retro-hub-<v>-macos-x86_64.tar.gz", "…": "…" }
}
}
```
Expand Down
8 changes: 7 additions & 1 deletion scripts/build-local.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,14 @@
# RETRO_HUB=<absolute path to retro-hub.exe>
#
# usage: scripts/build-local.ps1 [-Debug] [-Out DIR] [-Build DIR]
# [-Runtime <Retro-Runtime checkout>] [-Jobs N] [-Help]
# [-Runtime <Retro-Runtime checkout>] [-Jobs N] [-ReleaseVersion V] [-Help]
param(
[switch]$Debug,
[string]$Out = "",
[string]$Build = "",
[string]$Runtime = "",
[int]$Jobs = 0,
[string]$ReleaseVersion = "",
[switch]$Help
)

Expand All @@ -48,6 +49,10 @@ this machine, and print its path last, as RETRO_HUB=<absolute path>.
scripts\build-local.ps1 when it has one) instead of the
submodule's
-Jobs N parallel build jobs (default: all CPUs)
-ReleaseVersion V
build as release V (-DRETCOMM_VERSION, -DRETCOMM_RELEASE_BUILD):
the hub's --version says V. What scripts/package_bare_hub.py
archives in the release workflow.
-Help this text
"@ | Write-Output
exit 0
Expand Down Expand Up @@ -114,6 +119,7 @@ $cmakeArgs = @("-S", $Root, "-B", $Build, "-G", $generator,
"-DVCPKG_TARGET_TRIPLET=$Triplet",
"-DCMAKE_BUILD_TYPE=$Config",
"-DRETCOMM_COMMIT=$commit")
if ($ReleaseVersion) { $cmakeArgs += @("-DRETCOMM_VERSION=$ReleaseVersion", "-DRETCOMM_RELEASE_BUILD=ON") }
if ($generator -like "Visual Studio*") { $cmakeArgs += @("-A", $(if ($Arch -eq "arm64") { "ARM64" } else { "x64" })) }
Say "$Platform, $Config, build $Build"
Invoke-Checked cmake $cmakeArgs
Expand Down
8 changes: 7 additions & 1 deletion scripts/build-local.sh
Original file line number Diff line number Diff line change
Expand Up @@ -44,21 +44,26 @@ machine, and print its path last, as RETRO_HUB=<absolute path>.
scripts/build-local.sh when it has one) instead of the
submodule's
--jobs N parallel build jobs (default: all CPUs)
--release-version V
build as release V (-DRETCOMM_VERSION, -DRETCOMM_RELEASE_BUILD):
the hub's --version says V. What scripts/package_bare_hub.py
archives in the release workflow.
--help this text

<platform> is linux-x86_64, linux-arm64, macos-x86_64 or macos-arm64.
Relative paths are taken against the current directory.
EOF
}

CONFIG=Release OUT="" BUILD="" RUNTIME="" JOBS=""
CONFIG=Release OUT="" BUILD="" RUNTIME="" JOBS="" RELEASE_VERSION=""
while [[ $# -gt 0 ]]; do
case "$1" in
--debug) CONFIG=Debug; shift ;;
--out) [[ $# -ge 2 ]] || die "--out needs a directory"; OUT="$2"; shift 2 ;;
--build) [[ $# -ge 2 ]] || die "--build needs a directory"; BUILD="$2"; shift 2 ;;
--runtime) [[ $# -ge 2 ]] || die "--runtime needs a directory"; RUNTIME="$2"; shift 2 ;;
--jobs) [[ $# -ge 2 ]] || die "--jobs needs a number"; JOBS="$2"; shift 2 ;;
--release-version) [[ $# -ge 2 ]] || die "--release-version needs a version"; RELEASE_VERSION="$2"; shift 2 ;;
-h|--help) usage; exit 0 ;;
*) die "unknown argument '$1' (see --help)" ;;
esac
Expand Down Expand Up @@ -131,6 +136,7 @@ cmake_args=(
"-DCMAKE_BUILD_TYPE=${CONFIG}"
"-DRETCOMM_COMMIT=${COMMIT}"
)
[[ -z "${RELEASE_VERSION}" ]] || cmake_args+=("-DRETCOMM_VERSION=${RELEASE_VERSION}" -DRETCOMM_RELEASE_BUILD=ON)
command -v ninja >/dev/null && cmake_args+=(-G Ninja)
[[ -z "${CMAKE_PREFIX_PATH:-}" ]] || cmake_args+=("-DCMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH}")
# The runner finds SDL3 beside itself in the flat prefix (the hub already
Expand Down
7 changes: 2 additions & 5 deletions scripts/hub_manifest.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,10 @@

# Platforms a tool may ask for that this release cannot serve, and why. A tool
# reads the reason instead of finding the platform silently absent.
_INSTALLER_ONLY = ("no bare archive is built for this platform yet; the installer and DMG "
"assets carry retro-hub with Direct mode")
# (Windows and macOS had only the installer and DMG until their bare archives,
# scripts/package_bare_hub.py; an older release's manifest still says so.)
UNAVAILABLE = {
"linux-arm64": "not built yet",
"windows-x86_64": _INSTALLER_ONLY,
"macos-arm64": _INSTALLER_ONLY,
"macos-x86_64": _INSTALLER_ONLY,
}

# Fields every platform of one release must agree on.
Expand Down
Loading
Loading