A mobile application build for DWR & UDOT for users to submit reports about roadkill.
- create
.envfiles in<root>,src/front, andsrc/back - from root:
docker compose up - from root:
pnpm install - in both
src/frontandsrc/back:pnpm startpnpm test
Press "j" in console after starting expo project. See Expo Debugging & Profiling docs for more details.
pnpm dlx uri-scheme open exp://127.0.0.1:19000/--/main --ios
pnpm dlx uri-scheme open exp://127.0.0.1:19000/--/main --android
| git branch | app version | runtime version | deployed | release-channel | expo version |
|---|---|---|---|---|---|
| dev | 3.1.1 | 6.0.0 | custom dev clients for simulators are in src/front/dev-clients, app has an orange icon (dev clients for for physical devices can be installed directly from the expo build website) |
default | 57 |
| dev | 3.1.1 | 6.0.0 | TestFlight and Google Play internal testing separate apps from production with a blue icon | preview | 57 |
| main | 3.1.0 | 5.0.0 | App Stores | production | 52 |
These three environments are three separate bundle IDs (see src/front/app.config.js) and can all be installed on the same device simultaneously.
If you need to change something that requires a new app build (e.g. changes to app.config.js or any other native code library update), bump the runtimeVersion prop in app.config.js to keep it on a new release channel thus preventing conflicts with older app builds. expo-update will only download updates with matching app version numbers because we are using the "Custom runtimeVersion" runtime policy.
These values are managed in three places: .env.* files in your local project, GitHub Actions Secrets (for back end deployments), and Expo EAS Secrets.
These values are managed in GCP Secrets Manager. After running the terraform, make sure to populate versions for the secrets that it creates. Also create corresponding secret files in src/back/secrets/<secret_name>/value for local development.
- Create the following repo secrets in GitHub for each environment: Do the same thing for the front end only the secrets go in Expo EAS. It would be great to get these out of EAS and managed entirely in GitHub.
- The firebase project is created via terraform, but the apps need to be created manually via the firebase console. Follow these steps from the expo docs.
- Enable analytics in Firebase
- Create a web app just to get the
measurementIdconfig for theFIREBASE_MEASUREMENT_IDenv variable.
- From
/data:./start_cloud_sql_proxy.sh prod(ordev) (This need so to be done for each environment per release!) - From
src/front:pnpm run update-constants(may need to update the db connection props in.env) - Determine if the api version needs to be bumped and update src/common/config.js and src/back/package.json accordingly.
- Determine if app version (
versionin app.config.js) needs to be bumped. Apple requires it to be bumped after every production release. - Determine if
runtimeVersionneeds to be bumped (if any native code has changed). - Bump build number in src/front/app.config.js.
- Update value in changelog_context.json to match new version and build number.
- From root:
pnpm run changelog - Clean up change log entries, if needed.
- Create release commit (e.g.
release: v3.0.0 (123)) - Tag
git tag v3.0.0-123.stagingorgit tag v3.0.0-123(production) - Pushing to
devormainbranches will push a new image to the cloud run back end.
Do one of the following from src/front:
./scripts/deployNewAppBuild.shif a new app build is needed.- Android: Create new internal testing release in the appropriate version of the app.
- Apple: Promote release to "External Testers". Click the "notify testers" link next to the newly uploaded build in the appropriate version of the app in TestFlight.
or
- Push an OTA update (not applicable if the
runtimeVersionwas bumped):./scripts/deployOTAUpdate.shto publish a new over-the-air update.
This app uses a custom Expo Dev rather than the old Expo Go app. This means that anytime you install or upgrade a library with native code, you need to create new builds by running ./scripts/buildForDevelopment.sh.
After testing in dev client...
- From
src/front:./scripts/deployNewAppBuild.sh - Generate new screenshots if applicable.
- Apple Specs
- 6.9" - iPhone 16 Plus
- 13" - iPad Pro (M4)
- Android:
- Use any simulator
- Apple Specs
- Create new version in iTunes connect and update all relevant information.
- Submit the apps for review in both app stores.
Because app builds initiate from both the developer's machine (new native builds) and GitHub Actions (over-the-air updates), secrets need to be managed in both places. .env.sample should be duplicated and populated to .env, .env.staging, .env.production. Corresponding secrets are also stored in environments in the GitHub repository and EAS. These values can be found in the terraform repo.
Android Devices (Internal Testing): Production | Staging. Accounts need to be added to the "Wildlife-Vehicle Collisions" tester group before they can join the test.
iOS Devices (TestFlight): Production | Staging
The back end of this application uses firebase firestore and storage emulators during local development. Go to http://localhost:4000 to see the UI for them.
iOS: Trip Simulator
Initial Database Design Diagram - This has been replaced by data/sql/init.sql as the single source of truth for the design.
Database migrations are managed via knex from the ./data folder. Run knex migrate:make <migration-name> to create a new one.
These are the images that show up next to the species/class/order/family names. They are stored in a bucket named ut-dts-agrc-roadkill-[dev|prod]-identification-images. Members of the gcp-dts-ugrc-roadkill-viewers Google Group have object admin level access to the bucket. The images should be uploaded with the file extension: .jpg and sized 150 by 150 pixels.
The file name should match a distinct value from one of the following columns in the species table:
species_idspecies_classspecies_orderfamily
If a matching file in the bucket is not found, a blank gray fallback image is returned.
The repo is a single pnpm workspace (data, data/scripts, src/back, src/common, src/front, src/website) with one root pnpm-lock.yaml; all pnpm settings live in the root pnpm-workspace.yaml. Run pnpm install from the root. Dependency build scripts are denied by default; only approve them in allowBuilds when they are required for deployment.
The common package causes the expo build process to fail if it is switched to ESM at Expo v52.
- Update Expo SDK one major version at a time:
pnpm exec expo install expo@^<next SDK>.0.0 --fix pnpm dlx expo-doctor@latest- Commit changes as expo bump
pnpm dlx npm-check-updates --color --install always --interactive --format group,repo --cooldown 7 --reject react-native-collapsible && pnpm audit --fixpnpm exec expo install --fix(to downgrade any packages that are not compatible with the new Expo SDK)
react-native-collapsible has a bug in v1.6.2: a Collapsible that mounts expanded renders hidden, so the public sign-in options on the choose type screen need two taps to open. It is pinned to exactly 1.6.1 (no ^) in package.json. Keep the exact pin when updating dependencies or regenerating pnpm-lock.yaml; a caret range lets pnpm resolve 1.6.2 again.
This project was developed with the assistance of GitHub Copilot.