Skip to content

Commit ccb7a20

Browse files
abueideclaude
andcommitted
feat(plugins): add unified setup command for SDK pre-evaluation
Add a generic `devbox run setup` command to all plugins that: - Pre-evaluates and caches SDKs before parallel build phases - Respects ANDROID_SKIP_SETUP and IOS_SKIP_SETUP flags - Is idempotent and safe to call multiple times - Works in any project (Android, iOS, or React Native) Implementation: - plugins/android: setup script evaluates Nix flake, ensures ANDROID_SDK_ROOT - plugins/ios: setup script verifies Xcode/iOS toolchain readiness - plugins/react-native: setup orchestrates both Android and iOS (respecting skip flags) This fixes race conditions in CI where builds started before SDK evaluation completed, causing "ANDROID_HOME not set" and "xcrun simctl" failures. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
1 parent 0f34fbc commit ccb7a20

6 files changed

Lines changed: 155 additions & 1 deletion

File tree

plugins/android/plugin.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
"{{ .Virtenv }}/scripts/user/android.sh": "virtenv/scripts/user/android.sh",
5353
"{{ .Virtenv }}/scripts/user/config.sh": "virtenv/scripts/user/config.sh",
5454
"{{ .Virtenv }}/scripts/user/devices.sh": "virtenv/scripts/user/devices.sh",
55+
"{{ .Virtenv }}/scripts/user/setup.sh": "virtenv/scripts/user/setup.sh",
5556
"{{ .Virtenv }}/scripts/init/init-hook.sh": "virtenv/scripts/init/init-hook.sh",
5657
"{{ .Virtenv }}/scripts/init/setup.sh": "virtenv/scripts/init/setup.sh",
5758
"{{ .Virtenv }}/flake.nix": "virtenv/flake.nix",
@@ -64,6 +65,9 @@
6465
". {{ .Virtenv }}/scripts/init/setup.sh"
6566
],
6667
"scripts": {
68+
"setup": [
69+
"bash {{ .Virtenv }}/scripts/user/setup.sh"
70+
],
6771
"android:devices:eval": [
6872
"ANDROID_SDK_REQUIRED=0 android.sh devices eval"
6973
],
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
#!/usr/bin/env bash
2+
# Android Plugin - Setup Script
3+
# Pre-evaluates and caches Android SDK for fast subsequent operations
4+
# Safe to call multiple times (idempotent)
5+
6+
set -eu
7+
8+
# Skip if ANDROID_SKIP_SETUP=1
9+
if [ "${ANDROID_SKIP_SETUP:-0}" = "1" ]; then
10+
echo "⏭️ Skipping Android setup (ANDROID_SKIP_SETUP=1)"
11+
exit 0
12+
fi
13+
14+
echo "🔧 Setting up Android environment..."
15+
16+
# Source the init setup to trigger SDK evaluation
17+
if [ -n "${ANDROID_SCRIPTS_DIR:-}" ] && [ -f "${ANDROID_SCRIPTS_DIR}/init/setup.sh" ]; then
18+
. "${ANDROID_SCRIPTS_DIR}/init/setup.sh"
19+
fi
20+
21+
# Verify SDK was set up
22+
if [ -z "${ANDROID_SDK_ROOT:-}" ]; then
23+
echo "❌ Android SDK setup failed: ANDROID_SDK_ROOT not set" >&2
24+
exit 1
25+
fi
26+
27+
if [ ! -d "${ANDROID_SDK_ROOT}" ]; then
28+
echo "❌ Android SDK setup failed: ANDROID_SDK_ROOT directory does not exist: ${ANDROID_SDK_ROOT}" >&2
29+
exit 1
30+
fi
31+
32+
echo "✅ Android SDK ready: ${ANDROID_SDK_ROOT}"
33+
34+
# Verify essential tools are in PATH
35+
if ! command -v adb >/dev/null 2>&1; then
36+
echo "⚠️ Warning: adb not in PATH" >&2
37+
fi
38+
39+
if ! command -v emulator >/dev/null 2>&1; then
40+
echo "⚠️ Warning: emulator not in PATH" >&2
41+
fi
42+
43+
echo "✅ Android setup complete"

plugins/ios/plugin.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
"{{ .Virtenv }}/scripts/user/config.sh": "virtenv/scripts/user/config.sh",
5151
"{{ .Virtenv }}/scripts/user/ios.sh": "virtenv/scripts/user/ios.sh",
5252
"{{ .Virtenv }}/scripts/user/devices.sh": "virtenv/scripts/user/devices.sh",
53+
"{{ .Virtenv }}/scripts/user/setup.sh": "virtenv/scripts/user/setup.sh",
5354
"{{ .Virtenv }}/scripts/init/init-hook.sh": "virtenv/scripts/init/init-hook.sh",
5455
"{{ .Virtenv }}/scripts/init/setup.sh": "virtenv/scripts/init/setup.sh",
5556
"{{ .DevboxDir }}/devices/min.json": "config/devices/min.json",
@@ -61,6 +62,9 @@
6162
". {{ .Virtenv }}/scripts/init/setup.sh"
6263
],
6364
"scripts": {
65+
"setup": [
66+
"bash {{ .Virtenv }}/scripts/user/setup.sh"
67+
],
6468
"ios:devices:eval": [
6569
"ios.sh devices eval"
6670
],
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
#!/usr/bin/env bash
2+
# iOS Plugin - Setup Script
3+
# Ensures iOS development environment is ready
4+
# Safe to call multiple times (idempotent)
5+
6+
set -eu
7+
8+
# Skip if IOS_SKIP_SETUP=1
9+
if [ "${IOS_SKIP_SETUP:-0}" = "1" ]; then
10+
echo "⏭️ Skipping iOS setup (IOS_SKIP_SETUP=1)"
11+
exit 0
12+
fi
13+
14+
# Only run on macOS
15+
if [ "$(uname -s)" != "Darwin" ]; then
16+
echo "⏭️ Skipping iOS setup (not macOS)"
17+
exit 0
18+
fi
19+
20+
echo "🔧 Setting up iOS environment..."
21+
22+
# Source the init setup
23+
if [ -n "${IOS_SCRIPTS_DIR:-}" ] && [ -f "${IOS_SCRIPTS_DIR}/init/setup.sh" ]; then
24+
. "${IOS_SCRIPTS_DIR}/init/setup.sh"
25+
fi
26+
27+
# Verify Xcode is available
28+
if ! command -v xcrun >/dev/null 2>&1; then
29+
echo "❌ iOS setup failed: xcrun not found (Xcode not installed?)" >&2
30+
exit 1
31+
fi
32+
33+
# Verify simctl works
34+
if ! xcrun simctl list devices >/dev/null 2>&1; then
35+
echo "❌ iOS setup failed: xcrun simctl not working" >&2
36+
exit 1
37+
fi
38+
39+
# Verify IOS_DEVELOPER_DIR is set
40+
if [ -z "${IOS_DEVELOPER_DIR:-}" ]; then
41+
echo "⚠️ Warning: IOS_DEVELOPER_DIR not set" >&2
42+
fi
43+
44+
echo "✅ iOS environment ready"
45+
echo "✅ iOS setup complete"

plugins/react-native/plugin.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,14 +36,18 @@
3636
"{{ .Virtenv }}/scripts/init/init-hook.sh": "virtenv/scripts/init/init-hook.sh",
3737
"{{ .Virtenv }}/scripts/lib/lib.sh": "virtenv/scripts/lib/lib.sh",
3838
"{{ .Virtenv }}/scripts/user/rn.sh": "virtenv/scripts/user/rn.sh",
39-
"{{ .Virtenv }}/scripts/user/metro.sh": "virtenv/scripts/user/metro.sh"
39+
"{{ .Virtenv }}/scripts/user/metro.sh": "virtenv/scripts/user/metro.sh",
40+
"{{ .Virtenv }}/scripts/user/setup.sh": "virtenv/scripts/user/setup.sh"
4041
},
4142
"shell": {
4243
"init_hook": [
4344
". {{ .Virtenv }}/scripts/init/init-hook.sh",
4445
"export NODE_BINARY=\"$(command -v node)\""
4546
],
4647
"scripts": {
48+
"setup": [
49+
"bash {{ .Virtenv }}/scripts/user/setup.sh"
50+
],
4751
"rn:metro:port": [
4852
"rn.sh metro port ${1:-default}"
4953
],
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
#!/usr/bin/env bash
2+
# React Native Plugin - Setup Script
3+
# Sets up both Android and iOS environments (respecting skip flags)
4+
# Safe to call multiple times (idempotent)
5+
6+
set -eu
7+
8+
echo "🔧 Setting up React Native environment..."
9+
10+
# Track if any setup was performed
11+
setup_performed=0
12+
13+
# Setup Android (unless skipped)
14+
if [ "${ANDROID_SKIP_SETUP:-0}" != "1" ]; then
15+
if [ -n "${ANDROID_SCRIPTS_DIR:-}" ] && [ -f "${ANDROID_SCRIPTS_DIR}/user/setup.sh" ]; then
16+
bash "${ANDROID_SCRIPTS_DIR}/user/setup.sh"
17+
setup_performed=1
18+
else
19+
echo "⚠️ Android plugin not found (ANDROID_SCRIPTS_DIR not set)"
20+
fi
21+
else
22+
echo "⏭️ Skipping Android setup (ANDROID_SKIP_SETUP=1)"
23+
fi
24+
25+
# Setup iOS (unless skipped or not on macOS)
26+
if [ "${IOS_SKIP_SETUP:-0}" != "1" ]; then
27+
if [ "$(uname -s)" = "Darwin" ]; then
28+
if [ -n "${IOS_SCRIPTS_DIR:-}" ] && [ -f "${IOS_SCRIPTS_DIR}/user/setup.sh" ]; then
29+
bash "${IOS_SCRIPTS_DIR}/user/setup.sh"
30+
setup_performed=1
31+
else
32+
echo "⚠️ iOS plugin not found (IOS_SCRIPTS_DIR not set)"
33+
fi
34+
else
35+
echo "⏭️ Skipping iOS setup (not macOS)"
36+
fi
37+
else
38+
echo "⏭️ Skipping iOS setup (IOS_SKIP_SETUP=1)"
39+
fi
40+
41+
# Verify Node.js is available (required for React Native)
42+
if ! command -v node >/dev/null 2>&1; then
43+
echo "⚠️ Warning: Node.js not found (required for React Native)" >&2
44+
fi
45+
46+
if ! command -v npm >/dev/null 2>&1; then
47+
echo "⚠️ Warning: npm not found (required for React Native)" >&2
48+
fi
49+
50+
if [ "$setup_performed" -eq 0 ]; then
51+
echo "⚠️ No platforms were set up (all skipped)"
52+
fi
53+
54+
echo "✅ React Native setup complete"

0 commit comments

Comments
 (0)