Skip to content

Commit a308cee

Browse files
author
Lalit Sharma
committed
feat: add CI and EAS Build workflows, configure expo-updates for OTA updates
1 parent 005d6e7 commit a308cee

6 files changed

Lines changed: 270 additions & 11 deletions

File tree

.github/workflows/ci.yml

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
branches: [main]
8+
9+
concurrency:
10+
group: ci-${{ github.ref }}
11+
cancel-in-progress: true
12+
13+
jobs:
14+
ci:
15+
name: Typecheck · Lint · Test
16+
runs-on: ubuntu-latest
17+
18+
steps:
19+
- name: Checkout
20+
uses: actions/checkout@v4
21+
22+
- name: Install pnpm
23+
uses: pnpm/action-setup@v4
24+
with:
25+
version: 9
26+
27+
- name: Setup Node
28+
uses: actions/setup-node@v4
29+
with:
30+
node-version: 20
31+
cache: pnpm
32+
33+
- name: Install dependencies
34+
run: pnpm install --frozen-lockfile
35+
36+
- name: Typecheck
37+
run: pnpm typecheck
38+
39+
- name: Lint
40+
run: pnpm lint
41+
42+
- name: Test
43+
run: pnpm test

.github/workflows/eas-build.yml

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
name: EAS Build & Submit
2+
3+
on:
4+
push:
5+
branches: [main]
6+
paths:
7+
- "apps/mobile/**"
8+
- "packages/**"
9+
- "pnpm-lock.yaml"
10+
workflow_dispatch:
11+
inputs:
12+
platform:
13+
description: "Platform to build"
14+
required: true
15+
default: "all"
16+
type: choice
17+
options:
18+
- all
19+
- ios
20+
- android
21+
submit:
22+
description: "Submit to stores after build"
23+
required: false
24+
default: false
25+
type: boolean
26+
27+
concurrency:
28+
group: eas-${{ github.ref }}
29+
cancel-in-progress: false
30+
31+
jobs:
32+
ci:
33+
name: CI checks
34+
runs-on: ubuntu-latest
35+
steps:
36+
- name: Checkout
37+
uses: actions/checkout@v4
38+
39+
- name: Install pnpm
40+
uses: pnpm/action-setup@v4
41+
with:
42+
version: 9
43+
44+
- name: Setup Node
45+
uses: actions/setup-node@v4
46+
with:
47+
node-version: 20
48+
cache: pnpm
49+
50+
- name: Install dependencies
51+
run: pnpm install --frozen-lockfile
52+
53+
- name: Typecheck
54+
run: pnpm typecheck
55+
56+
- name: Lint
57+
run: pnpm lint
58+
59+
- name: Test
60+
run: pnpm test
61+
62+
build:
63+
name: EAS Build (${{ github.event.inputs.platform || 'all' }})
64+
needs: ci
65+
runs-on: ubuntu-latest
66+
67+
steps:
68+
- name: Checkout
69+
uses: actions/checkout@v4
70+
71+
- name: Install pnpm
72+
uses: pnpm/action-setup@v4
73+
with:
74+
version: 9
75+
76+
- name: Setup Node
77+
uses: actions/setup-node@v4
78+
with:
79+
node-version: 20
80+
cache: pnpm
81+
82+
- name: Install dependencies
83+
run: pnpm install --frozen-lockfile
84+
85+
- name: Setup EAS CLI
86+
uses: expo/expo-github-action@v8
87+
with:
88+
eas-version: latest
89+
token: ${{ secrets.EXPO_TOKEN }}
90+
91+
- name: Build
92+
working-directory: apps/mobile
93+
run: eas build --profile production --platform ${{ github.event.inputs.platform || 'all' }} --non-interactive
94+
95+
submit:
96+
name: Submit to stores
97+
needs: build
98+
if: >-
99+
github.event_name == 'workflow_dispatch' &&
100+
github.event.inputs.submit == 'true'
101+
runs-on: ubuntu-latest
102+
environment: production # Requires manual approval in GitHub settings
103+
104+
steps:
105+
- name: Checkout
106+
uses: actions/checkout@v4
107+
108+
- name: Install pnpm
109+
uses: pnpm/action-setup@v4
110+
with:
111+
version: 9
112+
113+
- name: Setup Node
114+
uses: actions/setup-node@v4
115+
with:
116+
node-version: 20
117+
cache: pnpm
118+
119+
- name: Install dependencies
120+
run: pnpm install --frozen-lockfile
121+
122+
- name: Setup EAS CLI
123+
uses: expo/expo-github-action@v8
124+
with:
125+
eas-version: latest
126+
token: ${{ secrets.EXPO_TOKEN }}
127+
128+
- name: Submit to App Store Connect & Google Play
129+
working-directory: apps/mobile
130+
run: eas submit --platform ${{ github.event.inputs.platform || 'all' }} --non-interactive --latest

apps/mobile/app.json

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,18 @@
7373
"organization": "__YOUR_SENTRY_ORG__",
7474
"project": "__YOUR_SENTRY_PROJECT__"
7575
}
76-
]
76+
],
77+
"expo-updates"
7778
],
79+
"runtimeVersion": {
80+
"policy": "appVersion"
81+
},
82+
"updates": {
83+
"url": "https://u.expo.dev/a29a7662-96be-4509-a79e-fbe4b5dac1ff",
84+
"enabled": true,
85+
"fallbackToCacheTimeout": 0,
86+
"checkAutomatically": "ON_LOAD"
87+
},
7888
"extra": {
7989
"eas": {
8090
"projectId": "a29a7662-96be-4509-a79e-fbe4b5dac1ff"

apps/mobile/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
"expo-notifications": "~0.32.16",
2727
"expo-speech": "^14.0.8",
2828
"expo-splash-screen": "^31.0.13",
29+
"expo-updates": "^29.0.16",
2930
"react": "19.1.0",
3031
"react-native": "0.81.5",
3132
"react-native-maps": "1.20.1",

documents/tech-debt.md

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -210,12 +210,12 @@
210210
| ID | Item | Severity | Details |
211211
|----|------|----------|---------|
212212
| CI-00 | **Convert from Expo Go to EAS Build for production releases** | 🔴 Critical | ✅ Resolved 2026-02-16: created `eas.json` with `development`/`preview`/`production` build profiles (EAS project ID `a29a7662-96be-4509-a79e-fbe4b5dac1ff`). |
213-
| CI-01 | **No CI pipeline** | 🔴 Critical | No GitHub Actions, no GitLab CI, no any CI config. Nothing runs `typecheck`, `lint`, or `test` automatically on push/PR. |
214-
| CI-02 | **No automated mobile builds in CI** | 🟠 High | Even after EAS setup, there is no CI workflow that runs EAS builds to produce Android and iOS release artifacts automatically. |
213+
| CI-01 | **No CI pipeline** | 🔴 Critical | ✅ Resolved 2026-02-16: created `.github/workflows/ci.yml` (GitHub Actions) running `pnpm typecheck`, `pnpm lint`, `pnpm test` on push/PR to `main`. |
214+
| CI-02 | **No automated mobile builds in CI** | 🟠 High | ✅ Resolved 2026-02-16: created `.github/workflows/eas-build.yml` with CI → EAS Build → EAS Submit pipeline. Triggered on `main` push or manual dispatch. Submit job gated behind `environment: production` approval. |
215215
| CI-03 | **No app signing / keystore management** | 🟠 High | No `eas.json`, no code-signing config. Android `gradle.properties` still references debug keystore only. Required for store distribution. Severity upgraded — this blocks store submission. |
216216
| CI-04 | **No environment configuration** | 🟡 Medium | No `.env` / `.env.example`, no `expo-constants`, no staging vs. production config. API keys or feature flags have no mechanism. |
217217
| CI-05 | **No crash reporting / analytics** | 🟠 High | ✅ Resolved 2026-02-16: installed `@sentry/react-native`, configured `app.json` plugin, wrapped root with `Sentry.wrap` + `ErrorBoundary`. DSN placeholder requires replacement before production. |
218-
| CI-06 | **No OTA update mechanism** | 🟡 Medium | `expo-updates` not installed or configured. Every JS-only fix requires a full store release cycle. |
218+
| CI-06 | **No OTA update mechanism** | 🟡 Medium | ✅ Resolved 2026-02-16: installed `expo-updates`, configured `runtimeVersion` (appVersion policy) and `updates` URL pointing to EAS project in `app.json`. |
219219
| CI-07 | **No app store metadata** | 🟡 Medium | No screenshots, store description, keyword list, or promotional assets. Required for both App Store Connect and Google Play Console submission. Severity upgraded — blocks submission. |
220220
| CI-08 | **iOS `bundleIdentifier` not set** | 🔴 Critical | ✅ Resolved 2026-02-16: set `expo.ios.bundleIdentifier` to `com.lallimaven.eclipse-timer` with `buildNumber: "1"`. |
221221
| CI-09 | **Android package name is a placeholder** | 🔴 Critical | ✅ Resolved 2026-02-16: set `android.package` to `com.lallimaven.eclipsetimer` with `versionCode: 1`. |
@@ -248,7 +248,7 @@
248248
| A-01 | ✅ Resolved 2026-02-12: break up the 1 000-line `App.tsx` |
249249
| C-01 | ✅ Resolved 2026-02-13: fix cross-package deep import in overlay build |
250250
| CI-00 | ✅ Resolved 2026-02-16: created `eas.json` with development/preview/production build profiles |
251-
| CI-01 | Set up a CI pipeline |
251+
| CI-01 | ✅ Resolved 2026-02-16: created GitHub Actions CI workflow (`.github/workflows/ci.yml`) |
252252
| CI-08 | ✅ Resolved 2026-02-16: set iOS `bundleIdentifier` to `com.lallimaven.eclipse-timer` |
253253
| CI-09 | ✅ Resolved 2026-02-16: set Android package to `com.lallimaven.eclipsetimer` |
254254

@@ -269,7 +269,7 @@
269269
| F-01 | Multi-eclipse switching on timer |
270270
| F-02 | ✅ Resolved 2026-02-16: persist user preferences via AsyncStorage |
271271
| F-03 | ✅ Resolved 2026-02-16: implement real alarm scheduling |
272-
| CI-02 | Automate EAS Build jobs in CI for Android/iOS artifacts |
272+
| CI-02 | ✅ Resolved 2026-02-16: created EAS Build + Submit workflow (`.github/workflows/eas-build.yml`) |
273273
| CI-03 | Configure app signing / keystore (blocks store submission) |
274274
| CI-05 | ✅ Resolved 2026-02-16: integrated @sentry/react-native with Sentry.wrap + ErrorBoundary |
275275
| SP-02 | ✅ Resolved 2026-02-16: privacy policy written, store privacy declarations documented, iOS privacy manifest added |
@@ -309,7 +309,7 @@
309309
| AC-04 | Support dynamic font sizing |
310310
| SP-01 | ✅ Resolved 2026-02-16: added pre-permission rationale Alert dialog before location request |
311311
| CI-04 | Add env config support |
312-
| CI-06 | Configure `expo-updates` for OTA |
312+
| CI-06 | ✅ Resolved 2026-02-16: installed + configured `expo-updates` with runtimeVersion and EAS update URL |
313313
| CI-07 | ✅ Partially resolved 2026-02-16: store descriptions, content rating answers, and icon fix completed. Screenshots and feature graphic still needed (manual). |
314314
| CI-10 | ✅ Resolved 2026-02-16: added `expo-splash-screen` with preventAutoHideAsync/hideAsync |
315315
| CI-11 | ✅ Resolved 2026-02-16: bumped to `1.0.0` with `buildNumber: "1"` and `versionCode: 1` |
@@ -386,10 +386,10 @@
386386

387387
| # | Step | Relates To | Status |
388388
|---|------|-----------|--------|
389-
| 5.1 | **Create a GitHub Actions CI workflow** (`.github/workflows/ci.yml`) that runs on push/PR: `pnpm install``pnpm typecheck``pnpm lint``pnpm test`. | CI-01 | ⬜ Not started |
390-
| 5.2 | **Add an EAS Build workflow** (`.github/workflows/eas-build.yml`) triggered on `main` push or manual dispatch: runs `eas build --profile production --platform all --non-interactive`. | CI-02 | ⬜ Not started |
391-
| 5.3 | **Add an EAS Submit step**`eas submit --platform all` to automate upload to App Store Connect and Google Play Console. | CI-02 | ⬜ Not started |
392-
| 5.4 | **Set up `expo-updates`** for OTA JS bundle updates post-launch (avoids full store review for JS-only fixes). | CI-06 | ⬜ Not started |
389+
| 5.1 | **Create a GitHub Actions CI workflow** `.github/workflows/ci.yml` runs on push/PR to `main`: checkout → pnpm installtypecheck → lint → test. Includes concurrency grouping to cancel stale runs. | CI-01 | ✅ Done 2026-02-16 |
390+
| 5.2 | **Add an EAS Build workflow** `.github/workflows/eas-build.yml` triggers on `main` push (when `apps/mobile/`, `packages/`, or lockfile change) or manual dispatch. CI checks run first, then `eas build --profile production`. Platform selectable via `workflow_dispatch` input (default: `all`). Requires `EXPO_TOKEN` secret. | CI-02 | ✅ Done 2026-02-16 |
391+
| 5.3 | **Add an EAS Submit step**included as a gated `submit` job in `eas-build.yml`. Only runs on manual dispatch with `submit: true`. Uses `environment: production` for manual approval before store upload. Runs `eas submit --platform all --latest`. | CI-02 | ✅ Done 2026-02-16 |
392+
| 5.4 | **Set up `expo-updates`** — installed `expo-updates`, added `runtimeVersion: { policy: "appVersion" }` and `updates` config (URL, checkAutomatically ON_LOAD, fallbackToCacheTimeout 0) to `app.json`, added `expo-updates` plugin. | CI-06 | ✅ Done 2026-02-16 |
393393

394394
### Phase 6 — Nice-to-have before v1.0.0
395395

0 commit comments

Comments
 (0)