name: Package installers # Builds the per-platform installer/setup tool (WiiCompiled-Setup.exe / # WiiCompiled-Setup-x86_64.AppImage / WiiCompiled-Setup.pkg) via the platform packaging scripts - # the same scripts a maintainer runs by hand today to # produce a GitHub Release asset. This does NOT build the actual translated game executable: # that step requires the end user's own Mario Kart Wii dump (Assets/main.dol, Assets/StaticR.rel), # which is proprietary and not present in this repository or in CI. on: push: tags: - '*' workflow_dispatch: inputs: version: description: Package version required: true type: string permissions: contents: read concurrency: group: package-${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true jobs: linux-appimage: name: Linux (AppImage, ${{ matrix.arch }}) strategy: fail-fast: false matrix: include: - runner: ubuntu-22.04 arch: x86_64 - runner: ubuntu-22.04-arm arch: aarch64 runs-on: ${{ matrix.runner }} steps: - uses: actions/checkout@v7 with: persist-credentials: false - uses: actions/setup-dotnet@v6 with: dotnet-version: '8.0.x' # appimagetool ships as an AppImage itself and needs to self-mount via FUSE to run directly; # GitHub's ubuntu-latest runners don't have libfuse2 preinstalled. - name: Install dependencies (required by appimagetool and SDL3 build) run: | sudo apt-get update sudo apt-get install -y libfuse2 build-essential git make \ pkg-config cmake ninja-build gnome-desktop-testing libasound2-dev libpulse-dev \ libaudio-dev libfribidi-dev libjack-dev libsndio-dev libx11-dev libxext-dev \ libxrandr-dev libxcursor-dev libxfixes-dev libxi-dev libxss-dev libxtst-dev \ libxkbcommon-dev libdrm-dev libgbm-dev libgl1-mesa-dev libgles2-mesa-dev \ libegl1-mesa-dev libdbus-1-dev libibus-1.0-dev libudev-dev libthai-dev libusb-1.0-0-dev \ libpipewire-0.3-dev libwayland-dev libdecor-0-dev liburing-dev - name: Build AppImage run: bash Launcher/build-appimage.sh - uses: actions/upload-artifact@v7 with: name: WiiCompiled-Setup-linux-${{ matrix.arch }} path: Launcher/dist/WiiCompiled-Setup-${{ matrix.arch }}.AppImage if-no-files-found: error archive: false windows-installer: name: Windows (installer exe) runs-on: windows-latest steps: - uses: actions/checkout@v7 with: persist-credentials: false - uses: actions/setup-dotnet@v6 with: dotnet-version: '8.0.x' - name: Build installer shell: pwsh run: ./Launcher/Build-Installer.ps1 - uses: actions/upload-artifact@v7 with: name: WiiCompiled-Setup-windows-x64 path: Launcher/dist/WiiCompiled-Setup.exe if-no-files-found: error archive: false macos-setup-package: name: macOS (Setup.pkg, Apple Silicon) runs-on: macos-14 steps: - uses: actions/checkout@v7 with: persist-credentials: false - uses: actions/setup-dotnet@v6 with: dotnet-version: '8.0.x' - name: Verify Apple Silicon runner tools shell: bash run: | test "$(uname -m)" = arm64 xcode-select -p command -v ninja file "$(command -v ninja)" | grep -q arm64 - name: Download pinned nodtool release shell: bash run: | mkdir -p Launcher/artifacts/macos nodtool_version=v2.0.0-alpha.10 nodtool_asset=nodtool-macos-arm64 nodtool_sha256=e23ca466999b720c55e6d29c9683fce8cc74451ba64ead2e543d50129f24528a curl -fsSL --retry 3 \ "https://github.com/encounter/nod/releases/download/${nodtool_version}/${nodtool_asset}" \ -o Launcher/artifacts/macos/nodtool printf '%s %s\n' "$nodtool_sha256" Launcher/artifacts/macos/nodtool | shasum -a 256 -c - chmod +x Launcher/artifacts/macos/nodtool Launcher/artifacts/macos/nodtool --version - name: Publish self-contained translator shell: bash run: | dotnet publish translator/src/Translator.Cli/Translator.Cli.csproj \ -c Release -r osx-arm64 --self-contained true \ -p:PublishSingleFile=true \ -o Launcher/artifacts/macos/translator - name: Download pinned portable CMake shell: bash run: | cmake_version=4.4.3 archive="cmake-${cmake_version}-macos-universal.tar.gz" base_url="https://github.com/Kitware/CMake/releases/download/v${cmake_version}" expected_sha256=0c5d65251c14cc884bfa16bdbed3c263ce5bffe2e21c0d0d00962cb0610464fa curl -fsSL --retry 3 "$base_url/$archive" -o "$archive" printf '%s %s\n' "$expected_sha256" "$archive" | shasum -a 256 -c - tar -xzf "$archive" mv "cmake-${cmake_version}-macos-universal/CMake.app/Contents" Launcher/artifacts/macos/cmake - name: Build Setup.pkg env: PACKAGE_VERSION: ${{ inputs.version }} TAG_VERSION: ${{ github.ref_name }} shell: bash run: | package_version="$PACKAGE_VERSION" if [[ -z "$package_version" ]]; then package_version="${TAG_VERSION#v}"; fi mkdir -p Launcher/dist Launcher/macos/build-setup-pkg.command \ --nodtool Launcher/artifacts/macos/nodtool \ --translator Launcher/artifacts/macos/translator/Translator.Cli \ --cmake-root Launcher/artifacts/macos/cmake \ --ninja "$(command -v ninja)" \ --output Launcher/dist/WiiCompiled-Setup.pkg \ --version "$package_version" - name: Verify package boundary shell: bash run: | pkgutil --check-signature Launcher/dist/WiiCompiled-Setup.pkg ! pkgutil --payload-files Launcher/dist/WiiCompiled-Setup.pkg | \ grep -E '/(Assets|generated|PulsarPacks|WiiCompiled.app|RetroRewind.app)(/|$)' - uses: actions/upload-artifact@v7 with: name: WiiCompiled-Setup-macos-arm64 path: Launcher/dist/WiiCompiled-Setup.pkg if-no-files-found: error archive: false # Publishes the packaged installers as a GitHub Release whenever a v* tag is pushed. Wheel Wizard # discovers updates from these releases, so the contract it relies on is enforced here: a full # (non-prerelease) release whose tag is v, carrying the expected platform assets, # produced by setup hosts that report that same version. release: name: Publish GitHub Release if: startsWith(github.ref, 'refs/tags/v') needs: [linux-appimage, windows-installer, macos-setup-package] runs-on: ubuntu-latest permissions: contents: write steps: - uses: actions/checkout@v7 with: persist-credentials: false # Wheel Wizard runs the downloaded setup with --version and refuses it when the reported # version differs from the release tag, so a tag that was pushed without bumping every pinned # version would ship an update nobody can install. Catch that before anything is published. - name: Verify the tag matches the pinned setup version env: TAG: ${{ github.ref_name }} run: | set -euo pipefail version="${TAG#v}" status=0 check() { if ! grep -Fq "$2" "$1"; then echo "::error file=$1::expected '$2' for tag $TAG" status=1 fi } check Launcher/WiiCompiled.Setup.Windows/Program.cs "public const string Version = \"$version\";" check Launcher/WiiCompiled.Setup.Windows/WiiCompiled.Setup.Windows.csproj "$version" check Launcher/Build-Installer.ps1 "ProductVersion = '$version'" exit $status # The build jobs upload with `archive: false`, which stores each installer as a raw file # rather than a zip (and names the artifact after the file). Only download-artifact v8 and # later understand such direct uploads; v7 tries to unzip everything and fails on them. - uses: actions/download-artifact@v8 with: path: artifacts merge-multiple: true - name: Publish release env: GH_TOKEN: ${{ github.token }} TAG: ${{ github.ref_name }} run: | set -euo pipefail ls -lR artifacts assets=() for name in WiiCompiled-Setup.exe WiiCompiled-Setup-x86_64.AppImage WiiCompiled-Setup-aarch64.AppImage WiiCompiled-Setup.pkg; do found="$(find artifacts -type f -name "$name" | head -n 1)" [ -n "$found" ] && [ -s "$found" ] || { echo "::error::missing release asset $name"; exit 1; } assets+=("$found") done # A re-run of a tag whose release already exists only refreshes the assets. if gh release view "$TAG" --repo "$GITHUB_REPOSITORY" >/dev/null 2>&1; then gh release upload "$TAG" "${assets[@]}" --repo "$GITHUB_REPOSITORY" --clobber else gh release create "$TAG" "${assets[@]}" \ --repo "$GITHUB_REPOSITORY" \ --title "$TAG" \ --verify-tag \ --generate-notes fi