Skip to content

Commit 1be24c4

Browse files
committed
big. huge. immaculate even. all to fall to a little red x
1 parent 966e3e0 commit 1be24c4

15 files changed

Lines changed: 703 additions & 238 deletions

File tree

.github/workflows/ci.yml

Lines changed: 87 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -27,40 +27,92 @@ jobs:
2727
run: devbox run build
2828

2929
run-e2e-ios:
30-
runs-on: ['macos-15', 'macos-15-intel' ]
30+
runs-on: ['macos-15' ]
3131
env:
3232
YARN_ENABLE_HARDENED_MODE: 0
33+
XCODE_VERSION: '26.1.1'
34+
strategy:
35+
matrix:
36+
include:
37+
- name: ios-min
38+
ios-device: "iPhone 14"
39+
ios-runtime: "18.5"
40+
- name: ios-latest
41+
ios-device: "iPhone 17"
42+
ios-runtime: "26.1"
3343
steps:
3444
- uses: maxim-lobanov/setup-xcode@v1
3545
with:
3646
xcode-version: '26.1.1'
3747
- uses: actions/checkout@v4
48+
- name: CocoaPods cache
49+
uses: actions/cache@v4
50+
with:
51+
path: |
52+
~/Library/Caches/CocoaPods
53+
key: cocoapods-${{ runner.os }}-${{ env.XCODE_VERSION }}-${{ hashFiles('examples/E2E/ios/Podfile.lock') }}
54+
restore-keys: |
55+
cocoapods-${{ runner.os }}-${{ env.XCODE_VERSION }}-
56+
cocoapods-${{ runner.os }}-
57+
- name: DerivedData cache
58+
uses: actions/cache@v4
59+
with:
60+
path: |
61+
~/Library/Developer/Xcode/DerivedData
62+
key: derived-${{ runner.os }}-${{ env.XCODE_VERSION }}-${{ hashFiles('examples/E2E/ios/Podfile.lock') }}
63+
restore-keys: |
64+
derived-${{ runner.os }}-${{ env.XCODE_VERSION }}-
65+
derived-${{ runner.os }}-
3866
- name: devbox installer
3967
uses: jetify-com/devbox-install-action@v0.14.0
4068
with:
4169
enable-cache: 'true'
4270
# --omit-nix-env is important to use the macos system c toolchain instead of the nix toolchain
43-
- name: devbox shell
44-
run: devbox shell --omit-nix-env
45-
- name: setup ios devices
46-
run: devbox run setup-ios-devices
47-
- name: IOS E2E Tests
48-
run: devbox run test-ios
71+
- name: iOS setup (simulators, pods)
72+
env:
73+
IOS_DEVICE_NAMES: ${{ matrix.ios-device }}
74+
IOS_RUNTIME: ${{ matrix.ios-runtime }}
75+
run: |
76+
set -euo pipefail
77+
devbox shell --omit-nix-env --command "devbox run setup-ios && yarn install && yarn e2e install && yarn e2e pods"
78+
- name: iOS build
79+
run: |
80+
set -euo pipefail
81+
devbox shell --omit-nix-env --command "yarn build && yarn e2e build:ios"
82+
- name: iOS E2E Tests
83+
env:
84+
DETOX_IOS_DEVICE: ${{ matrix.ios-device }}
85+
run: |
86+
set -euo pipefail
87+
devbox shell --omit-nix-env --command "DETOX_IOS_DEVICE='${{ matrix.ios-device }}' yarn e2e test:ios"
4988
5089
run-e2e-android:
5190
runs-on: 'ubuntu-22.04'
91+
env:
92+
# Default to both minsdk and latest; override ANDROID_MATRIX env to narrow/expand if needed.
93+
ANDROID_MATRIX: >
94+
[
95+
{"name":"android-min","avd-name":"pixel_API21_x86_64","start-script":"start-android-minsdk"},
96+
{"name":"android-latest","avd-name":"medium_phone_API33_x86_64","start-script":"start-android-latest"}
97+
]
5298
strategy:
5399
matrix:
54-
api-level: [21]
55-
profile: ['pixel']
100+
include: ${{ fromJson(env.ANDROID_MATRIX) }}
56101
steps:
57102
- uses: actions/checkout@v4
103+
- name: Yarn cache
104+
uses: actions/cache@v4
105+
with:
106+
path: |
107+
~/.cache/yarn
108+
.yarn/cache
109+
key: yarn-${{ runner.os }}-${{ hashFiles('**/yarn.lock') }}
110+
restore-keys: |
111+
yarn-${{ runner.os }}-
58112
- name: devbox installer
59113
uses: jetify-com/devbox-install-action@v0.14.0
60114
with:
61115
enable-cache: 'true'
62-
- name: devbox shell
63-
run: devbox shell
64116
- name: Gradle cache
65117
uses: actions/cache@v4
66118
with:
@@ -75,28 +127,28 @@ jobs:
75127
path: |
76128
~/.android/avd/*
77129
~/.android/adb*
78-
key: avd-${{ matrix.api-level }}-${{matrix.profile}}
130+
key: avd-${{ matrix.avd-name }}
79131

80-
- name: create AVD and generate snapshot for caching
81-
if: steps.avd-cache.outputs.cache-hit != 'true'
82-
uses: reactivecircus/android-emulator-runner@v2
83-
with:
84-
api-level: ${{ matrix.api-level }}
85-
profile: ${{matrix.profile}}
86-
avd-name: Pixel_API_21
87-
target: default
88-
force-avd-creation: false
89-
emulator-options: -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
90-
disable-animations: false
91-
script: echo "Generated AVD snapshot for caching."
92-
- name: Detox - Test
93-
uses: reactivecircus/android-emulator-runner@v2
94-
with:
95-
api-level: ${{ matrix.api-level }}
96-
profile: ${{matrix.profile}}
97-
avd-name: Pixel_API_21
98-
target: default
99-
force-avd-creation: false
100-
emulator-options: -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
101-
disable-animations: true
102-
script: devbox run test-android
132+
- name: Android setup (AVD + deps)
133+
env:
134+
DETOX_AVD: ${{ matrix.avd-name }}
135+
EMU_HEADLESS: "1"
136+
AVD_FLAVOR: ${{ startsWith(matrix.avd-name, 'pixel') && 'minsdk' || 'latest' }}
137+
run: |
138+
set -euo pipefail
139+
devbox run ${{ matrix.start-script }}
140+
devbox run setup-android
141+
yarn install
142+
yarn e2e install
143+
144+
- name: Android build
145+
run: |
146+
set -euo pipefail
147+
devbox run setup-android
148+
yarn build
149+
yarn e2e build:android
150+
151+
- name: Android E2E Tests
152+
env:
153+
DETOX_AVD: ${{ matrix.avd-name }}
154+
run: devbox run test-android

.github/workflows/publish.yml

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -35,18 +35,15 @@ jobs:
3535
cache: yarn
3636
# End workaround
3737

38-
- name: Config and Build
39-
run: |
40-
npm config set //registry.npmjs.org/:_authToken ${NPM_TOKEN}
41-
yarn install --immutable
42-
yarn build
43-
env:
44-
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
38+
- name: devbox installer
39+
uses: jetify-com/devbox-install-action@v0.14.0
40+
with:
41+
enable-cache: 'true'
4542

46-
- name: Publish (All)
47-
if: github.event.inputs.workspace == ''
48-
run: yarn release
43+
- name: Config, Build, Release
44+
run: devbox run release
4945
env:
46+
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
5047
GH_TOKEN: ${{ secrets.GH_TOKEN }}
5148
YARN_NPM_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
5249

devbox.json

Lines changed: 70 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,22 +11,11 @@
1111
"jq": "latest",
1212
"path:./nix#android-sdk": "",
1313
},
14-
"nix_config": {
15-
"extra-experimental-features": "nix-command flakes"
16-
},
1714
"shell": {
1815
"init_hook": [
1916
"echo 'Welcome to analytics-react-native devbox!' > /dev/null",
20-
"sdk_source=\"\"",
21-
"if [ -n \"${ANDROID_SDK_ROOT:-}\" ]; then sdk_source=\"user-defined ANDROID_SDK_ROOT\"; fi",
22-
"if [ -z \"$sdk_source\" ] && [ -n \"${ANDROID_HOME:-}\" ]; then ANDROID_SDK_ROOT=\"$ANDROID_HOME\"; sdk_source=\"user-defined ANDROID_HOME\"; fi",
23-
"if [ -z \"$sdk_source\" ]; then SM=\"\"; for CAND in $(command -v -a sdkmanager 2>/dev/null || true); do if echo \"$CAND\" | grep -q '^/nix/store/'; then SM=\"$CAND\"; break; fi; done; if [ -n \"$SM\" ]; then SM=$(readlink -f \"$SM\" 2>/dev/null || echo \"$SM\"); for C in \"$(dirname \"$SM\")/..\" \"$(dirname \"$SM\")/../share/android-sdk\" \"$(dirname \"$SM\")/../libexec/android-sdk\" \"$(dirname \"$SM\")/../..\"; do if [ -d \"$C/platform-tools\" ] || [ -d \"$C/platforms\" ] || [ -d \"$C/system-images\" ]; then ANDROID_SDK_ROOT=\"$C\"; sdk_source=\"nix sdkmanager\"; break; fi; done; fi; fi",
24-
"if [ -z \"$sdk_source\" ]; then if [ \"$(uname -s)\" = \"Darwin\" ]; then ANDROID_SDK_ROOT=\"$HOME/Library/Android/sdk\"; else ANDROID_SDK_ROOT=\"$HOME/Android/Sdk\"; fi; sdk_source=\"OS default\"; fi",
25-
"export ANDROID_SDK_ROOT",
26-
"if [ -z \"${ANDROID_HOME:-}\" ]; then export ANDROID_HOME=\"$ANDROID_SDK_ROOT\"; fi",
27-
"if [ -n \"${ANDROID_SDK_ROOT:-}\" ]; then export PATH=\"$ANDROID_SDK_ROOT/emulator:$ANDROID_SDK_ROOT/platform-tools:$ANDROID_SDK_ROOT/cmdline-tools/latest/bin:$PATH\"; fi",
28-
"echo \"Using Android SDK: $ANDROID_SDK_ROOT (source: $sdk_source)\"",
29-
"if [ \"$sdk_source\" = \"OS default\" ]; then echo \"Note: Nix flake android-sdk not detected; run 'devbox install' (or 'devbox add path:./nix#android-sdk') to ensure the flake SDK is pulled.\"; fi",
17+
"source \"$DEVBOX_PROJECT_ROOT/scripts/android-env.sh\"",
18+
"echo 'Android SDK env configured (details: wiki/devbox.md#devbox-android).'",
3019
],
3120
"scripts": {
3221
"clean": [
@@ -43,13 +32,15 @@
4332
"yarn test --coverage",
4433
],
4534
"test-android": [
35+
"devbox run setup-android",
4636
"yarn install",
4737
"yarn e2e install",
4838
"yarn build",
4939
"yarn e2e build:android",
5040
"yarn e2e test:android",
5141
],
5242
"test-ios": [
43+
"devbox run setup-ios",
5344
"yarn install",
5445
"yarn e2e install",
5546
"yarn e2e pods",
@@ -58,10 +49,74 @@
5849
"yarn e2e test:ios",
5950
],
6051
"setup-android": [
61-
"bash $DEVBOX_PROJECT_ROOT/scripts/setup-android.sh",
52+
"bash $DEVBOX_PROJECT_ROOT/scripts/android-setup.sh",
6253
],
6354
"setup-ios": [
64-
"bash $DEVBOX_PROJECT_ROOT/scripts/setup-ios.sh",
55+
"bash $DEVBOX_PROJECT_ROOT/scripts/ios-setup.sh",
56+
],
57+
"start-emulator": [
58+
"bash $DEVBOX_PROJECT_ROOT/scripts/android-manager.sh start"
59+
],
60+
"start-ios": [
61+
"bash $DEVBOX_PROJECT_ROOT/scripts/ios-manager.sh start"
62+
],
63+
"start-android-minsdk": [
64+
"bash $DEVBOX_PROJECT_ROOT/scripts/android-manager.sh start"
65+
],
66+
"start-android-latest": [
67+
"AVD_FLAVOR=latest bash $DEVBOX_PROJECT_ROOT/scripts/android-manager.sh start"
68+
],
69+
"start-android": [
70+
"bash $DEVBOX_PROJECT_ROOT/scripts/android-manager.sh start"
71+
],
72+
"release": [
73+
"npm config set //registry.npmjs.org/:_authToken ${NPM_TOKEN}",
74+
"yarn install --immutable",
75+
"yarn build",
76+
"yarn release"
77+
],
78+
"reset-android": [
79+
"rm -rf ~/.android/avd",
80+
"rm -f ~/.android/adbkey*",
81+
"echo \"AVDs and adb keys removed. Recreate via devbox run start-android* as needed.\""
82+
],
83+
"reset-ios": [
84+
"xcrun simctl shutdown all || true",
85+
"xcrun simctl erase all || true",
86+
"rm -rf ~/Library/Developer/CoreSimulator/Devices",
87+
"echo \"Simulators reset. Recreate via devbox run start-ios.\""
88+
],
89+
"stop-android": [
90+
"if command -v adb >/dev/null 2>&1; then",
91+
" devices=$(adb devices -l 2>/dev/null | tail -n +2 | awk '{print $1}' | tr '\\n' ' ');",
92+
" if [[ -n \"$devices\" ]]; then",
93+
" echo \"Stopping Android emulators: $devices\";",
94+
" for d in $devices; do adb -s \"$d\" emu kill >/dev/null 2>&1 || true; done;",
95+
" else",
96+
" echo \"No Android emulators detected via adb.\";",
97+
" fi;",
98+
"else",
99+
" echo \"adb not found; skipping Android emulator shutdown.\";",
100+
"fi",
101+
"pkill -f \"emulator@\" >/dev/null 2>&1 || true",
102+
"echo \"Android emulators stopped (if any were running).\""
103+
],
104+
"stop-ios": [
105+
"if command -v xcrun >/dev/null 2>&1 && xcrun -f simctl >/dev/null 2>&1; then",
106+
" if xcrun simctl list devices booted | grep -q \"Booted\"; then",
107+
" echo \"Shutting down booted iOS simulators...\";",
108+
" xcrun simctl shutdown all >/dev/null 2>&1 || true;",
109+
" else",
110+
" echo \"No booted iOS simulators detected.\";",
111+
" fi;",
112+
"else",
113+
" echo \"simctl not available; skipping iOS shutdown.\";",
114+
"fi",
115+
"echo \"iOS simulators shutdown (if any were running).\""
116+
],
117+
"stop": [
118+
"devbox run stop-android",
119+
"devbox run stop-ios"
65120
],
66121
"test": [
67122
"devbox run test-android",

examples/E2E/.detoxrc.js

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,8 @@ module.exports = {
5151
simulator: {
5252
type: 'ios.simulator',
5353
device: {
54-
type: 'iPhone 17'
54+
// Allow CI/local override; defaults to iPhone 17 on latest runtime.
55+
type: process.env.DETOX_IOS_DEVICE || 'iPhone 17'
5556
}
5657
},
5758
attached: {
@@ -63,7 +64,12 @@ module.exports = {
6364
emulator: {
6465
type: 'android.emulator',
6566
device: {
66-
avdName: process.env.CI ? 'Pixel_API_21_AOSP': 'Medium_Phone_API_24'
67+
// Default to latest AVD name (arch-aware); override via DETOX_AVD. For minsdk testing, set DETOX_AVD to an API 21 AVD.
68+
avdName: (() => {
69+
if (process.env.DETOX_AVD) return process.env.DETOX_AVD;
70+
const arch = require('os').arch();
71+
return arch === 'arm64' ? 'medium_phone_API33_arm64_v8a' : 'medium_phone_API33_x86_64';
72+
})()
6773
}
6874
}
6975
},

examples/E2E/android/build.gradle

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22

33
buildscript {
44
ext {
5-
buildToolsVersion = "33.0.0"
5+
// Default to the build-tools pinned in devbox; allow override via ANDROID_BUILD_TOOLS_VERSION.
6+
buildToolsVersion = System.getenv("ANDROID_BUILD_TOOLS_VERSION") ?: "33.0.0"
67
minSdkVersion = 21
78
compileSdkVersion = 33
89
targetSdkVersion = 33
@@ -34,4 +35,4 @@ allprojects {
3435
jcenter()
3536
maven { url 'https://www.jitpack.io' }
3637
}
37-
}
38+
}
0 Bytes
Binary file not shown.

nix/flake.nix

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,18 @@
3030
};
3131

3232
androidPkgs = pkgs.androidenv.composeAndroidPackages {
33-
platformVersions = ["21"];
33+
# Keep API 21 images for the AVD and add API 33 for React Native builds.
34+
platformVersions = [ "21" "33" ];
35+
buildToolsVersions = [ "30.0.3" "33.0.0" "latest" ];
36+
cmdLineToolsVersion = "19.0";
3437
includeEmulator = true;
3538
includeSystemImages = true;
3639
includeNDK = true;
3740
};
3841
in
3942
{
4043
android-sdk = androidPkgs.androidsdk;
44+
default = androidPkgs.androidsdk;
4145
});
4246
};
4347
}

0 commit comments

Comments
 (0)