|
1 | 1 | # Devbox |
2 | 2 |
|
3 | | -This repo uses [Devbox](https://www.jetify.com/devbox/) for reproducible builds. Each example app has its own `devbox.json` that pins Node.js, JDK, and build tools via Nix, with the [`mobile-devtools`](https://github.com/segment-integrations/mobile-devtools) plugin providing emulator/simulator management. |
| 3 | +This repo uses [Devbox](https://www.jetify.com/devbox/docs/) to provide reproducible, project-local development environments. Devbox uses Nix under the hood to pin tool versions so everyone gets the same setup. You don't need to know Nix to use it. |
4 | 4 |
|
5 | | -The root `devbox.json` is for library development only (linting, building, testing, releasing). E2E builds and device management live in the per-app configs. |
| 5 | +There are two tiers of Devbox environment in this repo: |
6 | 6 |
|
7 | | -## Getting started |
| 7 | +1. **Root environment** (`devbox.json` at the repo root) — a lean environment for building, testing, linting, formatting, and releasing the library packages. It does **not** provision the Android SDK, emulators, or iOS simulators. |
| 8 | +2. **Example/E2E environments** (`examples/e2e-latest/devbox.json`, `examples/e2e-compat/devbox.json`) — full mobile build + device environments for running the Detox end-to-end suites. These provision the Android and iOS toolchains via the shared [mobile-devtools](https://github.com/segment-integrations/mobile-devtools) Devbox plugins. |
8 | 9 |
|
9 | | -1. Install Devbox: https://www.jetify.com/devbox/docs/installing_devbox/ |
10 | | -2. Navigate to an example app directory: |
11 | | - ```bash |
12 | | - cd examples/e2e-compat # or e2e-latest |
13 | | - ``` |
14 | | -3. Run commands via `devbox run`: |
15 | | - ```bash |
16 | | - devbox run install |
17 | | - devbox run install:pods # iOS only |
18 | | - devbox run build:android |
19 | | - devbox run build:ios |
20 | | - ``` |
| 10 | +## Root environment |
21 | 11 |
|
22 | | -## Per-app configuration |
| 12 | +Enter it from the repo root with `devbox shell`. The init hook sets `PROJECT_ROOT`, adds `node_modules/.bin` to `PATH`, runs `yarn install` if dependencies are missing, prebuilds `packages/core/src/info.ts`, and installs the Husky git hooks. |
23 | 13 |
|
24 | | -Each example app's `devbox.json` defines: |
| 14 | +### Packages |
25 | 15 |
|
26 | | -- **Packages**: Node.js, Yarn, JDK, and optional extras (watchman, etc.) |
27 | | -- **Plugin**: `mobile-devtools` from `github:segment-integrations/mobile-devtools?dir=plugins/react-native&ref=main` |
28 | | -- **Environment variables**: SDK versions, artifact paths, cmake version |
29 | | -- **Scripts**: `install`, `install:pods`, `build:android`, `build:ios`, `test:android`, `test:ios` |
| 16 | +`cocoapods`, `nodejs` 22, `yarn-berry`, `jq`, `treefmt`, `nixfmt`, `shfmt`. |
30 | 17 |
|
31 | | -### Plugin-provided scripts |
| 18 | +### Scripts |
32 | 19 |
|
33 | | -The `mobile-devtools` plugin adds device management commands: |
| 20 | +Run with `devbox run <script>`: |
34 | 21 |
|
35 | | -| Script | Description | |
36 | | -| -------------------- | --------------------------- | |
37 | | -| `start:emu [device]` | Start Android emulator | |
38 | | -| `stop:emu` | Stop Android emulator | |
39 | | -| `start:sim [device]` | Start iOS simulator | |
40 | | -| `stop:sim` | Stop iOS simulator | |
41 | | -| `start:android` | Build + deploy to emulator | |
42 | | -| `start:ios` | Build + deploy to simulator | |
| 22 | +- `build` — build all public workspaces (`yarn build`). |
| 23 | +- `test` — run unit tests (`yarn test`). |
| 24 | +- `typecheck` — type-check (`yarn typecheck`). |
| 25 | +- `lint` / `format` / `format-check` — ESLint and treefmt. |
| 26 | +- `check` — runs lint, format-check, build, typecheck, and test in sequence (the local equivalent of CI). |
| 27 | +- `clean` — clean build artifacts and `node_modules`. |
| 28 | +- `release` / `release-dry-run` — run multi-semantic-release (see [RELEASING.md](../RELEASING.md)); these are invoked by the `Release` GitHub workflow, not run locally as a rule. |
| 29 | +- `sync-versions` — reconcile `package.json` versions with what was published to npm (`scripts/sync-versions.sh`). |
| 30 | +- `update-apps` — refresh the example apps' dependencies against the workspace. |
| 31 | +- `ci:install` / `ci:commitlint` — used by CI. |
43 | 32 |
|
44 | | -## Root devbox.json |
| 33 | +## Example / E2E environments |
45 | 34 |
|
46 | | -The root config is for library development and CI: |
| 35 | +The Detox E2E suites live in the example workspaces: |
47 | 36 |
|
48 | | -| Script | Description | |
49 | | -| --------------- | ------------------------------------- | |
50 | | -| `build` | Build all packages | |
51 | | -| `test` | Run unit tests | |
52 | | -| `lint` | Run ESLint | |
53 | | -| `typecheck` | Run TypeScript type checking | |
54 | | -| `format` | Format with prettier | |
55 | | -| `release` | Publish packages via semantic-release | |
56 | | -| `sync-versions` | Sync package.json versions with npm | |
| 37 | +- `examples/e2e-latest` — newest supported React Native. |
| 38 | +- `examples/e2e-compat` — minimum supported React Native. |
| 39 | + |
| 40 | +Each `devbox.json` includes the React Native plugin from mobile-devtools: |
| 41 | + |
| 42 | +```json |
| 43 | +"include": [ |
| 44 | + "github:segment-integrations/mobile-devtools?dir=plugins/react-native&ref=main" |
| 45 | +] |
| 46 | +``` |
| 47 | + |
| 48 | +The React Native plugin composes the Android and iOS plugins, which provide the emulator/simulator lifecycle and device management. Project-local device definitions and lock files are committed under each example's `devbox.d/` directory (`segment-integrations.mobile-devtools.android/` and `…ios/`, with `devices/min.json` and `devices/max.json` plus their `.lock` files), so the SDK/device configuration is reviewable in PRs and reproducible across machines. |
| 49 | + |
| 50 | +### Running E2E |
| 51 | + |
| 52 | +From an example directory: |
| 53 | + |
| 54 | +```sh |
| 55 | +cd examples/e2e-latest # or examples/e2e-compat |
| 56 | + |
| 57 | +# iOS |
| 58 | +devbox run build:ios |
| 59 | +devbox run test:ios |
| 60 | + |
| 61 | +# Android |
| 62 | +devbox run build:android |
| 63 | +devbox run test:android |
| 64 | +``` |
| 65 | + |
| 66 | +The `build:*` scripts are defined locally in each example's `devbox.json`; `test:*` boot a simulator/emulator (via the plugin's `start:sim` / `start:emu`) and then run Detox. See [wiki/e2e/setup.md](e2e/setup.md) for the shared test architecture and [.github/workflows/e2e-tests.yml](../.github/workflows/e2e-tests.yml) for how CI orchestrates the matrix. |
| 67 | + |
| 68 | +### Plugin-provided commands |
| 69 | + |
| 70 | +The mobile-devtools React Native plugin exposes device/build helpers that the example scripts build on, including: |
| 71 | + |
| 72 | +- **Android:** `devbox run start:emu`, `devbox run stop:emu`, `devbox run reset:emu`, `devbox run start:android` (build + install + launch). |
| 73 | +- **iOS:** `devbox run start:sim`, `devbox run stop:sim`, `devbox run start:ios` (build + install + launch). |
| 74 | +- **Metro:** `devbox run start:metro`, `devbox run stop:metro`. |
| 75 | +- **Diagnostics:** `devbox run doctor`, `devbox run verify:setup`. |
| 76 | + |
| 77 | +For the full command list, configurable env vars, and device-definition/lock-file workflow, see the plugin docs in the [mobile-devtools](https://github.com/segment-integrations/mobile-devtools) repo (`plugins/react-native/README.md` and `REFERENCE.md`, plus the `plugins/android` and `plugins/ios` READMEs). |
| 78 | + |
| 79 | +### Configuring SDK / device versions |
| 80 | + |
| 81 | +SDK levels and build tools are set via env vars in the example's `devbox.json` (e.g. `ANDROID_COMPILE_SDK`, `ANDROID_BUILD_TOOLS_VERSION`, `CMAKE_VERSION`, `ANDROID_APP_APK`, `IOS_APP_ARTIFACT`). Device targets are defined in the `devbox.d/.../devices/*.json` files and pinned by the adjacent `.lock` files; after editing a device definition, regenerate its lock file per the plugin docs. The Detox device wiring lives in each example's `.detoxrc.js`. |
57 | 82 |
|
58 | 83 | ## iOS build notes |
59 | 84 |
|
| 85 | +iOS uses the host Xcode toolchain — there is no Nix-provisioned iOS SDK. Make sure full Xcode is installed (Command Line Tools alone are not enough for `simctl`), the right toolchain is selected (`xcode-select --print-path`), and you have accepted the Xcode license. On macOS, `devbox shell` injects Nix toolchain variables; the plugin's init hooks re-select the system toolchain so Xcode builds work. |
| 86 | + |
60 | 87 | Both example apps use a two-step iOS build to avoid Metro resolution issues in the monorepo: |
61 | 88 |
|
62 | | -1. `RCT_NO_LAUNCH_PACKAGER=1 SKIP_BUNDLING=1 xcodebuild ...` — builds native binary without bundling JS or spawning Metro |
63 | | -2. `react-native bundle ...` — creates the JS bundle directly into the .app |
| 89 | +1. `RCT_NO_LAUNCH_PACKAGER=1 SKIP_BUNDLING=1 xcodebuild ...` — builds the native binary without bundling JS or spawning Metro. |
| 90 | +2. `react-native bundle ...` — creates the JS bundle directly into the `.app`. |
64 | 91 |
|
65 | 92 | `RCT_NO_LAUNCH_PACKAGER=1` prevents the Xcode "Start Packager" build phase from opening a Metro terminal during release builds. |
66 | 93 |
|
67 | 94 | ## Android build notes |
68 | 95 |
|
69 | | -- `e2e-compat` (RN 0.72): Standard `./gradlew assembleRelease` |
70 | | -- `e2e-latest` (RN 0.84): Runs `generateCodegenArtifactsFromSchema --rerun-tasks` before assembly (required for New Architecture) |
| 96 | +- `e2e-compat` (RN 0.72): standard `./gradlew assembleRelease`. |
| 97 | +- `e2e-latest` (RN 0.84): runs `generateCodegenArtifactsFromSchema --rerun-tasks` before assembly (required for the New Architecture). |
| 98 | + |
| 99 | +## Releases |
| 100 | + |
| 101 | +`devbox run release` (root environment) runs `yarn install --immutable`, `yarn build`, and `yarn release` (multi-semantic-release). It is invoked by the production/beta jobs of the `Release` GitHub workflow. Publishing to npm uses OIDC trusted publishing with provenance — there is **no** `NPM_TOKEN`; the workflow passes only `GH_TOKEN` (`github.token`) for GitHub releases. See [RELEASING.md](../RELEASING.md) for the full release guide. |
0 commit comments