mirror of
https://github.com/ARMSX2/ARMSX2.git
synced 2026-08-24 16:50:16 -07:00
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.
243 lines
9.1 KiB
YAML
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"
|