EAS Update Runbook
Critical: Always set EXPO_PUBLIC_API_URL before running eas update
eas update does not inherit the env block from eas.json build profiles.
EXPO_PUBLIC_API_URL is a build-time constant baked into the JS bundle at export time.
If it is unset when you run eas update, the bundle falls back to the hardcoded dev API URL
in mobile/src/api.js, breaking login and all API calls on the staging/production app.
Correct command for staging OTA updates
$env:EXPO_PUBLIC_API_URL = "https://staging.evergrn.co"
$env:EXPO_TOKEN = "<token>"
$env:CI = "1"
cd mobile
eas update --channel staging --message "your message"
Correct command for production OTA updates
$env:EXPO_PUBLIC_API_URL = "https://api.evergrn.co"
$env:EXPO_TOKEN = "<token>"
$env:CI = "1"
cd mobile
eas update --channel production --message "your message"
Why this matters
The fallback in mobile/src/api.js is now the staging URL (fixed 2026-06-28):
export const BASE_URL = process.env.EXPO_PUBLIC_API_URL
|| 'https://staging.evergrn.co'
Local dev (npx expo start) uses mobile/.env which sets the URL to the dev API โ
that file is gitignored and must be present on each dev machine.
EAS builds (staging/production) set EXPO_PUBLIC_API_URL via eas.json env section.
OTA updates must set it explicitly (see commands above). Forgetting it previously caused the app to silently hit dev โ symptoms were:
- "Invalid credentials" on login (accounts don't exist on dev)
- Staging/production data not appearing
- No error shown โ app just behaves as if credentials are wrong
Rotate the Expo token
The token UP25rH6Gh_97fBR23UxMNNTgOLq2M1W9yevooL7m was used in plain text
during session setup. Rotate it at https://expo.dev/accounts/davis151851/settings/access-tokens
and update wherever it is stored.
OTA update vs native rebuild
OTA updates (eas update) can change:
- JS logic, screens, navigation
- API call logic, push notification handling
- Any
EXPO_PUBLIC_*env var values (set at bundle time)
OTA updates cannot change:
- Native modules or permissions
app.jsonconfiguration (icons, bundle ID, entitlements)eas.jsonbuild profiles- Any code that runs in the native layer
If you change app.json, add a native package, or need to update entitlements,
you need a full eas build --profile staging followed by TestFlight re-submission.
APNs credentials โ resolved 2026-06-28
Status as of 2026-06-28: Resolved. APNs key uploaded to EAS via staging credentials flow. iOS push notifications should now deliver at the OS level.
What exists:
- APNs key
SSW3R447H4โ active in Apple Developer Portal until 2027-06-25, Team2QH59J6E6Y - Push token registration in the app is working (token stored in DB after login)
sendPushcalls fire correctly from the API
What's missing:
- The
.p8file for keySSW3R447H4needs to be uploaded to EAS
Fix (one-time, no rebuild needed):
- Locate the
.p8file downloaded when keySSW3R447H4was created - Go to expo.dev โ Projects โ evergrn โ Credentials โ iOS โ Push Notifications โ Add
- Enter Key ID
SSW3R447H4, Team ID2QH59J6E6Y, upload the.p8 - Push notifications will work immediately โ no OTA or rebuild required
If the .p8 file is lost:
Keys can only be downloaded once. Revoke SSW3R447H4 in Apple Developer Portal (Keys),
create a new key with APNs enabled, download the .p8, and upload to EAS as above.
Note: eas credentials --platform ios --profile staging from the CLI hits a bug
where it defaults to the simulator profile and errors with
"A simulator distribution does not require credentials." Use the web dashboard instead.