Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
f61790b
feat(android): Move flake.nix to devbox.d for version control
abueide Apr 20, 2026
b7468ce
feat(android): Add android.lock and unified sync command
abueide Apr 20, 2026
e591c81
feat: Add automatic doctor checks on shell init
abueide Apr 20, 2026
d7f597e
refactor: Move doctor init checks to init layer
abueide Apr 20, 2026
0db92e9
fix(android): address PR review feedback - security, deduplication, a…
abueide Apr 20, 2026
036cbb1
fix(react-native): disable Android NDK and CMake by default
abueide Apr 20, 2026
18a2f95
feat(android): detect and explain nixpkgs hash mismatch errors
abueide Apr 20, 2026
b609e63
feat(android): add automatic hash mismatch detection and fix
abueide Apr 20, 2026
56c1f97
feat(android): make hash mismatch fix fully automatic
abueide Apr 20, 2026
69308d0
fix(android): preserve reproducibility by committing hash overrides
abueide Apr 20, 2026
7ac0871
fix: address code review issues in Android plugin scripts
abueide Apr 20, 2026
07c92bb
fix(react-native): re-enable NDK to fix E2E build failures
abueide Apr 20, 2026
4834133
fix(android): use RETURN trap for function-scope cleanup
abueide Apr 20, 2026
a1f92b6
fix(android): update min device from API 21 to API 24
abueide Apr 20, 2026
b7ffde6
fix(android): implement hash override mechanism in flake
abueide Apr 21, 2026
89ba3fc
fix(android): fix case typo in includeCMake check
abueide Apr 21, 2026
3c88b92
fix(android): respect ANDROID_DEVICES filter in device sync
abueide Apr 21, 2026
133bdc6
fix: filter devices in AVD setup and fix iOS log noise
abueide Apr 21, 2026
894e966
fix(android): fix device filtering and add early failure detection
abueide Apr 21, 2026
a11abb1
fix(tests): update validation test to check for pixel_api24 instead o…
abueide Apr 21, 2026
d974264
fix(android): make deploy-app fail fast when emulator boot fails
abueide Apr 21, 2026
00db7cb
fix(android): remove bash-specific trap RETURN for POSIX compliance
abueide Apr 21, 2026
45d3fc9
refactor: change all script shebangs to bash for reproducibility
abueide Apr 21, 2026
6620ca0
fix(tests): prevent cleanup processes from hanging on failed deployments
abueide Apr 21, 2026
930274a
docs: remove documentation files (will be in separate PR)
abueide Apr 21, 2026
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,4 @@ examples/*/reports/
examples/*/test-results/
plugins/*/tests/reports/
plugins/*/tests/test-results/
notes/
12 changes: 7 additions & 5 deletions examples/android/devbox.d/android/devices/devices.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,16 @@
"name": "medium_phone_api36",
"api": 36,
"device": "medium_phone",
"tag": "google_apis"
"tag": "google_apis",
"filename": "max"
},
{
"name": "pixel_api21",
"api": 21,
"name": "pixel_api24",
"api": 24,
"device": "pixel",
"tag": "google_apis"
"tag": "google_apis",
"filename": "min"
}
],
"checksum": "8df4d3393b61fbbb08e45cf8762f95c521316938e514527916e4fce88a849d57"
"checksum": "9c9adf202cb494e4d6554d790fab9455481658cf70e7d0a0abcdb0ae9824ddc0"
}
4 changes: 2 additions & 2 deletions examples/android/devbox.d/android/devices/min.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "pixel_api21",
"api": 21,
"name": "pixel_api24",
"api": 24,
"device": "pixel",
"tag": "google_apis"
}
27 changes: 27 additions & 0 deletions examples/android/devbox.d/android/flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

138 changes: 138 additions & 0 deletions examples/android/devbox.d/android/flake.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
{
description = "Android SDK tools for Devbox (plugin local flake)";

inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";

outputs =
{ self, nixpkgs }:
let
systems = [
"x86_64-linux"
"aarch64-linux"
"x86_64-darwin"
"aarch64-darwin"
];

# Read generated android.json (created from env vars by android-init.sh)
# On first initialization, android.json may not exist yet, so provide defaults
configFileExists = builtins.pathExists ./android.json;
versionData = if configFileExists
then builtins.fromJSON (builtins.readFile ./android.json)
else {
# Default values for initial flake evaluation before android-init.sh runs
ANDROID_BUILD_TOOLS_VERSION = "36.1.0";
ANDROID_CMDLINE_TOOLS_VERSION = "19.0";
ANDROID_SYSTEM_IMAGE_TAG = "google_apis";
ANDROID_INCLUDE_NDK = false;
ANDROID_NDK_VERSION = "27.0.12077973";
ANDROID_INCLUDE_CMAKE = false;
ANDROID_CMAKE_VERSION = "3.22.1";
};
defaultsData = if builtins.hasAttr "defaults" versionData then versionData.defaults else versionData;
getVar =
name:
if builtins.hasAttr name defaultsData then toString (builtins.getAttr name defaultsData)
else builtins.throw "Missing required value in android.json: ${name}";

unique =
list:
builtins.foldl' (
acc: item: if builtins.elem item acc then acc else acc ++ [ item ]
) [ ] list;

lockData =
if builtins.pathExists ./devices.lock
then builtins.fromJSON (builtins.readFile ./devices.lock)
else { devices = [ ]; };

# Extract API versions from lock file devices array, default to latest if empty
deviceApis =
if builtins.hasAttr "devices" lockData && (builtins.length lockData.devices) > 0
then map (device: device.api) lockData.devices
else [ 36 ]; # Default to latest stable API

# Include ANDROID_COMPILE_SDK in platform versions if set (for projects
# that compile against a different API than the emulator/device targets)
compileSdkApis =
if builtins.hasAttr "ANDROID_COMPILE_SDK" defaultsData
then [ (toString defaultsData.ANDROID_COMPILE_SDK) ]
else [];

androidSdkConfig = {
platformVersions = unique ((map toString deviceApis) ++ compileSdkApis);
buildToolsVersion = getVar "ANDROID_BUILD_TOOLS_VERSION";
cmdLineToolsVersion = getVar "ANDROID_CMDLINE_TOOLS_VERSION";
systemImageTypes = [ (getVar "ANDROID_SYSTEM_IMAGE_TAG") ];
includeNDK =
if builtins.hasAttr "ANDROID_INCLUDE_NDK" defaultsData then defaultsData.ANDROID_INCLUDE_NDK else false;
ndkVersion = getVar "ANDROID_NDK_VERSION";
includeCMake =
if builtins.hasAttr "ANDROID_INCLUDE_CMAKE" defaultsData then defaultsData.ANDROID_INCLUDE_CMAKE else false;
cmakeVersion = getVar "ANDROID_CMAKE_VERSION";
};

# Hash overrides for when Google updates files on their servers
# These can be set in android.json to work around nixpkgs hash mismatches
hashOverrides = if builtins.hasAttr "hash_overrides" versionData
then versionData.hash_overrides
else {};

forAllSystems =
f:
builtins.listToAttrs (
map (system: {
name = system;
value = f system;
}) systems
);
in
{
packages = forAllSystems (
system:
let
pkgs = import nixpkgs {
inherit system;
config = {
allowUnfree = true;
android_sdk.accept_license = true;
};
};

abiVersions = if builtins.match "aarch64-.*" system != null then [ "arm64-v8a" ] else [ "x86_64" ];

# Apply hash overrides to nixpkgs if any are specified
pkgsWithOverrides = if (builtins.length (builtins.attrNames hashOverrides)) > 0
then pkgs.appendOverlays [(final: prev: {
fetchurl = args: prev.fetchurl (args // (
if builtins.hasAttr (args.url or "") hashOverrides
then { sha256 = hashOverrides.${args.url}; }
else {}
));
})]
else pkgs;

androidPkgs =
config:
pkgsWithOverrides.androidenv.composeAndroidPackages {
platformVersions = config.platformVersions;
buildToolsVersions = [ config.buildToolsVersion ];
cmdLineToolsVersion = config.cmdLineToolsVersion;
includeEmulator = true;
includeSystemImages = true;
includeNDK = config.includeNDK;
ndkVersions = if config.includeNDK && config.ndkVersion != "" then [ config.ndkVersion ] else [ ];
includeCmake = config.includeCMake;
cmakeVersions = if config.includeCMake && config.cmakeVersion != "" then [ config.cmakeVersion ] else [ ];
abiVersions = abiVersions;
systemImageTypes = config.systemImageTypes;
};
in
{
android-sdk = (androidPkgs androidSdkConfig).androidsdk;
default = (androidPkgs androidSdkConfig).androidsdk;
}
);

androidSdkConfig = androidSdkConfig;
};
}
Loading
Loading