Files
fressh/CONTRIBUTING.md
EthanShoeDev 7eda9b1295 Add flake
2025-09-12 14:14:52 -04:00

230 lines
5.6 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Development with Nix (Android/Expo)
This repo ships a Nix **flake** that provides reproducible dev shells for React
Native + Expo and Android workflows. You dont need global installs of
Node/Watchman/Android SDK—the shell provides everything.
## Prereqs
- Nix with flakes enabled (`nix --version` should work)
- (Optional, recommended) [`direnv`](https://direnv.net/) +
[`nix-direnv`](https://github.com/nix-community/nix-direnv) to auto-enter
shells
## Shell variants
We publish three dev shells:
- **`default`** minimal JS toolchain you always want (Node, pnpm, watchman,
git, jq, just)
- **`android-local`** adds a full **Android SDK** + **Emulator** + **API 36
Google Play x86_64** system image Good when you run the emulator **on your
machine**.
- **`android-remote`** no emulator/image; adds **adb** + **scrcpy** Good when
you run an emulator **on a remote server** and mirror/control it locally.
Pick one per your setup.
## Quick start
### A) One-off use (no direnv)
```bash
# Minimal JS shell
nix develop .#default
# Local emulator workflow (SDK + emulator + API 36 image)
nix develop .#android-local
# Remote emulator workflow (adb + scrcpy only)
nix develop .#android-remote
```
### B) Auto-enter with direnv (recommended)
Create `.envrc` at the project root:
```bash
# choose one:
use flake .#android-local
# use flake .#android-remote
# use flake .#default
```
Then:
```bash
direnv allow
```
Any new shell in this folder will enter the selected dev shell automatically.
## What the shell sets up
- **Node/PNPM/Watchman/Git/JQ/Just** (all shells)
- **ANDROID_SDK_ROOT / ANDROID_HOME** (in `android-local`; points to the
immutable SDK built by Nix)
- **adb / emulator / sdkmanager / avdmanager** (in `android-local`)
- **adb / scrcpy** (in `android-remote`)
> Tip: we keep the Android SDK fully **immutable** (declarative). You dont
> “install packages” via Android Studio; the flake lists exactly which
> components are present.
## Local emulator workflow (`android-local`)
1. Enter the shell:
```bash
nix develop .#android-local
```
2. (First time) Create an AVD for API 36 (Google Play, x86_64):
```bash
avdmanager create avd -n a36-play-x86_64 \
-k "system-images;android-36;google_apis_playstore;x86_64"
```
3. Run the emulator:
```bash
# GUI window (desktop)
emulator @a36-play-x86_64
# Headless (CI/servers):
emulator @a36-play-x86_64 -no-window -no-audio
# If no KVM: add -gpu swiftshader_indirect
```
4. Verify `adb` sees it:
```bash
adb devices
```
5. Run your typical Expo/RN commands (Metro, build, etc.) inside the shell.
> **macOS users**: You can still build Android in this shell. The
> `android-local` shell provides `platform-tools` + SDK commands; the GUI
> Android Studio app is optional. If you prefer to use the macOS GUI emulator
> instead of the Nix one, thats fine—use `default` or `android-remote` and keep
> your local Android Studio install.
## Remote emulator workflow (`android-remote`)
Use this when your emulator runs on a remote Linux box (often headless/KVM).
1. Enter the shell:
```bash
nix develop .#android-remote
```
2. SSH-tunnel the **remote adb server** back to your machine:
```bash
ssh -N -L 5037:127.0.0.1:5037 user@remote-host
```
3. Point `adb` at the forwarded server and verify:
```bash
adb -H 127.0.0.1 -P 5037 devices
```
4. Mirror/control the remote emulator window locally:
```bash
scrcpy
```
Thats it—everything flows through SSH, and you dont need any extra ports.
## Common tasks
- Check versions:
```bash
adb version
sdkmanager --version
avdmanager --help
```
- Upgrade/change Android components Edit the system image or
build-tools/platforms listed in `flake.nix` under the `androidSdk36`
definition, then re-enter the shell.
- Clean emulators/AVDs AVDs live in `~/.android/avd` by default. You can remove
an AVD with:
```bash
avdmanager delete avd -n a36-play-x86_64
```
## Troubleshooting
- **Emulator is very slow / wont start** (Linux): Ensure `/dev/kvm` exists and
your user has permission (`kvm` group). Headless servers without KVM can still
run, but add `-gpu swiftshader_indirect` and expect reduced performance.
- **`adb` doesnt see the emulator**: Kill any stray local adb server and retry:
```bash
adb kill-server
adb start-server
adb devices
```
- **Gradle/Java mismatch**: If your Android Gradle Plugin complains about Java,
pin the JDK you need in the dev shell and set `JAVA_HOME`. (You can add a JDK
to `defaultPkgs` in the flake if your project requires a specific version.)
- **Expo/Metro cant find Android SDK**: Confirm `echo $ANDROID_SDK_ROOT` prints
a path in the `android-local` shell.
## CI usage
You can build/test in CI with:
```bash
nix develop --command bash -lc 'pnpm install && pnpm test'
```
or pick a specific shell:
```bash
nix develop .#android-local --command bash -lc 'just android-build'
```
---
If you want, I can add a tiny `Justfile` with `just avd-create`, `just avd-run`,
and `just adb-tunnel-remote` helpers so the common commands are one-liners.
## Enable Nix flakes globally
If you see errors like:
```
error: experimental Nix feature 'nix-command' is disabled; add '--extra-experimental-features nix-command' to enable it
```
…it means flakes are not enabled in your Nix configuration yet.
You can enable them permanently with a one-liner:
```bash
sudo mkdir -p /etc/nix && echo 'experimental-features = nix-command flakes' | sudo tee /etc/nix/nix.conf
```
Then restart your shell (or `nix-daemon` on macOS), and the error goes away.
From now on you can just run:
```bash
nix develop .#android-local
```
without passing any extra flags.