* Reduce beast effect texture import sizes
* Fall back to GitHub LFS for missing mirror objects
* Disable local LFS filter process for non-LFS checkouts
* Use IL2CPP for Standalone Unity builds
* Install .NET SDK for Unity builds
* Expose setup-dotnet SDK to Unity builds
* Set dotnet host path for Unity Addressables
* Build Standalone Addressables with Mono backend
* Disable Addressables player rebuilds in CI
* Require Unity IL2CPP modules in CI
* Use Mono for macOS Windows Unity cross-builds
* Ensure Bazel is available in self-hosted workflows
* Allow Bazel CI to use Command Line Tools
* Set macOS C++ deployment target for Bazel
* Use Bazel macOS minimum OS flags
* Raise macOS Bazel deployment target for filesystem
* Ensure git-lfs is available for CI fetches
* Authenticate CI LFS fetches with workflow token
* Disable stale LFS hooks during CI checkout
* Disable LFS filters during CI checkout
* Prepare Git LFS before persistent checkout
* Harden generated Bazel rc and LFS auth
* Let Xcode sync skip without full Xcode
* Harden Unity build cache markers
* Require full Xcode for mactools sync
The Docker Build and Push workflow spends more time pushing than building
because the entire ~115MB Eagle classpath ships as one pkg_tar layer, so
every Scala commit re-uploads the whole blob to DOCR.
Add a jar_split rule that partitions the scala_binary's transitive runtime
jars by workspace into a stable third-party layer (76MB, 137 jars) and a
first-party layer (38MB, 989 jars). crane skips the unchanged deps blob, so
typical Scala-only commits re-upload ~38MB instead of ~115MB. Entrypoint
switches from -jar fat.jar to a -cp classpath glob over both layer dirs.
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
xcodebuild archive can reset the user keychain search list during long
builds, dropping the temporary CI keychain that holds the Apple
Distribution signing cert. Re-add and unlock the keychain right before
the export step so xcodebuild -exportArchive can find the certificate.
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Gitea's mirror-sync API is async — the GitHub webhook triggers it but
returns 200 before the sync completes. CI runners can start git lfs pull
before new LFS objects are available on Gitea. Extract LFS fetch into a
shared script with retry logic (5 attempts, 15s backoff) to bridge the
gap.
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Each xcodebuild archive creates a new ~3.6GB Unity-iPhone-<random>
folder in DerivedData that was never cleaned up, accumulating on
the build runner.
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
The exportArchive step was relying on the Xcode-Token in the keychain
for App Store Connect authentication. This token expires periodically,
breaking headless CI builds. Pass the App Store Connect API key (already
used by the upload step) to the export step as well.
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
The nightly iOS TestFlight build already builds and uploads iOS
addressables as part of its pipeline. The standalone workflow added
unnecessary complexity and forced platform switches on the unity-mac
runner. Manual TestFlight dispatches cover any need for immediate
addressable updates.
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Two fixes for iOS deep link handling:
1. CI: Remove UIApplicationSceneManifest from the generated Info.plist
during archive. Unity 6 adds this key, which opts the app into the
scene-based lifecycle. iOS then routes deep links through
UISceneDelegate instead of UIApplicationDelegate, but Unity doesn't
implement that path, so deep link URLs are silently dropped.
2. OAuthManager: Don't call Application.Quit() on iOS — it's documented
as having no effect. Instead, let the app go to background when the
browser opens and handle the deep link callback when iOS brings it
back via OnDeepLinkActivated.
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Add .e0mj map files as a layer in the admin server Docker image
and pass --maps-dir=/app/maps to enable the web-based map editor
added in #6186.
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
These scripts managed an rsync-based Library/ cache to /tmp/eagle0/ but
are never called from any workflow. Library/ caching now relies on
clean: false preserving the working directory between self-hosted runs.
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
The Unity DeepLinkPostProcessor depends on UNITY_IOS being defined at
script compilation time, which can fail if the editor starts with a
non-iOS build target. Set the key via PlistBuddy in the archive script
as a reliable fallback that doesn't depend on Unity preprocessor state.
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
GitHub Actions kills orphan processes after each job, which kills
the Bazel server and forces a cold reload of the skyframe graph on
every CI run (~15-20s for loading+analysis of 1080 packages / 78k
targets). With a warm server this drops to ~2-3s.
Changes:
- .bazelrc: Set startup --max_idle_secs=0 to prevent idle shutdown
- ci/runners/bazel-keepalive.sh: Pings the Bazel server to keep it alive
- ci/runners/install-bazel-keepalive.sh: One-time setup script that
installs a macOS launchd agent to run the keepalive every 5 minutes
The launchd agent owns the Bazel server process, so GitHub Actions'
orphan cleanup won't kill it. To set up on a new runner:
./ci/runners/install-bazel-keepalive.sh /path/to/actions-runner/_work/eagle0/eagle0
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Replace deprecated altool (removed in Xcode 14) with xcodebuild
-exportArchive using App Store Connect API authentication.
Changes:
- upload_testflight.sh: Use xcodebuild with destination=upload
and API key authentication instead of altool
- ios_testflight.yml: Pass xcarchive path and use new API key secrets
Required new GitHub secrets:
- APP_STORE_CONNECT_API_KEY_ID
- APP_STORE_CONNECT_API_ISSUER_ID
- APP_STORE_CONNECT_API_KEY (contents of .p8 file)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Upgrade Eagle server and JFR sidecar from Java 21 to Java 25.
Java 25 is the latest LTS release (September 2025). Scala 3.7.2
fully supports JDK 25.
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Upgrade Eagle server and JFR sidecar from Java 17 to Java 21.
Benefits:
- Better garbage collection (Generational ZGC available)
- General JVM performance improvements
- Foundation for future virtual threads adoption
- Supported until 2031
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
The Eagle server only needs to run Java, not compile it. Using the JRE
base image instead of JDK reduces the image size from ~273MB to ~120MB.
The JFR sidecar still uses JDK because it needs jcmd for JFR dumps.
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
The warmup binary was being copied from a hardcoded bazel-bin path that
doesn't work reliably with cross-compilation and remote caching. When the
binary was cached but not materialized locally, the cp command would fail.
Fix by:
- Create a warmup_tar pkg_tar target that packages the warmup binary
- Use tar extraction instead of cp, which forces Bazel to materialize
the output file before the command runs
- Rename the binary from warmup_linux_amd64 to warmup in the tar
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* Fix iOS build by checking for iOS module before skipping install
The script was checking if Unity was installed but not whether the iOS
module was present. This caused iOS builds to fail when Unity was
installed without iOS support.
Now checks for platform-specific module directories before declaring
Unity ready.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Use install-modules when editor exists but modules missing
Unity Hub CLI has separate commands:
- install: installs editor with modules (fails if editor exists)
- install-modules: adds modules to existing installation
Now detects which command to use based on whether the editor
directory exists.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Output Unity log on build failure for easier debugging
When Unity builds fail, the actual error is hidden in a log file that
requires downloading an artifact. Now all Unity build scripts output
the last 200 lines of the log directly to the console on failure.
Updated scripts:
- build_unity_ios.sh
- build_windows.sh
- build_mac.sh
- build_ios_addressables.sh
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Treat 'module already installed' as success
Unity Hub CLI returns non-zero exit code when all requested modules
are already installed, with message "No modules found to install".
Now check output for "already installed" messages and treat as success.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Adds /credits endpoint to the auth service that displays all attribution
information from attributions.json in a readable HTML format.
The page includes:
- Creative Commons music (31 tracks with artist and license)
- Sound effects from Freesound (with source links)
- Fonts (with license info)
- Open source software dependencies (Java, Go, C++, C#)
The attributions.json file is now included in the auth server Docker
image so it can be served at runtime.
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>