Files
ARMSX2/.github/workflows/build-all.yml
Brian Degenhardt 10fab243e7 CI: install the Rust Android target for the librashader cargo build
The Android APK job fails (also on master - the job is
continue-on-error so it never blocked) because librashader's cargo
build targets aarch64-linux-android and the runner's rustup only has
the host std: error[E0463] can't find crate for 'core'. One rustup
target add before the gradle build fixes it. Candidate to send
upstream to master independently of this branch.
2026-07-19 13:11:01 -07:00

243 lines
9.1 KiB
YAML

# Unified "build everything on every commit" pipeline for the single-core monorepo.
#
# One push to the default branch fans out to every supported target and uploads
# an individual binary artifact per platform:
# * PC arm64 Qt GUI -> macOS, Linux, Windows (reuses the reusable workflows)
# * Android APK -> platforms/android (Gradle + NDK, thin CMake on root core)
# * iOS .app -> platforms/ios (Xcode/CMake on root core)
#
# Windows-on-arm64 builds natively on a Windows 11 arm64 runner (see
# windows_build_qt.yml): a single arm64 deps stage, then the arm64 GUI.
#
# NOTE: The Android and iOS jobs build against the freshly-collapsed single core
# and have not yet had a green run; they are the mechanism that will surface the
# remaining reconciliation work. Keep them non-blocking until they first pass.
#
# INVARIANT (do not weaken): the PC arm64 jobs (pc-macos-arm64 / pc-linux-arm64 /
# pc-windows-arm64) are BLOCKING and must stay so. They are the guardrail that a
# mobile-motivated change has not silently altered the shared canonical core.
# Anything mobile-specific belongs behind a platform guard (#if __ANDROID__ /
# ARMSX2_IOS) or in a forked, CMake-selected translation unit (see the aR5900*
# EE fork in pcsx2/CMakeLists.txt) -- never grafted unguarded into shared files.
name: Build All Platforms
on:
push:
branches:
- master
# Doc-only pushes shouldn't burn ~2h of arm64 CI.
paths-ignore:
- '**/*.md'
- 'LICENSE*'
- '.gitignore'
pull_request:
paths-ignore:
- '**/*.md'
- 'LICENSE*'
- '.gitignore'
workflow_dispatch:
concurrency:
group: build-all-${{ github.ref }}
cancel-in-progress: true
jobs:
# ---- PC arm64 Qt GUI (mac / linux) -------------------------------------
pc-macos-arm64:
name: PC · macOS arm64 (Qt)
uses: ./.github/workflows/macos_build.yml
with:
jobName: "macOS arm64"
artifactPrefixName: "armsx2-macos-arm64"
sign_and_notarize: true
secrets: inherit
pc-linux-arm64:
name: PC · Linux arm64 (Qt)
strategy:
fail-fast: false
matrix:
include:
# The GitHub aarch64 runners use 4K pages, so an unqualified build only
# runs on 4K-page kernels. 16K-page kernels (e.g. Asahi Linux on Apple
# Silicon) need a separate binary, so build both variants explicitly
# instead of quietly inheriting the runner's page size.
- pageVariant: "4k"
pageSize: "4096"
cacheLineSize: "64"
- pageVariant: "16k"
pageSize: "16384"
cacheLineSize: "128"
uses: ./.github/workflows/linux_build_qt.yml
with:
jobName: "Linux arm64 (${{ matrix.pageVariant }} pages)"
artifactPrefixName: "armsx2-linux-arm64-${{ matrix.pageVariant }}-appimage"
compiler: clang
cmakeflags: "-DHOST_PAGE_SIZE=${{ matrix.pageSize }} -DHOST_CACHE_LINE_SIZE=${{ matrix.cacheLineSize }}"
buildAppImage: true
# ---- libretro core (linux arm64) ---------------------------------------
pc-linux-arm64-libretro:
name: PC · Linux arm64 (libretro core)
uses: ./.github/workflows/linux_build_libretro.yml
with:
jobName: "libretro Core Build (arm64)"
artifactPrefixName: "armsx2-linux-arm64-libretro"
fetchTags: true
secrets: inherit
# ---- SDL/kmsdrm handheld frontend (linux arm64) ------------------------
pc-linux-arm64-sdl:
name: PC · Linux arm64 (SDL kmsdrm)
uses: ./.github/workflows/linux_build_sdl.yml
with:
jobName: "SDL Handheld Build (arm64)"
artifactPrefixName: "armsx2-linux-arm64-sdl"
fetchTags: true
secrets: inherit
# ---- PC arm64 Qt GUI (windows) -----------------------------------------
pc-windows-arm64:
name: PC · Windows arm64 (Qt)
uses: ./.github/workflows/windows_build_qt.yml
with:
jobName: "Windows arm64"
artifactPrefixName: "armsx2-windows-arm64"
# ---- Android APK -------------------------------------------------------
android:
name: Android APK
runs-on: ubuntu-24.04
# Non-blocking until the collapsed-core Android build first goes green.
continue-on-error: true
defaults:
run:
working-directory: platforms/android
steps:
- uses: actions/checkout@v7
with:
submodules: recursive
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
distribution: temurin
java-version: "17"
- name: Set up Android SDK
uses: android-actions/setup-android@v3
# NDK matches the version AGP resolves to (build.gradle.kts pins none, so it
# uses AGP's default 28.2.13676358); cmake 3.31.6 matches the pin in
# build.gradle.kts. 3.22.1 (AGP's default) is the shaderc deps' exact
# cmake_minimum_required floor and fails to configure spirv-tools.
- name: Install NDK + CMake
run: yes | sdkmanager "ndk;28.2.13676358" "cmake;3.31.6" >/dev/null || true
# shaderc's SPIRV-Tools/glslang/etc. are fetched on demand (not vendored,
# not submodules), so `submodules: recursive` above does not provide them.
- name: Fetch shaderc third-party deps
run: python3 app/src/main/cpp/3rdparty/shaderc/utils/git-sync-deps
# librashader is built by cargo for the Android target; the runner's
# rustup only ships the host std, so the cargo step dies with
# "error[E0463]: can't find crate for `core`" without this.
- name: Install Rust Android target
run: rustup target add aarch64-linux-android
- name: Build release APK
run: ./gradlew :app:assembleRelease --stacktrace
- name: Upload APK
uses: actions/upload-artifact@v7
with:
name: armsx2-android-arm64
path: platforms/android/app/build/outputs/apk/**/*.apk
if-no-files-found: warn
# ---- iOS .app ----------------------------------------------------------
ios:
name: iOS (arm64, unsigned device IPA)
runs-on: macos-26
# Non-blocking until the collapsed-core iOS build first goes green.
continue-on-error: true
steps:
- uses: actions/checkout@v7
with:
submodules: recursive
- name: Select Xcode
run: sudo xcode-select -switch /Applications/Xcode.app
- name: Configure (CMake, Xcode generator, real device SDK, no signing)
working-directory: platforms/ios/app/src/main/cpp
run: >
cmake -G Xcode -B build
-DCMAKE_SYSTEM_NAME=iOS
-DCMAKE_OSX_ARCHITECTURES=arm64
-DARMSX2_REAL_DEVICE=ON
- name: Build (iphoneos SDK, unsigned)
working-directory: platforms/ios/app/src/main/cpp
run: >
cmake --build build --config Release
-- -sdk iphoneos CODE_SIGNING_ALLOWED=NO CODE_SIGNING_REQUIRED=NO
- name: Package unsigned .ipa
working-directory: platforms/ios/app/src/main/cpp
run: |
SHORT_SHA=$(echo "${{ github.sha }}" | cut -c1-8)
IPA_NAME="ARMSX2-iOS-${SHORT_SHA}.ipa"
APP_PATH=$(find build -name "ARMSX2iOS.app" -type d | head -1)
if [ -z "$APP_PATH" ]; then
echo "ERROR: ARMSX2iOS.app not found in build output"
exit 1
fi
echo "Found app at: $APP_PATH"
echo "Packaging as: $IPA_NAME"
STAGING=$(mktemp -d)
mkdir -p "$STAGING/Payload"
cp -R "$APP_PATH" "$STAGING/Payload/"
cd "$STAGING"
zip -r "$GITHUB_WORKSPACE/$IPA_NAME" Payload -x "*.DS_Store"
cd "$GITHUB_WORKSPACE"
echo "IPA_NAME=$IPA_NAME" >> $GITHUB_ENV
ls -lh "$IPA_NAME"
- name: Upload .ipa
uses: actions/upload-artifact@v4
with:
name: ${{ env.IPA_NAME }}
path: ${{ github.workspace }}/${{ env.IPA_NAME }}
if-no-files-found: error
# ---- Alert on a broken master build ------------------------------------
# Fires only when a BLOCKING guardrail job (the PC arm64 builds) fails on a
# push to master -- never on PRs, and never on the non-blocking mobile jobs
# (they are continue-on-error, so they can't trip `failure()`). GitHub also
# emails the pusher natively; this adds a Discord ping to the shared channel.
notify-failure:
name: Notify on master build failure
needs: [pc-macos-arm64, pc-linux-arm64, pc-windows-arm64]
if: ${{ failure() && github.event_name == 'push' }}
runs-on: ubuntu-latest
# Job-level so the step's `if: env.HOOK != ''` guard can see it.
env:
HOOK: ${{ secrets.DISCORD_BUILD_WEBHOOK }}
steps:
- name: Discord failure ping
if: ${{ env.HOOK != '' }} # no-op on forks that lack the secret
env:
RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
run: |
jq -n \
--arg url "$RUN_URL" \
--arg desc "Commit \`${{ github.sha }}\` by ${{ github.actor }} failed a required build." \
'{username:"ARMSX2 CI", embeds:[{title:"❌ master build broke", url:$url, color:15158332, description:$desc}]}' \
| curl -fsSL -H 'Content-Type: application/json' -d @- "$HOOK"