Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
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
21 changes: 19 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -126,13 +126,15 @@ jobs:
run: docker exec unity dotnet build -c Release -v:d

- name: Install assemblyalias
run: docker exec unity dotnet tool install --global Alias --version 0.4.3 --allow-roll-forward
run: docker exec unity dotnet tool install --global Sentry.AssemblyAlias --version 0.5.0 --allow-roll-forward

- name: Alias editor assemblies
run: docker exec unity /home/gh/.dotnet/tools/assemblyalias --target-directory "package-dev/Editor" --internalize --prefix "Sentry." --assemblies-to-alias "Microsoft*;Mono.Cecil*"

# --assemblies-to-exclude: BCL assemblies Unity's unityaot profile already provides. Aliasing them
# mints a duplicate System.Span<T> definition that breaks IL2CPP's intrinsic remap (#2717, #1777).
- name: Alias runtime assemblies
run: docker exec unity /home/gh/.dotnet/tools/assemblyalias --target-directory "package-dev/Runtime" --internalize --prefix "Sentry." --assemblies-to-alias "Microsoft*;System*"
run: docker exec unity /home/gh/.dotnet/tools/assemblyalias --target-directory "package-dev/Runtime" --internalize --prefix "Sentry." --assemblies-to-alias "Microsoft*;System*" --assemblies-to-exclude "System.Buffers;System.Memory;System.Numerics.Vectors;System.Threading.Tasks.Extensions"

- name: Package for release
run: |
Expand All @@ -147,6 +149,21 @@ jobs:
path: |
package-release.zip

# The DependencyConflict package ships plain, UNALIASED System.*/Microsoft.*
# assemblies at versions that differ from the ones the SDK ships aliased. It
# gets dropped into the integration test project alongside Sentry to verify
# the assembly aliasing keeps them from colliding. Build it here (this job
# has the pinned .NET SDK) and pass it to the integration jobs as an artifact.
- name: Build DependencyConflict package
run: docker exec unity dotnet build test/Scripts.Integration.Test/DependencyConflictPackage

- name: Upload DependencyConflict package
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: dependency-conflict-package
if-no-files-found: error
path: test/Scripts.Integration.Test/DependencyConflictPackage/DependencyConflict

- name: Run Unity tests (playmode)
run: docker exec unity dotnet msbuild /t:UnityPlayModeTest /p:Configuration=Release /p:OutDir=other test/Sentry.Unity.Tests

Expand Down
9 changes: 9 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,15 @@ jobs:
- name: Add Sentry to the project
run: ./test/Scripts.Integration.Test/add-sentry.ps1 -UnityPath "$env:UNITY_PATH" -PackagePath "test-package-release"

- name: Download DependencyConflict package
uses: ./.github/actions/wait-for-artifact
with:
name: dependency-conflict-package
path: dependency-conflict-package

- name: Add DependencyConflict to the project
run: ./test/Scripts.Integration.Test/add-dependency-conflict.ps1 -PackagePath "dependency-conflict-package"

- name: Configure Sentry
run: ./test/Scripts.Integration.Test/configure-sentry.ps1 -UnityPath "$env:UNITY_PATH" -Platform "$env:BUILD_PLATFORM"
env:
Expand Down
5 changes: 3 additions & 2 deletions .github/workflows/create-unity-matrix.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@ on:

env:
# Unity versions used in PRs
PR_UNITY_VERSIONS: '["2022.3", "6000.0", "6000.3"]'
# TEMPORARY: reduced to 6000.5 only to probe Unity 6.5 CI on this branch
PR_UNITY_VERSIONS: '["6000.5"]'
# Unity versions used on main branch
FULL_UNITY_VERSIONS: '["2021.3", "2022.3", "6000.0", "6000.3"]'
FULL_UNITY_VERSIONS: '["6000.5"]'

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a quick comment, should this change be merged into main?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, definitely not. This is just while it's in a draft state to cut down on CI time.


jobs:
create-unity-matrix:
Expand Down
24 changes: 24 additions & 0 deletions .github/workflows/test-build-android.yml
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,15 @@ jobs:
- name: Add Sentry to the project
run: ./test/Scripts.Integration.Test/add-sentry.ps1 -UnityPath "$env:UNITY_PATH" -PackagePath "test-package-release"

- name: Download DependencyConflict package
uses: ./.github/actions/wait-for-artifact
with:
name: dependency-conflict-package
path: dependency-conflict-package

- name: Add DependencyConflict to the project
run: ./test/Scripts.Integration.Test/add-dependency-conflict.ps1 -PackagePath "dependency-conflict-package"

- name: Configure Sentry
run: ./test/Scripts.Integration.Test/configure-sentry.ps1 -UnityPath "$env:UNITY_PATH" -Platform "Android"
env:
Expand All @@ -84,6 +93,21 @@ jobs:
- name: Export APK - Runtime Initialization
run: ./test/Scripts.Integration.Test/build-project.ps1 -UnityPath "$env:UNITY_PATH" -Platform "Android" -UnityVersion "$env:UNITY_VERSION"

# Unity pipes the gradle output (which contains the Sentry symbol-upload task) to a separate
# log file instead of the editor log, so it never shows up in the build step output. Surface
# it (and the Sentry CLI upload logs) so we can verify debug symbols were actually uploaded.
- name: Upload gradle and symbol-upload logs
if: ${{ always() }}
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: android-gradle-logs-${{ env.UNITY_VERSION }}
path: |
samples/IntegrationTest/Library/Bee/Android/Prj/IL2CPP/Gradle/launcher/build/outputs/logs/*.log
samples/IntegrationTest/Logs/sentry-symbols-upload.log
samples/IntegrationTest/Logs/sentry-mapping-upload.log
retention-days: 14
if-no-files-found: warn

- name: Compare build sizes (Runtime)
run: ./test/Scripts.Integration.Test/measure-build-size.ps1 -Path1 "samples/IntegrationTest/Build-NoSentry" -Path2 "samples/IntegrationTest/Build" -Platform "Android" -UnityVersion "$env:UNITY_VERSION"

Expand Down
9 changes: 9 additions & 0 deletions .github/workflows/test-build-ios.yml
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,15 @@ jobs:
- name: Add Sentry to the project
run: ./test/Scripts.Integration.Test/add-sentry.ps1 -UnityPath "$env:UNITY_PATH" -PackagePath "test-package-release"

- name: Download DependencyConflict package
uses: ./.github/actions/wait-for-artifact
with:
name: dependency-conflict-package
path: dependency-conflict-package

- name: Add DependencyConflict to the project
run: ./test/Scripts.Integration.Test/add-dependency-conflict.ps1 -PackagePath "dependency-conflict-package"

- name: Configure Sentry
run: ./test/Scripts.Integration.Test/configure-sentry.ps1 -UnityPath "$env:UNITY_PATH" -Platform "$env:BUILD_PLATFORM"
env:
Expand Down
9 changes: 9 additions & 0 deletions .github/workflows/test-build-linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,15 @@ jobs:
- name: Add Sentry to the project
run: ./test/Scripts.Integration.Test/add-sentry.ps1 -UnityPath "$env:UNITY_PATH" -PackagePath "test-package-release"

- name: Download DependencyConflict package
uses: ./.github/actions/wait-for-artifact
with:
name: dependency-conflict-package
path: dependency-conflict-package

- name: Add DependencyConflict to the project
run: ./test/Scripts.Integration.Test/add-dependency-conflict.ps1 -PackagePath "dependency-conflict-package"

- name: Configure Sentry
run: ./test/Scripts.Integration.Test/configure-sentry.ps1 -UnityPath "$env:UNITY_PATH" -Platform Linux
env:
Expand Down
11 changes: 10 additions & 1 deletion .github/workflows/test-build-macos.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ jobs:
"unityChangeset=$($u.changeset)" >> $env:GITHUB_OUTPUT

- name: Setup Unity
uses: getsentry/setup-unity@1bbd385ae3b0505069aacc56d47f0a16366f10b1
uses: getsentry/setup-unity@c3304fd81a0c4e11fb3ce14f2bcca12e9b0bfc95
with:
unity-version: ${{ steps.env.outputs.unityVersion }}
unity-version-changeset: ${{ steps.env.outputs.unityChangeset }}
Expand Down Expand Up @@ -82,6 +82,15 @@ jobs:
- name: Add Sentry to the project
run: ./test/Scripts.Integration.Test/add-sentry.ps1 -UnityPath "$env:UNITY_PATH" -PackagePath "test-package-release"

- name: Download DependencyConflict package
uses: ./.github/actions/wait-for-artifact
with:
name: dependency-conflict-package
path: dependency-conflict-package

- name: Add DependencyConflict to the project
run: ./test/Scripts.Integration.Test/add-dependency-conflict.ps1 -PackagePath "dependency-conflict-package"

- name: Configure Sentry
run: ./test/Scripts.Integration.Test/configure-sentry.ps1 -UnityPath "$env:UNITY_PATH" -Platform MacOS
env:
Expand Down
11 changes: 10 additions & 1 deletion .github/workflows/test-build-windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ jobs:
"unityChangeset=$($u.changeset)" >> $env:GITHUB_OUTPUT

- name: Setup Unity
uses: getsentry/setup-unity@1bbd385ae3b0505069aacc56d47f0a16366f10b1
uses: getsentry/setup-unity@c3304fd81a0c4e11fb3ce14f2bcca12e9b0bfc95
with:
unity-version: ${{ steps.env.outputs.unityVersion }}
unity-version-changeset: ${{ steps.env.outputs.unityChangeset }}
Expand Down Expand Up @@ -82,6 +82,15 @@ jobs:
- name: Add Sentry to the project
run: ./test/Scripts.Integration.Test/add-sentry.ps1 -UnityPath "$env:UNITY_PATH" -PackagePath "test-package-release"

- name: Download DependencyConflict package
uses: ./.github/actions/wait-for-artifact
with:
name: dependency-conflict-package
path: dependency-conflict-package

- name: Add DependencyConflict to the project
run: ./test/Scripts.Integration.Test/add-dependency-conflict.ps1 -PackagePath "dependency-conflict-package"

- name: Configure Sentry
run: ./test/Scripts.Integration.Test/configure-sentry.ps1 -UnityPath "$env:UNITY_PATH" -Platform Windows
env:
Expand Down
101 changes: 91 additions & 10 deletions .github/workflows/test-run-android.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,13 @@ defaults:
jobs:
run:
name: ${{ inputs.unity-version }} ${{ inputs.api-level }} ${{ inputs.init-type }}
runs-on: ubuntu-latest
# Unity 6000.5+ builds ARM64 only (x86_64 was removed). No GitHub-hosted runner can run an
# accelerated Android *emulator* for an arm64 app: x86 Linux would need ndk_translation (SIGILL),
# arm64 Linux has no /dev/kvm, and macOS arm64 can't nest virtualization (HVF HV_UNSUPPORTED).
# So for 6000.5+ we run Redroid (containerized arm64 Android, no hypervisor) on an arm64 Linux
# runner. Older Unity versions keep x86_64 and run the emulator on the standard x86 Linux runner.
# Keep in sync with the "Determine device" step below and Builder.cs.
runs-on: ${{ inputs.unity-version == '6000.5' && 'ubuntu-24.04-arm' || 'ubuntu-latest' }}
env:
ARTIFACTS_PATH: samples/IntegrationTest/test-artifacts/
HOMEBREW_NO_INSTALL_CLEANUP: 1
Expand All @@ -48,28 +54,48 @@ jobs:
name: testapp-android-compiled-${{ inputs.unity-version }}-${{ inputs.init-type }}
path: samples/IntegrationTest/Build

# Unity 6000.5+ ships an ARM64-only app -> Redroid on the arm64 runner. Older versions ship
# x86_64 and run the hardware-accelerated emulator. Keep in sync with runs-on and Builder.cs.
- name: Determine device
id: device
shell: bash
run: |
case "${{ inputs.unity-version }}" in
6000.5) device="redroid"; arch="arm64-v8a" ;;
*) device="emulator"; arch="x86_64" ;;
esac
echo "device=$device" >> "$GITHUB_OUTPUT"
echo "arch=$arch" >> "$GITHUB_OUTPUT"
echo "Using device: $device ($arch)"

# --- x86_64 path: hardware-accelerated emulator on the x86 Linux runner ---

- name: Add Android build-tools to PATH
if: ${{ steps.device.outputs.device == 'emulator' }}
run: |
BUILD_TOOLS_DIR=$(ls -d $ANDROID_HOME/build-tools/*/ | sort -V | tail -1)
echo "Found build-tools at: $BUILD_TOOLS_DIR"
echo "$BUILD_TOOLS_DIR" >> $GITHUB_PATH
shell: bash

# See https://github.blog/changelog/2023-02-23-hardware-accelerated-android-virtualization-on-actions-windows-and-linux-larger-hosted-runners/
- name: Enable KVM group perms
if: ${{ steps.device.outputs.device == 'emulator' }}
run: |
echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
sudo udevadm control --reload-rules
sudo udevadm trigger --name-match=kvm

# Make sure that the required directories and .cfg do exists. Workaround to keep ADV happy on `ubuntu-latest`.
- name: Setup Android directories
if: ${{ steps.device.outputs.device == 'emulator' }}
run: |
mkdir -p $HOME/.android
mkdir -p $HOME/.android/avd
touch $HOME/.android/repositories.cfg

- name: Add Android build-tools to PATH
run: |
BUILD_TOOLS_DIR=$(ls -d $ANDROID_HOME/build-tools/*/ | sort -V | tail -1)
echo "Found build-tools at: $BUILD_TOOLS_DIR"
echo "$BUILD_TOOLS_DIR" >> $GITHUB_PATH
shell: bash

- name: Run Android Integration Tests
- name: Run Android Integration Tests (emulator)
if: ${{ steps.device.outputs.device == 'emulator' }}
uses: reactivecircus/android-emulator-runner@0a638108440efd5c7f980e6ba145dbcdd8f32009 # v2.37.0
id: integration-test
timeout-minutes: 30
Expand All @@ -90,13 +116,68 @@ jobs:
-camera-front none
-timezone US/Pacific
-no-metrics
arch: x86_64
arch: ${{ steps.device.outputs.arch }}
script: |
adb wait-for-device
adb shell input keyevent 82
adb devices -l
pwsh -Command '$env:SENTRY_TEST_PLATFORM = "Android"; $env:SENTRY_TEST_APP = "samples/IntegrationTest/Build/test.apk"; Invoke-Pester -Path test/IntegrationTest/Integration.Tests.ps1 -CI'

# --- arm64 path: Redroid container on the arm64 runner (no hypervisor needed) ---

- name: Start Redroid container
if: ${{ steps.device.outputs.device == 'redroid' }}
shell: bash
run: |
set -euo pipefail
# The arm runner image has no Android tooling or binder kernel module. Install adb (talk
# to Redroid over TCP), aapt (the test reads the APK package name), and the binder module.
# Redroid runs the Android userspace directly on the host kernel via binder/ashmem.
sudo apt-get update
sudo apt-get install -y adb aapt "linux-modules-extra-$(uname -r)"
sudo modprobe binder_linux devices="binder,hwbinder,vndbinder"
sudo modprobe ashmem_linux || true # built into the kernel on newer releases; ignore if absent
if [ ! -e /dev/binderfs ] && ! grep -qw binder /proc/filesystems && [ ! -e /dev/binder ]; then
echo "binder is unavailable on this kernel ($(uname -r)); Redroid cannot run." >&2
exit 1
fi
docker run -d --rm --privileged \
--name redroid \
-p 5555:5555 \
redroid/redroid:13.0.0_64only-latest \
androidboot.redroid_gpu_mode=guest

- name: Run Android Integration Tests (redroid)
if: ${{ steps.device.outputs.device == 'redroid' }}
id: integration-test-redroid
timeout-minutes: 30
shell: bash
env:
# adb auto-detects Redroid both on the emulator console port (emulator-5554) and via our
# `adb connect` (localhost:5555). Pin a single serial so bare `adb` commands in the test
# (e.g. the launcher-activity dumpsys) don't fail/misfire with "more than one device".
ANDROID_SERIAL: localhost:5555
run: |
set -euo pipefail
# adbd inside Redroid takes a while to come up. `adb connect` reports success even when the
# port isn't serving yet and the transport stays 'offline', so poll connect + boot state
# together instead of relying on `adb wait-for-device`.
for i in $(seq 1 60); do
adb connect localhost:5555 >/dev/null 2>&1 || true
booted=$(adb -s localhost:5555 shell getprop sys.boot_completed 2>/dev/null | tr -d '\r' || true)
if [ "$booted" = "1" ]; then echo "Redroid booted after $((i * 5))s"; break; fi
if [ "$i" -eq 60 ]; then
echo "Redroid did not boot in time"
adb devices -l || true
docker logs redroid 2>&1 | tail -80 || true
adb -s localhost:5555 logcat -d 2>&1 | tail -100 || true
exit 1
fi
sleep 5
done
adb devices -l
pwsh -Command '$env:SENTRY_TEST_PLATFORM = "Android"; $env:SENTRY_TEST_APP = "samples/IntegrationTest/Build/test.apk"; Invoke-Pester -Path test/IntegrationTest/Integration.Tests.ps1 -CI'

- name: Upload test results on failure
if: ${{ failure() }}
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
Expand Down
9 changes: 9 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,15 @@ package-dev/**/TestSentryOptions.json
package-dev/Tests/Editor/TestFiles/
package-dev/Plugins/*/Sentry/crashpad_handler*

# DependencyConflict integration-test fixture: the DLLs are rebuilt fresh in CI
# (and locally) from DependencyConflictPackage.csproj. Only the hand-authored Unity
# metadata (.meta, asmdef, package.json) is tracked.
test/Scripts.Integration.Test/DependencyConflictPackage/DependencyConflict/Runtime/*.dll
test/Scripts.Integration.Test/DependencyConflictPackage/DependencyConflict/Runtime/*.pdb
test/Scripts.Integration.Test/DependencyConflictPackage/DependencyConflict/Runtime/*.xml
test/Scripts.Integration.Test/DependencyConflictPackage/obj/
test/Scripts.Integration.Test/DependencyConflictPackage/bin/

# Download cache for native SDKs
modules/sentry-native-ndk

Expand Down
20 changes: 20 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -611,6 +611,26 @@ Located in `test/Scripts.Integration.Test/`:
| `build-project.ps1` | Builds for target platform |
| `measure-build-size.ps1` | Compares build size with/without SDK |
| `integration-test.ps1` | Full local integration test |
| `add-dependency-conflict.ps1` | Adds the DependencyConflict alias stress-test package |

### Assembly Aliasing Regression Test (`DependencyConflict`)

`test/Scripts.Integration.Test/DependencyConflictPackage/` is a committed fixture that
stress-tests the SDK's assembly aliasing. It is a tiny UPM package shipping
**plain, unaliased** `System.*`/`Microsoft.*` assemblies at versions that differ
from the ones the SDK ships aliased in `package-dev`. Both packages are installed
into the same integration test project; `IntegrationTester.cs` calls into it on
startup (logging `"Dependencies say hi"`), forcing the unaliased assemblies to be
linked alongside Sentry's aliased copies.

- The DLLs are built in `build.yml` (it has the pinned .NET SDK) and uploaded as
the `dependency-conflict-package` artifact; integration jobs download it and run
`add-dependency-conflict.ps1` to embed it in the test project.
- Only the Unity metadata (`.meta`, asmdef, `package.json`) is committed;
`DependencyConflict/Runtime/*.dll` is gitignored and rebuilt via
`dotnet build test/Scripts.Integration.Test/DependencyConflictPackage`.
- **A red integration build is the regression signal** — if aliasing breaks, the
duplicate assemblies collide and the project no longer builds.

### Local Integration Testing

Expand Down
4 changes: 3 additions & 1 deletion package-dev/assembly-alias.ps1
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
assemblyalias --target-directory "Runtime" --internalize --prefix "Sentry." --assemblies-to-alias "Microsoft*;System*"
# --assemblies-to-exclude: BCL assemblies Unity's unityaot profile already provides. Aliasing them
# mints a duplicate System.Span<T> definition that breaks IL2CPP's intrinsic remap (#2717, #1777).
assemblyalias --target-directory "Runtime" --internalize --prefix "Sentry." --assemblies-to-alias "Microsoft*;System*" --assemblies-to-exclude "System.Buffers;System.Memory;System.Numerics.Vectors;System.Threading.Tasks.Extensions"
Loading
Loading