diff --git a/.github/workflows/ci-fast.yml b/.github/workflows/ci-fast.yml deleted file mode 100644 index 6d110a051..000000000 --- a/.github/workflows/ci-fast.yml +++ /dev/null @@ -1,24 +0,0 @@ -name: CI Fast - -on: - push: - branches: [master, beta] - pull_request: - branches: [master, beta] - -concurrency: - group: ci-fast-${{ github.ref }} - cancel-in-progress: true - -jobs: - build-and-test: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: devbox installer - uses: jetify-com/devbox-install-action@v0.14.0 - with: - project-path: shells/devbox-fast.json - enable-cache: 'false' - - name: build - run: devbox run --config=shells/devbox-fast.json build diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 000000000..866948e43 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,47 @@ +name: CI + +on: + push: + branches: [master, beta] + pull_request: + branches: [master, beta] + +concurrency: + group: ci-${{ github.ref }} + cancel-in-progress: true + +jobs: + ci: + name: Lint + Build + Test + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Install devbox + uses: jetify-com/devbox-install-action@v0.14.0 + - name: Install dependencies + run: devbox run ci:install + - name: Lint (eslint) + run: devbox run lint + - name: Lint (formatting) + run: devbox run format-check + - name: Build + run: devbox run build + - name: Typecheck + run: devbox run typecheck + - name: Test + run: devbox run test + + commitlint: + name: Commitlint + if: github.event_name == 'pull_request' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Install devbox + uses: jetify-com/devbox-install-action@v0.14.0 + - name: Install dependencies + run: devbox run ci:install + - name: Validate PR title + run: devbox run ci:commitlint + env: + PR_TITLE: ${{ github.event.pull_request.title }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 49fcc8783..bec246d31 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -17,22 +17,29 @@ concurrency: cancel-in-progress: true jobs: - fast-checks: - name: Build + Lint + ci: + name: Lint + Build + Test runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - name: devbox installer + - name: Install devbox uses: jetify-com/devbox-install-action@v0.14.0 - with: - project-path: shells/devbox-fast.json - enable-cache: 'false' - - name: build - run: devbox run --config=shells/devbox-fast.json build + - name: Install dependencies + run: devbox run ci:install + - name: Lint (eslint) + run: devbox run lint + - name: Lint (formatting) + run: devbox run format-check + - name: Build + run: devbox run build + - name: Typecheck + run: devbox run typecheck + - name: Test + run: devbox run test release: name: Release (${{ inputs.type }}) - needs: [fast-checks] + needs: [ci] runs-on: ubuntu-latest environment: Publish permissions: @@ -52,30 +59,27 @@ jobs: git checkout -B beta HEAD git push origin beta --force - - name: devbox installer + - name: Install devbox uses: jetify-com/devbox-install-action@v0.14.0 - with: - project-path: shells/devbox-fast.json - enable-cache: 'false' - name: Release (dry-run) if: inputs.type == 'dry-run' - run: devbox run --config=shells/devbox-fast.json release-dry-run + run: devbox run release-dry-run env: GH_TOKEN: ${{ github.token }} - name: Release (beta) if: inputs.type == 'beta' - run: devbox run -e GITHUB_REF=refs/heads/beta --config=shells/devbox-fast.json release + run: devbox run -e GITHUB_REF=refs/heads/beta release env: GH_TOKEN: ${{ github.token }} - name: Release (production) if: inputs.type == 'production' - run: devbox run --config=shells/devbox-fast.json release + run: devbox run release env: GH_TOKEN: ${{ github.token }} - name: Update Apps if: inputs.type == 'production' - run: devbox run --config=shells/devbox-fast.json update-apps + run: devbox run update-apps diff --git a/.husky/pre-commit b/.husky/pre-commit index a1828f9ab..921e95cb1 100755 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -1,4 +1,4 @@ #!/usr/bin/env sh . "$(dirname -- "$0")/_/husky.sh" -yarn lint && yarn typescript && yarn test +yarn lint && yarn typecheck && yarn test diff --git a/devbox.json b/devbox.json index 6dd289314..68104f98b 100644 --- a/devbox.json +++ b/devbox.json @@ -5,103 +5,42 @@ "version": "latest", "platforms": ["x86_64-darwin", "aarch64-darwin"] }, + "nodejs": "22", "yarn-berry": "latest", + "jq": "latest", "treefmt": "latest", "nixfmt": "latest", - "shfmt": "latest", - "jdk17": "latest", - "gradle": "latest", - "jq": "latest", - "netcat": "latest", - "path:./nix#android-sdk": "" + "shfmt": "latest" }, "shell": { "init_hook": [ - "echo 'Welcome to analytics-react-native devbox!' > /dev/null", - ". $DEVBOX_PROJECT_ROOT/scripts/shared/common.sh", - "if [ \"$(uname -s)\" = \"Darwin\" ]; then . $DEVBOX_PROJECT_ROOT/scripts/ios/env.sh; fi", - ". $DEVBOX_PROJECT_ROOT/scripts/android/env.sh", - "echo 'Android SDK env configured (details: wiki/devbox.md#devbox-android).'" + "export PROJECT_ROOT=\"$(git rev-parse --show-toplevel 2>/dev/null || echo $DEVBOX_PROJECT_ROOT)\"", + "export PATH=\"$PROJECT_ROOT/node_modules/.bin:$PATH\"", + "if [ ! -d \"$PROJECT_ROOT/node_modules\" ]; then echo 'Running yarn install...'; yarn install; fi", + "if [ ! -f \"$PROJECT_ROOT/packages/core/src/info.ts\" ]; then yarn core prebuild; fi", + "if [ ! -d \"$PROJECT_ROOT/.husky/_\" ]; then yarn husky install; fi" ], "scripts": { - "clean": [ - "rm -rf $DEVBOX_PROJECT_ROOT/examples/E2E/ios/Podfile.lock", - "rm -rf $DEVBOX_PROJECT_ROOT/examples/E2E/ios/Pods", - "cd $DEVBOX_PROJECT_DIR/examples/E2E/android && gradle clean", - "yarn cache clean", - "find $DEVBOX_PROJECT_DIR -type d -name node_modules -exec rmdir {} \\;" - ], - "build": ["bash $SCRIPTS_DIR/build.sh"], - "format": ["treefmt"], - "lint": ["treefmt --fail-on-change"], - "test-android": ["bash $SCRIPTS_DIR/android/test.sh"], - "test-ios": ["bash $SCRIPTS_DIR/ios/test.sh"], - "act-ci": [ - "bash $SCRIPTS_DIR/act-ci.sh --platform ubuntu-latest=ghcr.io/catthehacker/ubuntu:act-24.04" - ], - "setup-android": ["bash $SCRIPTS_DIR/android/setup.sh"], - "setup-ios": ["bash $SCRIPTS_DIR/ios/setup.sh"], - "start-emulator": ["bash $SCRIPTS_DIR/android/manager.sh start"], - "start-ios": ["bash $SCRIPTS_DIR/ios/manager.sh start"], - "start-android-minsdk": ["bash $SCRIPTS_DIR/android/manager.sh start"], - "start-android-latest": [ - "AVD_FLAVOR=latest bash $SCRIPTS_DIR/android/manager.sh start" - ], - "start-android": ["bash $SCRIPTS_DIR/android/manager.sh start"], + "ci:install": ["yarn install --immutable"], + "ci:commitlint": ["bash -c 'echo \"$PR_TITLE\" | yarn commitlint'"], + "build": ["yarn build"], + "test": ["yarn test"], + "typecheck": ["yarn typecheck"], + "lint": ["yarn lint"], + "format": ["yarn format"], + "format-check": ["yarn format:check"], + "clean": ["yarn clean"], + "release": ["yarn install --immutable", "yarn build", "yarn release"], + "release-dry-run": [ + "yarn install --immutable", + "yarn build", + "yarn multi-semantic-release --dry-run" + ], + "sync-versions": ["bash $PROJECT_ROOT/scripts/sync-versions.sh"], "update-apps": [ "yarn install --no-immutable", - "yarn e2e install --no-immutable", "yarn example install --no-immutable" - ], - "update-shells": [ - "devbox update", - "devbox update --config=shells/devbox-fast.json", - "devbox update --config=shells/devbox-android.json", - "devbox update --config=shells/devbox-ios.json" - ], - "reset-android": [ - "rm -rf ~/.android/avd", - "rm -f ~/.android/adbkey*", - "echo \"AVDs and adb keys removed. Recreate via devbox run start-android* as needed.\"" - ], - "reset-ios": [ - "xcrun simctl shutdown all || true", - "xcrun simctl erase all || true", - "xcrun simctl delete all || true", - "xcrun simctl delete unavailable || true", - "killall -9 com.apple.CoreSimulatorService 2>/dev/null || true", - "echo \"Simulators reset via simctl. Recreate via devbox run start-ios.\"" - ], - "stop-android": [ - "if command -v adb >/dev/null 2>&1; then", - " devices=$(adb devices -l 2>/dev/null | tail -n +2 | awk '{print $1}' | tr '\\n' ' ');", - " if [[ -n \"$devices\" ]]; then", - " echo \"Stopping Android emulators: $devices\";", - " for d in $devices; do adb -s \"$d\" emu kill >/dev/null 2>&1 || true; done;", - " else", - " echo \"No Android emulators detected via adb.\";", - " fi;", - "else", - " echo \"adb not found; skipping Android emulator shutdown.\";", - "fi", - "pkill -f \"emulator@\" >/dev/null 2>&1 || true", - "echo \"Android emulators stopped (if any were running).\"" - ], - "stop-ios": [ - "if command -v xcrun >/dev/null 2>&1 && xcrun -f simctl >/dev/null 2>&1; then", - " if xcrun simctl list devices booted | grep -q \"Booted\"; then", - " echo \"Shutting down booted iOS simulators...\";", - " xcrun simctl shutdown all >/dev/null 2>&1 || true;", - " else", - " echo \"No booted iOS simulators detected.\";", - " fi;", - "else", - " echo \"simctl not available; skipping iOS shutdown.\";", - "fi", - "echo \"iOS simulators shutdown (if any were running).\"" - ], - "stop": ["devbox run stop-android", "devbox run stop-ios"], - "test": ["devbox run test-android", "devbox run test-ios"] + ] } } } diff --git a/nix/flake.lock b/nix/flake.lock deleted file mode 100644 index d1f4e1080..000000000 --- a/nix/flake.lock +++ /dev/null @@ -1,27 +0,0 @@ -{ - "nodes": { - "nixpkgs": { - "locked": { - "lastModified": 1769527094, - "narHash": "sha256-xV20Alb7ZGN7qujnsi5lG1NckSUmpIb05H2Xar73TDc=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "afce96367b2e37fc29afb5543573cd49db3357b7", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixpkgs-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, - "root": { - "inputs": { - "nixpkgs": "nixpkgs" - } - } - }, - "root": "root", - "version": 7 -} diff --git a/nix/flake.nix b/nix/flake.nix deleted file mode 100644 index 06ff87380..000000000 --- a/nix/flake.nix +++ /dev/null @@ -1,74 +0,0 @@ -{ - description = "Slim Android SDK tools for Devbox via flakes"; - - inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; - - outputs = - { self, nixpkgs }: - let - systems = [ - "x86_64-linux" - "aarch64-linux" - "x86_64-darwin" - "aarch64-darwin" - ]; - - versionData = builtins.fromJSON (builtins.readFile ./platform-versions.json); - getVar = - name: default: - if builtins.hasAttr name versionData then toString (builtins.getAttr name versionData) else default; - - androidSdkConfig = { - platformVersions = [ - (getVar "PLATFORM_ANDROID_MIN_API" "21") - (getVar "PLATFORM_ANDROID_MAX_API" "33") - ]; - buildToolsVersion = getVar "PLATFORM_ANDROID_BUILD_TOOLS_VERSION" "30.0.3"; - cmdLineToolsVersion = getVar "PLATFORM_ANDROID_CMDLINE_TOOLS_VERSION" "19.0"; - systemImageTypes = [ (getVar "PLATFORM_ANDROID_SYSTEM_IMAGE_TAG" "google_apis") ]; - }; - - 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" ]; - - androidPkgs = pkgs.androidenv.composeAndroidPackages { - # Keep API 21 images for the AVD and add API 33 for React Native builds. - platformVersions = androidSdkConfig.platformVersions; - buildToolsVersions = [ androidSdkConfig.buildToolsVersion ]; - cmdLineToolsVersion = androidSdkConfig.cmdLineToolsVersion; - includeEmulator = true; - includeSystemImages = true; - includeNDK = false; - abiVersions = abiVersions; - systemImageTypes = androidSdkConfig.systemImageTypes; - }; - in - { - android-sdk = androidPkgs.androidsdk; - default = androidPkgs.androidsdk; - } - ); - - androidSdkConfig = androidSdkConfig; - }; -} diff --git a/nix/platform-versions.json b/nix/platform-versions.json deleted file mode 100644 index 506669900..000000000 --- a/nix/platform-versions.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "PLATFORM_ANDROID_MIN_API": "21", - "PLATFORM_ANDROID_MAX_API": "33", - "PLATFORM_ANDROID_BUILD_TOOLS_VERSION": "30.0.3", - "PLATFORM_ANDROID_CMDLINE_TOOLS_VERSION": "19.0", - "PLATFORM_ANDROID_SYSTEM_IMAGE_TAG": "google_apis", - "PLATFORM_ANDROID_MIN_DEVICE": "pixel", - "PLATFORM_ANDROID_MAX_DEVICE": "medium_phone", - "PLATFORM_IOS_MIN_RUNTIME": "15.0", - "PLATFORM_IOS_MAX_RUNTIME": "", - "PLATFORM_IOS_MIN_DEVICE": "iPhone 13", - "PLATFORM_IOS_MAX_DEVICE": "iPhone 17" -} diff --git a/package.json b/package.json index 30af344e2..a512acf99 100644 --- a/package.json +++ b/package.json @@ -8,20 +8,16 @@ "packages/plugins/*" ], "scripts": { - "bootstrap": "yarn install && yarn example install && yarn example pods && yarn e2e install && yarn e2e pods && husky install", - "bootstrap:ci": "yarn install && yarn e2e install && yarn e2e pods && husky install", "core": "yarn workspace @segment/analytics-react-native", "sovran": "yarn workspace @segment/sovran-react-native", "example": "yarn --cwd examples/AnalyticsReactNativeExample", - "e2e": "yarn --cwd examples/E2E", "build": "yarn workspaces foreach -A -p --topological-dev run build", - "testAll": "yarn workspaces foreach -A -p run test --passWithNoTests", - "clean": "yarn workspaces foreach -A -p run clean", - "typescript": "tsc --noEmit --composite false", "test": "jest", + "typecheck": "tsc --noEmit --composite false", "lint": "eslint .", "format": "treefmt --clear-cache", "format:check": "treefmt --clear-cache --fail-on-change", + "clean": "yarn workspaces foreach -A -p run clean", "release": "yarn multi-semantic-release" }, "devDependencies": { diff --git a/packages/core/src/__tests__/api.test.ts b/packages/core/src/__tests__/api.test.ts index 86a378752..f968a3201 100644 --- a/packages/core/src/__tests__/api.test.ts +++ b/packages/core/src/__tests__/api.test.ts @@ -64,6 +64,7 @@ describe('#sendEvents', () => { expect(fetch).toHaveBeenCalledWith(toUrl, { method: 'POST', + keepalive: true, body: JSON.stringify({ batch: [event], sentAt: '2001-01-01T00:00:00.000Z', diff --git a/scripts/act-ci.sh b/scripts/act-ci.sh deleted file mode 100755 index 60c7f85a9..000000000 --- a/scripts/act-ci.sh +++ /dev/null @@ -1,46 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -# Run GitHub Actions workflows locally via act. -# Usage: scripts/act-ci.sh [--job JOB] [--platform ubuntu-latest=IMAGE] - -JOB="" -PLATFORMS=() - -host_arch="$(uname -m)" -if [[ $host_arch == "arm64" || $host_arch == "aarch64" ]]; then - PLATFORMS+=("ubuntu-24.04-arm=ghcr.io/catthehacker/ubuntu:act-24.04") -else - PLATFORMS+=("ubuntu-24.04=ghcr.io/catthehacker/ubuntu:act-24.04") -fi -PLATFORMS+=("ubuntu-latest=ghcr.io/catthehacker/ubuntu:act-24.04") - -while [[ $# -gt 0 ]]; do - case "$1" in - -j | --job) - JOB="$2" - shift 2 - ;; - -p | --platform) - PLATFORMS+=("$2") - shift 2 - ;; - *) - echo "Unknown option: $1" >&2 - exit 1 - ;; - esac -done - -CMD=(act) -CMD+=(--pull=false) -for platform in "${PLATFORMS[@]}"; do - CMD+=(--platform "$platform") -done -CMD+=(--input ACT=true) -if [[ -n $JOB ]]; then - CMD+=(--job "$JOB") -fi - -printf 'Running: %s\n' "${CMD[*]}" -exec "${CMD[@]}" diff --git a/scripts/android/env.sh b/scripts/android/env.sh deleted file mode 100755 index 0ffe24379..000000000 --- a/scripts/android/env.sh +++ /dev/null @@ -1,82 +0,0 @@ -#!/usr/bin/env bash -# Sets ANDROID_SDK_ROOT/ANDROID_HOME and PATH to the flake-pinned SDK if not already set. - -# Load shared platform versions if present. -script_path="${BASH_SOURCE[0]:-$0}" -script_dir="$(cd "$(dirname "$script_path")" && pwd)" -# shellcheck disable=SC1090 -. "$script_dir/../shared/common.sh" -load_platform_versions "$script_dir" - -if [ -z "${ANDROID_MIN_API:-}" ] && [ -n "${PLATFORM_ANDROID_MIN_API:-}" ]; then - ANDROID_MIN_API="$PLATFORM_ANDROID_MIN_API" -fi -if [ -z "${ANDROID_MAX_API:-}" ] && [ -n "${PLATFORM_ANDROID_MAX_API:-}" ]; then - ANDROID_MAX_API="$PLATFORM_ANDROID_MAX_API" -fi -if [ -z "${ANDROID_BUILD_TOOLS_VERSION:-}" ] && [ -n "${PLATFORM_ANDROID_BUILD_TOOLS_VERSION:-}" ]; then - ANDROID_BUILD_TOOLS_VERSION="$PLATFORM_ANDROID_BUILD_TOOLS_VERSION" -fi -if [ -z "${ANDROID_CMDLINE_TOOLS_VERSION:-}" ] && [ -n "${PLATFORM_ANDROID_CMDLINE_TOOLS_VERSION:-}" ]; then - ANDROID_CMDLINE_TOOLS_VERSION="$PLATFORM_ANDROID_CMDLINE_TOOLS_VERSION" -fi -if [ -z "${ANDROID_SYSTEM_IMAGE_TAG:-}" ] && [ -n "${PLATFORM_ANDROID_SYSTEM_IMAGE_TAG:-}" ]; then - ANDROID_SYSTEM_IMAGE_TAG="$PLATFORM_ANDROID_SYSTEM_IMAGE_TAG" -fi - -# Only act if neither var is already provided. -if [ -z "${ANDROID_SDK_ROOT:-}" ] && [ -z "${ANDROID_HOME:-}" ]; then - DEVBOX_SDK_OUT=$( - nix --extra-experimental-features 'nix-command flakes' \ - eval --raw "path:${DEVBOX_PROJECT_ROOT}/nix#android-sdk.outPath" 2>/dev/null || true - ) - if [ -n "${DEVBOX_SDK_OUT:-}" ] && [ -d "$DEVBOX_SDK_OUT/libexec/android-sdk" ]; then - ANDROID_SDK_ROOT="$DEVBOX_SDK_OUT/libexec/android-sdk" - ANDROID_HOME="$ANDROID_SDK_ROOT" - fi -fi - -if [ -z "${ANDROID_SDK_ROOT:-}" ] && [ -n "${ANDROID_HOME:-}" ]; then - ANDROID_SDK_ROOT="$ANDROID_HOME" -fi - -if [ -n "${ANDROID_SDK_ROOT:-}" ] && [ -z "${ANDROID_HOME:-}" ]; then - ANDROID_HOME="$ANDROID_SDK_ROOT" -fi - -export ANDROID_SDK_ROOT ANDROID_HOME -export ANDROID_BUILD_TOOLS_VERSION - -if [ -n "${ANDROID_SDK_ROOT:-}" ]; then - # Prefer cmdline-tools;latest, or fall back to the highest numbered cmdline-tools folder. - cmdline_tools_bin="" - if [ -d "$ANDROID_SDK_ROOT/cmdline-tools/latest/bin" ]; then - cmdline_tools_bin="$ANDROID_SDK_ROOT/cmdline-tools/latest/bin" - else - cmdline_tools_dir=$(find "$ANDROID_SDK_ROOT/cmdline-tools" -maxdepth 1 -mindepth 1 -type d -not -name latest 2>/dev/null | sort -V | tail -n 1) - if [ -n "${cmdline_tools_dir:-}" ] && [ -d "$cmdline_tools_dir/bin" ]; then - cmdline_tools_bin="$cmdline_tools_dir/bin" - fi - fi - - new_path="$ANDROID_SDK_ROOT/emulator:$ANDROID_SDK_ROOT/platform-tools" - - if [ -n "${cmdline_tools_bin:-}" ]; then - new_path="$new_path:$cmdline_tools_bin" - fi - - new_path="$new_path:$ANDROID_SDK_ROOT/tools/bin:$PATH" - PATH="$new_path" - export PATH - echo "Using Android SDK: $ANDROID_SDK_ROOT" - case "$ANDROID_SDK_ROOT" in - /nix/store/*) - echo "Source: Nix flake (reproducible, pinned). To use your local SDK instead, set ANDROID_HOME/ANDROID_SDK_ROOT before starting devbox shell." - ;; - *) - echo "Source: User/local SDK. To use the pinned Nix SDK, unset ANDROID_HOME/ANDROID_SDK_ROOT before starting devbox shell." - ;; - esac -else - echo "Android SDK not set; using system PATH" -fi diff --git a/scripts/android/manager.sh b/scripts/android/manager.sh deleted file mode 100755 index a1275adb6..000000000 --- a/scripts/android/manager.sh +++ /dev/null @@ -1,57 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -action="${1:-}" -shift || true - -source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/env.sh" - -start_android() { - local flavor="${AVD_FLAVOR:-latest}" headless="${EMU_HEADLESS:-}" port="${EMU_PORT:-5554}" - local avd="${DETOX_AVD:-}" - - if [[ -z $avd ]]; then - if [[ $flavor == "latest" ]]; then - local host_arch - host_arch="$(uname -m)" - avd="medium_phone_API33_$([[ $host_arch == "arm64" || $host_arch == "aarch64" ]] && echo arm64_v8a || echo x86_64)" - else - avd="pixel_API21_$(uname -m | grep -qi arm && echo arm64_v8a || echo x86_64)" - fi - fi - - devbox run setup-android - local target_serial="emulator-${port}" - if command -v adb >/dev/null 2>&1; then - adb devices | awk 'NR>1 && $2=="offline" {print $1}' | while read -r d; do adb -s "$d" emu kill >/dev/null 2>&1 || true; done - fi - echo "Starting Android emulator: ${avd} (flavor ${flavor}, port ${port}, headless=${headless:-0})" - emulator -avd "${avd}" ${headless:+-no-window} -port "${port}" -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none -accel on -writable-system -no-snapshot-save & - adb -s "${target_serial}" wait-for-device - local boot_completed="" - until [ "$boot_completed" = "1" ]; do - boot_completed=$(adb -s "${target_serial}" shell getprop sys.boot_completed 2>/dev/null | tr -d "\r") - sleep 5 - done - adb -s "${target_serial}" shell settings put global window_animation_scale 0 - adb -s "${target_serial}" shell settings put global transition_animation_scale 0 - adb -s "${target_serial}" shell settings put global animator_duration_scale 0 -} - -stop_android() { - devbox run stop-android -} - -reset_android() { - devbox run reset-android -} - -case "$action" in -start) start_android ;; -stop) stop_android ;; -reset) reset_android ;; -*) - echo "Usage: manager.sh {start|stop|reset}" >&2 - exit 1 - ;; -esac diff --git a/scripts/android/setup.sh b/scripts/android/setup.sh deleted file mode 100755 index ffc0b7cef..000000000 --- a/scripts/android/setup.sh +++ /dev/null @@ -1,150 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -# Creates AVDs using the Android SDK provided by devbox/flake (system images, emulator, NDK already installed). -# Run inside a devbox shell so SDK tools are available. -# Configurable via env: -# AVD_API (default 21) -# AVD_DEVICE (default "pixel") -# AVD_TAG (default "google_apis") -# AVD_ABI (preferred ABI; optional) -# AVD_NAME (override final AVD name; otherwise computed) -# Secondary AVD (created in addition to the primary): -# AVD_SECONDARY_API (default 33) -# AVD_SECONDARY_DEVICE (default "medium_phone") -# AVD_SECONDARY_TAG (default "google_apis") -# AVD_SECONDARY_ABI (preferred ABI; optional) -# AVD_SECONDARY_NAME (override final name) - -script_dir="$(cd "$(dirname "$0")" && pwd)" -# shellcheck disable=SC1090 -. "$script_dir/../shared/common.sh" -load_platform_versions "$script_dir" - -detect_sdk_root() { - if [[ -n ${ANDROID_SDK_ROOT:-} ]]; then - echo "$ANDROID_SDK_ROOT" - return - fi - - local sm - sm="$(command -v sdkmanager 2>/dev/null || true)" - if [[ -z $sm ]]; then - return - fi - sm="$(readlink -f "$sm")" - local candidates=( - "$(dirname "$sm")/.." - "$(dirname "$sm")/../share/android-sdk" - "$(dirname "$sm")/../libexec/android-sdk" - "$(dirname "$sm")/../.." - ) - for c in "${candidates[@]}"; do - if [[ -d "$c/platform-tools" || -d "$c/platforms" || -d "$c/system-images" ]]; then - echo "$c" - return - fi - done -} - -avd_exists() { - local name="$1" - avdmanager list avd | grep -q "Name: ${name}" -} - -pick_image() { - local api="$1" tag="$2" preferred_abi="$3" - local host_arch - host_arch="$(uname -m)" - - local candidates=() - if [[ -n ${preferred_abi:-} ]]; then - candidates=("$preferred_abi") - else - case "$host_arch" in - arm64 | aarch64) candidates=("arm64-v8a" "x86_64" "x86") ;; - *) candidates=("x86_64" "x86" "arm64-v8a") ;; - esac - fi - - for abi in "${candidates[@]}"; do - local image="system-images;android-${api};${tag};${abi}" - local path="${ANDROID_SDK_ROOT}/system-images/android-${api}/${tag}/${abi}" - if [[ -d $path ]]; then - echo "$image" - return 0 - fi - done - - return 1 -} - -create_avd() { - local name="$1" device="$2" image="$3" - local abi="${image##*;}" - - if avd_exists "$name"; then - echo "AVD ${name} already exists." - return 0 - fi - - echo "Creating AVD ${name} with ${image}..." - avdmanager create avd --force --name "$name" --package "$image" --device "$device" --abi "$abi" --sdcard 512M -} - -main() { - local detected_sdk_root - detected_sdk_root="$(detect_sdk_root)" - - if [[ -z ${ANDROID_SDK_ROOT:-} && -n $detected_sdk_root ]]; then - export ANDROID_SDK_ROOT="$detected_sdk_root" - fi - - if [[ -z ${ANDROID_SDK_ROOT:-} && -z ${ANDROID_HOME:-} ]]; then - echo "ANDROID_SDK_ROOT/ANDROID_HOME must be set. In a devbox shell, the flake-provided SDK should supply sdkmanager in PATH; if not, set ANDROID_SDK_ROOT to the flake's android-sdk path." >&2 - exit 1 - fi - - export ANDROID_HOME="${ANDROID_HOME:-$ANDROID_SDK_ROOT}" - - require_tool avdmanager - require_tool emulator - - local primary_api="${AVD_API:-${ANDROID_MIN_API:-${PLATFORM_ANDROID_MIN_API:-21}}}" - local primary_tag="${AVD_TAG:-${ANDROID_SYSTEM_IMAGE_TAG:-${PLATFORM_ANDROID_SYSTEM_IMAGE_TAG:-google_apis}}}" - local primary_device="${AVD_DEVICE:-pixel}" - local primary_preferred_abi="${AVD_ABI:-}" - - local secondary_api="${AVD_SECONDARY_API:-${ANDROID_MAX_API:-${PLATFORM_ANDROID_MAX_API:-33}}}" - local secondary_tag="${AVD_SECONDARY_TAG:-${ANDROID_SYSTEM_IMAGE_TAG:-${PLATFORM_ANDROID_SYSTEM_IMAGE_TAG:-google_apis}}}" - local secondary_device="${AVD_SECONDARY_DEVICE:-medium_phone}" - local secondary_preferred_abi="${AVD_SECONDARY_ABI:-}" - - local targets=( - "$primary_api|$primary_tag|$primary_device|$primary_preferred_abi|${AVD_NAME:-}" - "$secondary_api|$secondary_tag|$secondary_device|$secondary_preferred_abi|${AVD_SECONDARY_NAME:-}" - ) - - for target in "${targets[@]}"; do - IFS="|" read -r api tag device preferred_abi name_override <<<"$target" - - local api_image - if ! api_image="$(pick_image "$api" "$tag" "$preferred_abi")"; then - echo "Expected API ${api} system image (${tag}; preferred ABI ${preferred_abi:-auto}) not found under ${ANDROID_SDK_ROOT}/system-images/android-${api}." >&2 - echo "Re-enter the devbox shell (flake should provide images) or rebuild Devbox to fetch them." >&2 - continue - fi - - local abi="${api_image##*;}" - local avd_name="${name_override:-$(printf '%s_API%s_%s' "$device" "$api" "${abi//-/_}")}" - - create_avd "$avd_name" "$device" "$api_image" - if avd_exists "$avd_name"; then - echo "AVD ready: ${avd_name} (${api_image})" - fi - done - - echo "AVDs ready. Boot with: emulator -avd --netdelay none --netspeed full" -} - -main "$@" diff --git a/scripts/android/test.sh b/scripts/android/test.sh deleted file mode 100755 index 342a187a0..000000000 --- a/scripts/android/test.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -script_dir="$(cd "$(dirname "$0")" && pwd)" -# shellcheck disable=SC1090 -. "$script_dir/../shared/common.sh" - -bash "$SCRIPTS_DIR/android/setup.sh" -yarn install -yarn e2e install -yarn build -yarn e2e build:android -yarn e2e test:android diff --git a/scripts/build.sh b/scripts/build.sh deleted file mode 100755 index d22efb734..000000000 --- a/scripts/build.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -script_dir="$(cd "$(dirname "$0")" && pwd)" -# shellcheck disable=SC1090 -. "$script_dir/shared/common.sh" - -yarn install --immutable -yarn build -yarn lint diff --git a/scripts/ios/env.sh b/scripts/ios/env.sh deleted file mode 100755 index c5ee09930..000000000 --- a/scripts/ios/env.sh +++ /dev/null @@ -1,55 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -devbox_omit_nix_env() { - if [ "${DEVBOX_OMIT_NIX_ENV_APPLIED:-}" = "1" ]; then - return 0 - fi - - export DEVBOX_OMIT_NIX_ENV_APPLIED=1 - - dump_env() { - echo "devbox omit-nix-env $1" - echo " PATH=$PATH" - echo " CC=${CC:-}" - echo " CXX=${CXX:-}" - echo " LD=${LD:-}" - echo " CPP=${CPP:-}" - echo " AR=${AR:-}" - echo " SDKROOT=${SDKROOT:-}" - echo " DEVELOPER_DIR=${DEVELOPER_DIR:-}" - } - - dump_env "before" - - eval "$(devbox shellenv --init-hook --install --no-refresh-alias --omit-nix-env=true)" - - if [ "$(uname -s)" = "Darwin" ]; then - PATH="$(printf '%s' "$PATH" | tr ':' '\n' | awk '!/^\/nix\/store\//{print}' | paste -sd ':' -)" - - for var in CC CXX LD CPP AR AS NM RANLIB STRIP OBJC OBJCXX SDKROOT DEVELOPER_DIR; do - value="${!var:-}" - if [ -n "$value" ] && [ "${value#/nix/store/}" != "$value" ]; then - unset "$var" - fi - done - - if [ -x /usr/bin/clang ]; then - export CC=/usr/bin/clang - export CXX=/usr/bin/clang++ - fi - - if command -v xcode-select >/dev/null 2>&1; then - dev_dir="$(xcode-select -p 2>/dev/null || true)" - if [ -n "$dev_dir" ]; then - export DEVELOPER_DIR="$dev_dir" - fi - fi - - unset SDKROOT - fi - - dump_env "after" -} - -devbox_omit_nix_env diff --git a/scripts/ios/manager.sh b/scripts/ios/manager.sh deleted file mode 100755 index 52359735f..000000000 --- a/scripts/ios/manager.sh +++ /dev/null @@ -1,51 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -script_dir="$(cd "$(dirname "$0")" && pwd)" -# shellcheck disable=SC1090 -. "$script_dir/../shared/common.sh" -load_platform_versions "$script_dir" - -action="${1:-}" -shift || true - -start_ios() { - local flavor="${IOS_FLAVOR:-latest}" - if [[ $flavor == "minsdk" ]]; then - export IOS_DEVICE_NAMES="${IOS_MIN_DEVICE:-${PLATFORM_IOS_MIN_DEVICE:-iPhone 13}}" - export IOS_RUNTIME="${IOS_MIN_RUNTIME:-${PLATFORM_IOS_MIN_RUNTIME:-15.0}}" - export DETOX_IOS_DEVICE="${DETOX_IOS_DEVICE:-${IOS_MIN_DEVICE:-${PLATFORM_IOS_MIN_DEVICE:-iPhone 13}}}" - else - export IOS_DEVICE_NAMES="${IOS_DEVICE_NAMES:-${IOS_MIN_DEVICE:-${PLATFORM_IOS_MIN_DEVICE:-iPhone 13}},${IOS_MAX_DEVICE:-${PLATFORM_IOS_MAX_DEVICE:-iPhone 17}}}" - export IOS_RUNTIME="${IOS_RUNTIME:-${IOS_MAX_RUNTIME:-${PLATFORM_IOS_MAX_RUNTIME:-}}}" - export DETOX_IOS_DEVICE="${DETOX_IOS_DEVICE:-iPhone 17}" - fi - - devbox run setup-ios - local sim_device="${DETOX_IOS_DEVICE}" - if ! xcrun simctl list devices | grep -q "${sim_device}"; then - echo "Simulator ${sim_device} not found; ensure setup-ios created it." >&2 - exit 1 - fi - echo "Starting iOS simulator: ${sim_device} (runtime ${IOS_RUNTIME})" - xcrun simctl boot "$sim_device" || true - open -a Simulator -} - -stop_ios() { - devbox run stop-ios -} - -reset_ios() { - devbox run reset-ios -} - -case "$action" in -start) start_ios ;; -stop) stop_ios ;; -reset) reset_ios ;; -*) - echo "Usage: manager.sh {start|stop|reset}" >&2 - exit 1 - ;; -esac diff --git a/scripts/ios/setup.sh b/scripts/ios/setup.sh deleted file mode 100755 index de7827cad..000000000 --- a/scripts/ios/setup.sh +++ /dev/null @@ -1,69 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -script_dir="$(cd "$(dirname "$0")" && pwd)" -# shellcheck disable=SC1090 -. "$script_dir/../shared/common.sh" -# shellcheck disable=SC1090 -. "$script_dir/simctl.sh" -load_platform_versions "$script_dir" - -# Creates local iOS simulators for common targets. Requires Xcode command-line tools and jq. -# Env overrides: -# IOS_DEVICE_NAMES="iPhone 15,iPhone 17" (comma-separated) -# IOS_RUNTIME="26.1" (preferred runtime prefix; falls back to latest available) -# IOS_DOWNLOAD_RUNTIME=1 to attempt xcodebuild -downloadPlatform iOS when the preferred runtime is missing -# IOS_DEVELOPER_DIR="/Applications/Xcode.app/Contents/Developer" to override the Xcode path; defaults to xcode-select -p or the standard Xcode.app if found - -ensure_developer_dir() { - local desired="${IOS_DEVELOPER_DIR:-}" - if [[ -z $desired ]]; then - if xcode-select -p >/dev/null 2>&1; then - desired="$(xcode-select -p)" - elif [[ -d /Applications/Xcode.app/Contents/Developer ]]; then - desired="/Applications/Xcode.app/Contents/Developer" - fi - fi - - if [[ -n $desired && -d $desired ]]; then - export DEVELOPER_DIR="$desired" - export PATH="$DEVELOPER_DIR/usr/bin:$PATH" - return 0 - fi - - echo "Xcode developer directory not found. Install Xcode/CLI tools or set IOS_DEVELOPER_DIR to an Xcode path (e.g., /Applications/Xcode.app/Contents/Developer)." >&2 - exit 1 -} - -ensure_developer_dir - -require_tool xcrun "Missing required tool: xcrun. Install Xcode CLI tools before running (xcode-select --install or Xcode.app + xcode-select -s)." -require_tool jq - -ensure_simctl() { - if xcrun -f simctl >/dev/null 2>&1; then - return 0 - fi - cat >&2 <<'EOF' -Missing simctl. -- The standalone Command Line Tools do NOT include simctl; you need full Xcode. -- Install/locate Xcode.app, then select it: - sudo xcode-select -s /Applications/Xcode.app/Contents/Developer -- You can also set IOS_DEVELOPER_DIR to your Xcode path for this script. -EOF - exit 1 -} - -ensure_simctl - -main() { - ensure_core_sim_service || return 1 - IFS=',' read -r -a devices <<<"${IOS_DEVICE_NAMES:-${IOS_MIN_DEVICE:-${PLATFORM_IOS_MIN_DEVICE:-iPhone 13}},${IOS_MAX_DEVICE:-${PLATFORM_IOS_MAX_DEVICE:-iPhone 17}}}" - local runtime="${IOS_RUNTIME:-${IOS_MIN_RUNTIME:-${PLATFORM_IOS_MIN_RUNTIME:-15.0}}}" - for device in "${devices[@]}"; do - ensure_device "$(echo "$device" | xargs)" "$runtime" - done - echo "Done. Launch via Xcode > Devices or 'xcrun simctl boot \"\"' then 'open -a Simulator'." -} - -main "$@" diff --git a/scripts/ios/simctl.sh b/scripts/ios/simctl.sh deleted file mode 100644 index ddfe7bf27..000000000 --- a/scripts/ios/simctl.sh +++ /dev/null @@ -1,127 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -ensure_core_sim_service() { - local output status - output="$(xcrun simctl list devices -j 2>&1)" || status=$? - if [[ -n ${status:-} ]]; then - echo "simctl failed while listing devices (status ${status}). CoreSimulatorService may be unhealthy." >&2 - echo "Try restarting it:" >&2 - echo " killall -9 com.apple.CoreSimulatorService 2>/dev/null || true" >&2 - echo " launchctl kickstart -k gui/$UID/com.apple.CoreSimulatorService" >&2 - echo "Then open Simulator once and rerun devbox run setup-ios." >&2 - echo "simctl error output:" >&2 - echo "$output" >&2 - return 1 - fi - - if echo "$output" | grep -q "CoreSimulatorService connection became invalid"; then - echo "CoreSimulatorService is not healthy. Try restarting it:" >&2 - echo " killall -9 com.apple.CoreSimulatorService 2>/dev/null || true" >&2 - echo " launchctl kickstart -k gui/$UID/com.apple.CoreSimulatorService" >&2 - echo "Then open Simulator once and rerun devbox run setup-ios." >&2 - echo "simctl error output:" >&2 - echo "$output" >&2 - return 1 - fi -} - -pick_runtime() { - local preferred="$1" - local json choice - json="$(xcrun simctl list runtimes -j)" - choice="$(echo "$json" | jq -r --arg v "$preferred" '.runtimes[] | select(.isAvailable and (.name|startswith("iOS \($v)"))) | "\(.identifier)|\(.name)"' | head -n1)" - if [[ -z $choice || $choice == "null" ]]; then - choice="$(echo "$json" | jq -r '.runtimes[] | select(.isAvailable and (.name|startswith("iOS "))) | "\(.version)|\(.identifier)|\(.name)"' | sort -Vr | head -n1 | cut -d"|" -f2-)" - fi - [[ -n $choice && $choice != "null" ]] || return 1 - echo "$choice" -} - -resolve_runtime() { - local preferred="$1" - if choice=$(pick_runtime "$preferred"); then - echo "$choice" - return 0 - fi - - if [[ ${IOS_DOWNLOAD_RUNTIME:-1} != "0" ]] && command -v xcodebuild >/dev/null 2>&1; then - echo "Preferred runtime iOS ${preferred} not found. Attempting to download via xcodebuild -downloadPlatform iOS..." >&2 - if xcodebuild -downloadPlatform iOS; then - if choice=$(pick_runtime "$preferred"); then - echo "$choice" - return 0 - fi - else - echo "xcodebuild -downloadPlatform iOS failed; continuing with available runtimes." >&2 - fi - fi - - pick_runtime "$preferred" -} - -existing_device_udid_any_runtime() { - local name="$1" - xcrun simctl list devices -j | jq -r --arg name "$name" '.devices[]?[]? | select(.name == $name) | .udid' | head -n1 -} - -device_data_dir_exists() { - local udid="${1:-}" - [[ -n $udid ]] || return 1 - local dir="$HOME/Library/Developer/CoreSimulator/Devices/$udid" - [[ -d $dir ]] -} - -devicetype_id_for_name() { - local name="$1" - xcrun simctl list devicetypes -j | jq -r --arg name "$name" '.devicetypes[] | select((.name|ascii_downcase) == ($name|ascii_downcase)) | .identifier' | head -n1 -} - -ensure_device() { - local base_name="$1" preferred_runtime="$2" - - # If a device with this name already exists anywhere, reuse it. - if - existing_udid=$(existing_device_udid_any_runtime "$base_name") - [[ -n ${existing_udid} ]] - then - if device_data_dir_exists "$existing_udid"; then - echo "Found existing ${base_name}: ${existing_udid}" - return 0 - fi - echo "Existing ${base_name} (${existing_udid}) is missing its data directory. Deleting stale simulator..." - xcrun simctl delete "$existing_udid" || true - fi - - local choice runtime_id runtime_name - if ! choice=$(resolve_runtime "$preferred_runtime"); then - echo "No available iOS simulator runtime found. Install one in Xcode (Settings > Platforms) and retry." >&2 - return 1 - fi - runtime_id="$(echo "$choice" | cut -d'|' -f1)" - runtime_name="$(echo "$choice" | cut -d'|' -f2)" - - local display_name="${base_name} (${runtime_name})" - - if ! device_type=$(devicetype_id_for_name "$base_name"); then - echo "Device type '${base_name}' is unavailable in this Xcode install. Skipping ${display_name}." >&2 - return 0 - fi - - # Also check for an existing device with the runtime-qualified display name. - if - existing_udid=$(existing_device_udid_any_runtime "$display_name") - [[ -n ${existing_udid} ]] - then - if device_data_dir_exists "$existing_udid"; then - echo "Found existing ${display_name}: ${existing_udid}" - return 0 - fi - echo "Existing ${display_name} (${existing_udid}) is missing its data directory. Deleting stale simulator..." - xcrun simctl delete "$existing_udid" || true - fi - - echo "Creating ${display_name}..." - xcrun simctl create "$display_name" "$device_type" "$runtime_id" - echo "Created ${display_name}" -} diff --git a/scripts/ios/test.sh b/scripts/ios/test.sh deleted file mode 100755 index 7bf5a4189..000000000 --- a/scripts/ios/test.sh +++ /dev/null @@ -1,25 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -script_dir="$(cd "$(dirname "$0")" && pwd)" -# shellcheck disable=SC1090 -. "$script_dir/../shared/common.sh" - -if [ "$(uname -s)" = "Darwin" ]; then - . "$SCRIPTS_DIR/ios/env.sh" -fi - -echo "iOS test env" -echo " PATH=$PATH" -echo " CC=${CC:-}" -echo " CXX=${CXX:-}" -echo " SDKROOT=${SDKROOT:-}" -echo " DEVELOPER_DIR=${DEVELOPER_DIR:-}" - -bash "$SCRIPTS_DIR/ios/setup.sh" -yarn install -yarn e2e install -yarn e2e pods -yarn build -yarn e2e build:ios -yarn e2e test:ios diff --git a/scripts/platform-versions.sh b/scripts/platform-versions.sh deleted file mode 100644 index 0713ce9cb..000000000 --- a/scripts/platform-versions.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/env sh -# Load shared platform version defaults from JSON for a single source of truth. - -script_dir="$(cd "$(dirname "$0")" && pwd)" -repo_root="$(cd "$script_dir/.." && pwd)" -versions_json="${PLATFORM_VERSIONS_JSON:-$repo_root/nix/platform-versions.json}" - -if [ -f "$versions_json" ] && command -v jq >/dev/null 2>&1; then - eval "$( - jq -r 'to_entries[] | "\(.key)=\(.value|@sh)"' "$versions_json" - )" -fi diff --git a/scripts/shared/common.sh b/scripts/shared/common.sh deleted file mode 100644 index a62edbf02..000000000 --- a/scripts/shared/common.sh +++ /dev/null @@ -1,54 +0,0 @@ -#!/usr/bin/env sh - -require_tool() { - tool="$1" - message="${2:-Missing required tool: $tool. Ensure devbox shell is active and required packages are installed.}" - if ! command -v "$tool" >/dev/null 2>&1; then - echo "$message" >&2 - exit 1 - fi -} - -ensure_project_root() { - if [ -n "${PROJECT_ROOT:-}" ]; then - return 0 - fi - - base_dir="${1:-}" - if [ -z "$base_dir" ]; then - base_dir="$PWD" - fi - - git_root="" - if command -v git >/dev/null 2>&1; then - git_root="$(git -C "$base_dir" rev-parse --show-toplevel 2>/dev/null || true)" - fi - - if [ -n "$git_root" ]; then - PROJECT_ROOT="$git_root" - elif [ -f "$base_dir/../shared/common.sh" ] && [ -f "$base_dir/../build.sh" ]; then - PROJECT_ROOT="$(cd "$base_dir/.." && pwd)" - elif [ -f "$base_dir/shared/common.sh" ] && [ -f "$base_dir/build.sh" ]; then - PROJECT_ROOT="$(cd "$base_dir" && pwd)" - fi - - if [ -n "${PROJECT_ROOT:-}" ]; then - export PROJECT_ROOT - fi -} - -load_platform_versions() { - base_dir="$1" - platform_versions="${base_dir%/}/../platform-versions.sh" - if [ -f "$platform_versions" ]; then - # shellcheck disable=SC1090 - . "$platform_versions" - fi -} - -ensure_project_root "${SCRIPT_DIR:-${script_dir:-${PWD}}}" - -if [ -z "${SCRIPTS_DIR:-}" ] && [ -n "${PROJECT_ROOT:-}" ]; then - SCRIPTS_DIR="$PROJECT_ROOT/scripts" - export SCRIPTS_DIR -fi diff --git a/scripts/sync-versions.sh b/scripts/sync-versions.sh index 51f911283..8dba3e19a 100755 --- a/scripts/sync-versions.sh +++ b/scripts/sync-versions.sh @@ -2,12 +2,23 @@ set -euo pipefail # Syncs package.json version fields with the latest published npm versions. -# Run via: devbox run sync-versions +# +# Usage: +# devbox run sync-versions # update version fields in place +# devbox run sync-versions-check # check only, fail if out of sync +# +# If the CI check fails, run `devbox run sync-versions` locally and commit. + +CHECK_ONLY=false +if [ "${1:-}" = "--check" ]; then + CHECK_ONLY=true +fi PROJECT_ROOT="${PROJECT_ROOT:-$(git rev-parse --show-toplevel)}" updated=0 skipped=0 +drift=0 for pkg_json in "$PROJECT_ROOT"/packages/*/package.json "$PROJECT_ROOT"/packages/plugins/*/package.json; do [ -f "$pkg_json" ] || continue @@ -32,12 +43,24 @@ for pkg_json in "$PROJECT_ROOT"/packages/*/package.json "$PROJECT_ROOT"/packages if [ "$current" = "$latest" ]; then echo " ok $name@$current" skipped=$((skipped + 1)) + elif [ "$CHECK_ONLY" = true ]; then + echo " drift $name $current (local) != $latest (npm)" + drift=$((drift + 1)) else - jq --arg v "$latest" '.version = $v' "$pkg_json" > "$pkg_json.tmp" && mv "$pkg_json.tmp" "$pkg_json" + jq --arg v "$latest" '.version = $v' "$pkg_json" >"$pkg_json.tmp" && mv "$pkg_json.tmp" "$pkg_json" echo " bump $name $current -> $latest" updated=$((updated + 1)) fi done echo "" -echo "Done: $updated updated, $skipped unchanged/skipped" +if [ "$CHECK_ONLY" = true ]; then + if [ "$drift" -gt 0 ]; then + echo "Error: $drift package(s) out of sync with npm." + echo "Run 'devbox run sync-versions' locally and commit the result." + exit 1 + fi + echo "All $skipped package(s) in sync with npm." +else + echo "Done: $updated updated, $skipped unchanged/skipped" +fi diff --git a/shells/devbox-android.json b/shells/devbox-android.json deleted file mode 100644 index a1be49c55..000000000 --- a/shells/devbox-android.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "$schema": "https://raw.githubusercontent.com/jetify-com/devbox/0.14.2/.schema/devbox.schema.json", - "packages": { - "yarn-berry": "latest", - "jdk17": "latest", - "gradle": "latest", - "jq": "latest", - "path:../nix#android-sdk": "" - }, - "shell": { - "init_hook": [ - ". $DEVBOX_PROJECT_ROOT/../scripts/shared/common.sh", - "echo 'Android SDK env configured (details: wiki/devbox.md#devbox-android).'", - ". $SCRIPTS_DIR/android/env.sh" - ], - "scripts": { - "setup-android": ["bash $SCRIPTS_DIR/android/setup.sh"], - "test-android": ["bash $SCRIPTS_DIR/android/test.sh"] - } - } -} diff --git a/shells/devbox-fast.json b/shells/devbox-fast.json deleted file mode 100644 index 59aaccc83..000000000 --- a/shells/devbox-fast.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "$schema": "https://raw.githubusercontent.com/jetify-com/devbox/0.14.2/.schema/devbox.schema.json", - "packages": { - "yarn-berry": "latest", - "jq": "latest", - "treefmt": "latest", - "nixfmt": "latest", - "shfmt": "latest" - }, - "shell": { - "init_hook": [". $DEVBOX_PROJECT_ROOT/../scripts/shared/common.sh"], - "scripts": { - "build": ["bash $SCRIPTS_DIR/build.sh"], - "release": [ - "cd \"$PROJECT_ROOT\"", - "yarn install --immutable", - "yarn build", - "yarn multi-semantic-release" - ], - "release-dry-run": [ - "cd \"$PROJECT_ROOT\"", - "yarn install --immutable", - "yarn build", - "yarn multi-semantic-release --dry-run" - ], - "format": ["treefmt"], - "lint": ["treefmt --fail-on-change"], - "sync-versions": ["bash $SCRIPTS_DIR/sync-versions.sh"], - "update-apps": [ - "yarn install --no-immutable", - "yarn e2e install --no-immutable", - "yarn example install --no-immutable" - ] - } - } -} diff --git a/shells/devbox-ios.json b/shells/devbox-ios.json deleted file mode 100644 index ba43b7d33..000000000 --- a/shells/devbox-ios.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "$schema": "https://raw.githubusercontent.com/jetify-com/devbox/0.14.2/.schema/devbox.schema.json", - "packages": { - "cocoapods": { - "version": "latest", - "platforms": ["x86_64-darwin", "aarch64-darwin"] - }, - "yarn-berry": "latest", - "jq": "latest" - }, - "shell": { - "init_hook": [ - ". $DEVBOX_PROJECT_ROOT/../scripts/shared/common.sh", - "if [ \"$(uname -s)\" = \"Darwin\" ]; then . $SCRIPTS_DIR/ios/env.sh; fi" - ], - "scripts": { - "setup-ios": ["bash $SCRIPTS_DIR/ios/setup.sh"], - "test-ios": ["bash $SCRIPTS_DIR/ios/test.sh"] - } - } -} diff --git a/shells/devbox.lock b/shells/devbox.lock deleted file mode 100644 index e652c6018..000000000 --- a/shells/devbox.lock +++ /dev/null @@ -1,317 +0,0 @@ -{ - "lockfile_version": "1", - "packages": { - "github:NixOS/nixpkgs/nixpkgs-unstable": { - "last_modified": "2026-01-27T15:18:14Z", - "resolved": "github:NixOS/nixpkgs/afce96367b2e37fc29afb5543573cd49db3357b7?lastModified=1769527094" - }, - "jq@latest": { - "last_modified": "2026-01-20T02:11:35Z", - "resolved": "github:NixOS/nixpkgs/ed142ab1b3a092c4d149245d0c4126a5d7ea00b0#jq", - "source": "devbox-search", - "version": "1.8.1", - "systems": { - "aarch64-darwin": { - "outputs": [ - { - "name": "bin", - "path": "/nix/store/9rm6fm3zq1jq8rgsx528cw8wkmfya2gf-jq-1.8.1-bin", - "default": true - }, - { - "name": "man", - "path": "/nix/store/cv999saj62xhq7xv5i7q6944vljykfmw-jq-1.8.1-man", - "default": true - }, - { - "name": "dev", - "path": "/nix/store/5camppj4hz2mgkdbxs0kr6nvh6qa65wf-jq-1.8.1-dev" - }, - { - "name": "doc", - "path": "/nix/store/lak094rhhxlaj1qycadmxyfphgjadj5r-jq-1.8.1-doc" - }, - { - "name": "out", - "path": "/nix/store/g371yvjasdr552v98p5kav7n35s1dfib-jq-1.8.1" - } - ], - "store_path": "/nix/store/9rm6fm3zq1jq8rgsx528cw8wkmfya2gf-jq-1.8.1-bin" - }, - "aarch64-linux": { - "outputs": [ - { - "name": "bin", - "path": "/nix/store/m8qv4g54q3jmjb8i33v9lljcwhydx2vd-jq-1.8.1-bin", - "default": true - }, - { - "name": "man", - "path": "/nix/store/9x2457g76jikfy7xq4mjqwzl8iz3zvxj-jq-1.8.1-man", - "default": true - }, - { - "name": "dev", - "path": "/nix/store/5ykn83b3hhvnnq0p5vqgcrzihrl9wpsl-jq-1.8.1-dev" - }, - { - "name": "doc", - "path": "/nix/store/37ypy1595g6rj3cymh1mpk2b25fx40g7-jq-1.8.1-doc" - }, - { - "name": "out", - "path": "/nix/store/16lg603jzppwjanlakcak1ais69mkd03-jq-1.8.1" - } - ], - "store_path": "/nix/store/m8qv4g54q3jmjb8i33v9lljcwhydx2vd-jq-1.8.1-bin" - }, - "x86_64-darwin": { - "outputs": [ - { - "name": "bin", - "path": "/nix/store/kkb17whpkdrmn9g3gk7y6l69vipxsw0i-jq-1.8.1-bin", - "default": true - }, - { - "name": "man", - "path": "/nix/store/iwr61wi83kflqvz8j5nf7ridaqq6nh2w-jq-1.8.1-man", - "default": true - }, - { - "name": "dev", - "path": "/nix/store/lypnqs272644l8ff6wfji9rg5jw10v7h-jq-1.8.1-dev" - }, - { - "name": "doc", - "path": "/nix/store/nyw97c4pywfcqqap5hyk9xjghczlbshl-jq-1.8.1-doc" - }, - { - "name": "out", - "path": "/nix/store/ri930a557685c64bdh88a5031i7hx3vy-jq-1.8.1" - } - ], - "store_path": "/nix/store/kkb17whpkdrmn9g3gk7y6l69vipxsw0i-jq-1.8.1-bin" - }, - "x86_64-linux": { - "outputs": [ - { - "name": "bin", - "path": "/nix/store/zssasryipb2x4gk2ahzacl4mvvcmk48j-jq-1.8.1-bin", - "default": true - }, - { - "name": "man", - "path": "/nix/store/7d4pv1iymyqk2lykwj1ydml3rjhc6gl3-jq-1.8.1-man", - "default": true - }, - { - "name": "dev", - "path": "/nix/store/rmxxm5jnxq93kvkhbr2b3hzj6v3ldp8z-jq-1.8.1-dev" - }, - { - "name": "doc", - "path": "/nix/store/mkhfvc69grlky3iblibkw9wcc12jcdqq-jq-1.8.1-doc" - }, - { - "name": "out", - "path": "/nix/store/807g765zgpmp1c8fm5y40rw2gbr1k6dk-jq-1.8.1" - } - ], - "store_path": "/nix/store/zssasryipb2x4gk2ahzacl4mvvcmk48j-jq-1.8.1-bin" - } - } - }, - "nixfmt@latest": { - "last_modified": "2026-02-23T15:40:43Z", - "resolved": "github:NixOS/nixpkgs/80d901ec0377e19ac3f7bb8c035201e2e098cc97#nixfmt", - "source": "devbox-search", - "version": "1.2.0", - "systems": { - "aarch64-darwin": { - "outputs": [ - { - "name": "out", - "path": "/nix/store/igl44md7ljf5c3hx6s6ys6325fkpldny-nixfmt-1.2.0", - "default": true - } - ], - "store_path": "/nix/store/igl44md7ljf5c3hx6s6ys6325fkpldny-nixfmt-1.2.0" - }, - "aarch64-linux": { - "outputs": [ - { - "name": "out", - "path": "/nix/store/s250gfxr6v1bmxdx9l8z4sn5fjf2bllb-nixfmt-1.2.0", - "default": true - } - ], - "store_path": "/nix/store/s250gfxr6v1bmxdx9l8z4sn5fjf2bllb-nixfmt-1.2.0" - }, - "x86_64-darwin": { - "outputs": [ - { - "name": "out", - "path": "/nix/store/jb1qw3g5hcslahl02v7mjaixwfw725g8-nixfmt-1.2.0", - "default": true - } - ], - "store_path": "/nix/store/jb1qw3g5hcslahl02v7mjaixwfw725g8-nixfmt-1.2.0" - }, - "x86_64-linux": { - "outputs": [ - { - "name": "out", - "path": "/nix/store/ihzhi2cgjfhvqbap36fx91hbj524ym5l-nixfmt-1.2.0", - "default": true - } - ], - "store_path": "/nix/store/ihzhi2cgjfhvqbap36fx91hbj524ym5l-nixfmt-1.2.0" - } - } - }, - "shfmt@latest": { - "last_modified": "2026-02-23T15:40:43Z", - "resolved": "github:NixOS/nixpkgs/80d901ec0377e19ac3f7bb8c035201e2e098cc97#shfmt", - "source": "devbox-search", - "version": "3.12.0", - "systems": { - "aarch64-darwin": { - "outputs": [ - { - "name": "out", - "path": "/nix/store/sc8kb91395fw69qcmij89m3bxdmj8gwb-shfmt-3.12.0", - "default": true - } - ], - "store_path": "/nix/store/sc8kb91395fw69qcmij89m3bxdmj8gwb-shfmt-3.12.0" - }, - "aarch64-linux": { - "outputs": [ - { - "name": "out", - "path": "/nix/store/a80kl3brskqmq8k861x8hjwnlw94kyfn-shfmt-3.12.0", - "default": true - } - ], - "store_path": "/nix/store/a80kl3brskqmq8k861x8hjwnlw94kyfn-shfmt-3.12.0" - }, - "x86_64-darwin": { - "outputs": [ - { - "name": "out", - "path": "/nix/store/hax40r2y50jv8z0rlryfc11gvnhfx7hz-shfmt-3.12.0", - "default": true - } - ], - "store_path": "/nix/store/hax40r2y50jv8z0rlryfc11gvnhfx7hz-shfmt-3.12.0" - }, - "x86_64-linux": { - "outputs": [ - { - "name": "out", - "path": "/nix/store/822axjnnxnscgxwval6lrc1bp5q4n9li-shfmt-3.12.0", - "default": true - } - ], - "store_path": "/nix/store/822axjnnxnscgxwval6lrc1bp5q4n9li-shfmt-3.12.0" - } - } - }, - "treefmt@latest": { - "last_modified": "2026-02-23T15:40:43Z", - "resolved": "github:NixOS/nixpkgs/80d901ec0377e19ac3f7bb8c035201e2e098cc97#treefmt", - "source": "devbox-search", - "version": "2.4.0", - "systems": { - "aarch64-darwin": { - "outputs": [ - { - "name": "out", - "path": "/nix/store/gza41a4j5hypl5vl6f7x5s0xgnx0g06h-treefmt-2.4.0", - "default": true - } - ], - "store_path": "/nix/store/gza41a4j5hypl5vl6f7x5s0xgnx0g06h-treefmt-2.4.0" - }, - "aarch64-linux": { - "outputs": [ - { - "name": "out", - "path": "/nix/store/rz6d1w4a8gkkrd9gk4nfadskzyz75h4v-treefmt-2.4.0", - "default": true - } - ], - "store_path": "/nix/store/rz6d1w4a8gkkrd9gk4nfadskzyz75h4v-treefmt-2.4.0" - }, - "x86_64-darwin": { - "outputs": [ - { - "name": "out", - "path": "/nix/store/h7xb3dssb16yny6wg713w78lawivzjay-treefmt-2.4.0", - "default": true - } - ], - "store_path": "/nix/store/h7xb3dssb16yny6wg713w78lawivzjay-treefmt-2.4.0" - }, - "x86_64-linux": { - "outputs": [ - { - "name": "out", - "path": "/nix/store/vp95nd69hq59rqpdlgrg63wncy4yw8fd-treefmt-2.4.0", - "default": true - } - ], - "store_path": "/nix/store/vp95nd69hq59rqpdlgrg63wncy4yw8fd-treefmt-2.4.0" - } - } - }, - "yarn-berry@latest": { - "last_modified": "2025-12-31T03:27:36Z", - "resolved": "github:NixOS/nixpkgs/f665af0cdb70ed27e1bd8f9fdfecaf451260fc55#yarn-berry", - "source": "devbox-search", - "version": "4.12.0", - "systems": { - "aarch64-darwin": { - "outputs": [ - { - "name": "out", - "path": "/nix/store/2l7sbyyqardvrzr35zkrw67gbng5gb8y-yarn-berry-4.12.0", - "default": true - } - ], - "store_path": "/nix/store/2l7sbyyqardvrzr35zkrw67gbng5gb8y-yarn-berry-4.12.0" - }, - "aarch64-linux": { - "outputs": [ - { - "name": "out", - "path": "/nix/store/klx9ndw1djgx0zhhyrkcn9an094rmmwv-yarn-berry-4.12.0", - "default": true - } - ], - "store_path": "/nix/store/klx9ndw1djgx0zhhyrkcn9an094rmmwv-yarn-berry-4.12.0" - }, - "x86_64-darwin": { - "outputs": [ - { - "name": "out", - "path": "/nix/store/m6cwiya6hrbwnlprh2cbnmz6c7mkylrf-yarn-berry-4.12.0", - "default": true - } - ], - "store_path": "/nix/store/m6cwiya6hrbwnlprh2cbnmz6c7mkylrf-yarn-berry-4.12.0" - }, - "x86_64-linux": { - "outputs": [ - { - "name": "out", - "path": "/nix/store/q1gys3zgijcciiafbh9nfawkx5wj8179-yarn-berry-4.12.0", - "default": true - } - ], - "store_path": "/nix/store/q1gys3zgijcciiafbh9nfawkx5wj8179-yarn-berry-4.12.0" - } - } - } - } -} diff --git a/shells/gradle.properties b/shells/gradle.properties deleted file mode 100644 index a468eda9e..000000000 --- a/shells/gradle.properties +++ /dev/null @@ -1 +0,0 @@ -org.gradle.java.home=/nix/store/hlm8a8cnp4hm8xkg0a2yy4kv7cq44jii-zulu-ca-jdk-17.0.12