# Task 5 — Dev Build Workflow (Shared Native Binary for All Devs)

## Context
We're replacing Expo Go with development builds (expo-dev-client) because the app has
`newArchEnabled: true` which Expo Go doesn't support. Devs install one shared dev build
binary and switch between PR branches via the dev-client launcher (shake/gesture → home → pick branch).
New native builds are only triggered when native deps actually change.

## Branch / Worktree
Create a new worktree:
```
git worktree add .claude/worktrees/ci-dev-build -b feat/ci-dev-build
```

## What to create

### `.github/workflows/build-dev.yml`
```yaml
name: Build Dev Client

on:
  workflow_dispatch:    # manual trigger (anyone can kick it)
  push:
    branches: [main]
    paths:              # auto-trigger only on native changes
      - 'package.json'
      - 'app.json'
      - 'eas.json'

concurrency:
  group: build-dev
  cancel-in-progress: true   # if native change on main, cancel previous run

permissions:
  contents: read

jobs:
  build:
    name: Build Dev Client (${{ matrix.platform }})
    runs-on: ubuntu-latest
    strategy:
      matrix:
        platform: [ios, android]
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
      - uses: pnpm/action-setup@v4
      - name: Get pnpm store
        run: echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV
      - uses: actions/cache@v4
        with:
          path: ${{ env.STORE_PATH }}
          key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
          restore-keys: ${{ runner.os }}-pnpm-store-
      - run: pnpm install --frozen-lockfile
      - uses: expo/expo-github-action@v8
        with:
          eas-version: ^18.0.0
          packager: pnpm
          token: ${{ secrets.EXPO_TOKEN }}
      - name: Build dev client
        run: eas build --platform ${{ matrix.platform }} --profile development --non-interactive
```

### `eas.json` — `development` profile update
The development profile needs a channel so OTA updates (from `eas update --branch pr-{N}`)
can be received. Update the development profile:
```json
"development": {
  "developmentClient": true,
  "distribution": "internal",
  "channel": "preview",
  "env": {
    "APP_ENV": "development"
  }
}
```
Setting `channel: "preview"` means dev builds listen to the `preview` channel.
When the PR preview hook runs `eas channel:edit preview --branch pr-{N}`, 
all installed dev builds switch to that PR's bundle.

## Dependencies
- iOS development build needs ad-hoc distribution credentials (device registered)
  - Fathoni's iPhone is already registered (UDID: 00008110-001C5D5234D9801E)
  - Development profile uses `distribution: "internal"` (ad-hoc) 
  - The preview ad-hoc credentials generated in eas-setup session can be reused
    (same bundle ID pattern — but development uses `ai.nanostreet.app.dev`)
  - Need to check if `ai.nanostreet.app.dev` has credentials set up in expo.dev
- Android development build: EAS manages automatically ✅
- `EXPO_TOKEN` already configured ✅

## Key behavior
- Devs install this binary once
- Shake device → dev menu → "Go home" → see branch list → tap to switch PR
- QR code in PR comment = deep-link shortcut to load that PR branch directly
- Binary is only rebuilt when package.json / app.json / eas.json changes
- Estimated frequency: 0–2 rebuilds per month → fits 15/month quota easily

## Acceptance criteria
- [ ] `workflow_dispatch` from GitHub UI triggers build for both platforms
- [ ] iOS `.ipa` installs on Fathoni's iPhone (ad-hoc registered device)
- [ ] Android `.apk` installs via internal link
- [ ] Shake → dev menu → "Go home" works on device
- [ ] After `eas update --branch pr-123`, scanning PR QR loads that PR's bundle
- [ ] Pushing a JS-only change to main does NOT trigger this workflow
