Skip to content

Commit 0773822

Browse files
maximcodingclaude
andcommitted
chore: improve CI/CD pipelines and tighten Biome config
- ci.yml: parallel lint/test jobs, concurrency cancel, coverage summary, dependency-review on PRs - android-ci.yml: tag v* trigger, Gradle cache, .env seeding, AAB/Sentry stubs - ios-ci.yml: tag v* trigger, CocoaPods cache, .env seeding, Sentry stub - biome.json: noDebugger/noFocusedTests → error; remove 3 dead overrides; relax noConsole in test files - docs/OPERATIONS.md, CHANGELOG.md: reflect all workflow changes Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 6ab686a commit 0773822

File tree

6 files changed

+122
-20
lines changed

6 files changed

+122
-20
lines changed

.github/workflows/android-ci.yml

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,16 @@
11
name: Android CI Build
22

3-
# Manual native release build (template). PR quality checks live in ci.yml.
3+
# Manual build or tag-triggered release build.
4+
# PR quality checks (lint, tests, type-check) live in ci.yml.
45
on:
56
workflow_dispatch:
7+
push:
8+
tags:
9+
- 'v*'
10+
11+
concurrency:
12+
group: android-${{ github.ref }}
13+
cancel-in-progress: true
614

715
jobs:
816
android-build:
@@ -27,12 +35,39 @@ jobs:
2735
distribution: 'temurin'
2836
java-version: 17
2937

38+
- name: Cache Gradle packages
39+
uses: actions/cache@v4
40+
with:
41+
path: |
42+
~/.gradle/caches
43+
~/.gradle/wrapper
44+
key: gradle-${{ hashFiles('android/gradle/wrapper/gradle-wrapper.properties', 'android/**/*.gradle*') }}
45+
restore-keys: gradle-
46+
3047
- name: Install Android SDK
3148
uses: android-actions/setup-android@v3
3249

33-
- name: Build Android Release
50+
- name: Seed .env for build
51+
run: cp .env.example .env
52+
53+
# Template uses the debug keystore. Replace with a real signing step
54+
# (e.g. decode a base64-encoded keystore from secrets) before store upload.
55+
- name: Build Android Release APK
3456
run: cd android && ./gradlew assembleRelease
3557

58+
# Uncomment for Play Store upload (requires signing + Google service account secret):
59+
# - name: Build Android Release Bundle (AAB)
60+
# run: cd android && ./gradlew bundleRelease
61+
62+
# Upload Sentry source maps if DSN is configured.
63+
# Uncomment and set SENTRY_AUTH_TOKEN + SENTRY_ORG + SENTRY_PROJECT secrets.
64+
# - name: Upload Sentry source maps
65+
# env:
66+
# SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
67+
# SENTRY_ORG: ${{ secrets.SENTRY_ORG }}
68+
# SENTRY_PROJECT: ${{ secrets.SENTRY_PROJECT }}
69+
# run: npx @sentry/cli releases files "${{ github.ref_name }}" upload-sourcemaps android/app/build
70+
3671
- name: Upload APK Artifact
3772
uses: actions/upload-artifact@v4
3873
with:

.github/workflows/ci.yml

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,14 @@ on:
66
pull_request:
77
branches: [master, main]
88

9+
# Cancel in-flight runs for the same PR / branch so stale runs don't queue up.
10+
concurrency:
11+
group: ci-${{ github.ref }}
12+
cancel-in-progress: true
13+
914
jobs:
10-
quality:
15+
lint:
16+
name: Lint & type-check
1117
runs-on: ubuntu-latest
1218
steps:
1319
- uses: actions/checkout@v4
@@ -26,11 +32,33 @@ jobs:
2632
- name: Typecheck
2733
run: npx tsc --noEmit
2834

35+
test:
36+
name: Tests & guards
37+
runs-on: ubuntu-latest
38+
steps:
39+
- uses: actions/checkout@v4
40+
41+
- uses: actions/setup-node@v4
42+
with:
43+
node-version: '20'
44+
cache: npm
45+
46+
- name: Install dependencies
47+
run: npm ci
48+
2949
- name: Unit tests
30-
run: npm test
50+
run: npm test -- --coverage --coverageReporters=text-summary
3151

3252
- name: Check icons registry
3353
run: npm run check:icons
3454

3555
- name: Check import paths
3656
run: npm run check:imports
57+
58+
dependency-review:
59+
name: Dependency review
60+
runs-on: ubuntu-latest
61+
if: github.event_name == 'pull_request'
62+
steps:
63+
- uses: actions/checkout@v4
64+
- uses: actions/dependency-review-action@v4

.github/workflows/ios-ci.yml

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,16 @@
11
name: iOS CI Build
22

3-
# Manual simulator build (no signing). PR quality checks live in ci.yml.
3+
# Manual build or tag-triggered release build.
4+
# PR quality checks (lint, tests, type-check) live in ci.yml.
45
on:
56
workflow_dispatch:
7+
push:
8+
tags:
9+
- 'v*'
10+
11+
concurrency:
12+
group: ios-${{ github.ref }}
13+
cancel-in-progress: true
614

715
jobs:
816
ios-build:
@@ -21,9 +29,23 @@ jobs:
2129
- name: Install dependencies
2230
run: npm ci
2331

32+
- name: Cache CocoaPods specs
33+
uses: actions/cache@v4
34+
with:
35+
path: ~/.cocoapods
36+
key: cocoapods-${{ hashFiles('ios/Podfile.lock') }}
37+
restore-keys: cocoapods-
38+
2439
- name: Install Pods
2540
run: cd ios && pod install
2641

42+
- name: Seed .env for build
43+
run: cp .env.example .env
44+
45+
# Simulator / CI build (no signing required).
46+
# For a real device/TestFlight build, switch to -configuration Release,
47+
# add code signing setup (e.g. Fastlane match or manual cert import),
48+
# and change -destination to 'generic/platform=iOS'.
2749
- name: Build iOS (Simulator)
2850
run: |
2951
cd ios
@@ -36,6 +58,15 @@ jobs:
3658
-derivedDataPath build \
3759
build
3860
61+
# Upload Sentry source maps if DSN is configured.
62+
# Uncomment and set SENTRY_AUTH_TOKEN + SENTRY_ORG + SENTRY_PROJECT secrets.
63+
# - name: Upload Sentry source maps
64+
# env:
65+
# SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
66+
# SENTRY_ORG: ${{ secrets.SENTRY_ORG }}
67+
# SENTRY_PROJECT: ${{ secrets.SENTRY_PROJECT }}
68+
# run: npx @sentry/cli releases files "${{ github.ref_name }}" upload-sourcemaps ios/build
69+
3970
- name: Upload Simulator app
4071
uses: actions/upload-artifact@v4
4172
with:

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,14 @@ All notable changes to this project will be documented in this file.
44

55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
66

7+
## [Unreleased]
8+
9+
### Changed
10+
- **CI (`ci.yml`):** split quality gate into two parallel jobs (`lint`: Biome + TypeScript; `test`: Jest with coverage summary + `check:icons` + `check:imports`); add `concurrency` group to cancel stale PR runs; add `dependency-review` job on pull requests.
11+
- **Android CI (`android-ci.yml`):** add `v*` tag trigger alongside `workflow_dispatch`; add Gradle cache (`~/.gradle`); seed `.env` from `.env.example` before build; add commented stubs for AAB (`bundleRelease`) and Sentry source map upload.
12+
- **iOS CI (`ios-ci.yml`):** add `v*` tag trigger alongside `workflow_dispatch`; add CocoaPods specs cache (`~/.cocoapods`); seed `.env` from `.env.example` before build; add commented stub for Sentry source map upload.
13+
- **`docs/OPERATIONS.md`:** update GitHub Actions table and notes to reflect parallel jobs, caching, tag triggers, and Sentry upload stubs.
14+
715
## [1.0.0] - 2026-03-23
816

917
- Align **react-native-nitro-modules** with **react-native-mmkv** (pin mmkv 4.3.0 + nitro 0.35.0) to fix Android Kotlin compile (`CxxPart` / Nitrogen skew); **`package.json` `overrides`** pins nitro 0.35.0; refresh [`ios/Podfile.lock`](ios/Podfile.lock) (MMKVCore 2.4.0). Doc: [docs/development.md#react-native-mmkv-and-react-native-nitro-modules](docs/development.md#react-native-mmkv-and-react-native-nitro-modules).

biome.json

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -69,14 +69,14 @@
6969
"noConfusingLabels": "warn",
7070
"noConsole": "off",
7171
"noControlCharactersInRegex": "warn",
72-
"noDebugger": "warn",
72+
"noDebugger": "error",
7373
"noDoubleEquals": "warn",
7474
"noDuplicateClassMembers": "error",
7575
"noDuplicateJsxProps": "error",
7676
"noDuplicateObjectKeys": "error",
7777
"noEmptyBlockStatements": "off",
7878
"noFallthroughSwitchClause": "warn",
79-
"noFocusedTests": "warn",
79+
"noFocusedTests": "error",
8080
"noFunctionAssign": "warn",
8181
"noGlobalAssign": "error",
8282
"noLabelVar": "warn",
@@ -135,12 +135,6 @@
135135
}
136136
},
137137
"overrides": [
138-
{ "includes": ["*.js"], "linter": { "rules": {} } },
139-
{ "includes": ["*.jsx"] },
140-
{
141-
"includes": ["*.js", "*.jsx", "*.ts", "*.tsx"],
142-
"linter": { "rules": {} }
143-
},
144138
{
145139
"includes": ["*.ts", "*.tsx"],
146140
"linter": {
@@ -157,7 +151,11 @@
157151
"*.{spec,test}.{js,ts,tsx}",
158152
"**/__{mocks,tests}__/**/*.{js,ts,tsx}"
159153
],
160-
"linter": { "rules": {} }
154+
"linter": {
155+
"rules": {
156+
"suspicious": { "noConsole": "off" }
157+
}
158+
}
161159
}
162160
],
163161
"assist": {

docs/OPERATIONS.md

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -67,24 +67,26 @@ Add YAML flows under `maestro/` and keep them deterministic (seed data, locale,
6767

6868
| File | Trigger | Purpose |
6969
|------|---------|---------|
70-
| [`.github/workflows/ci.yml`](../.github/workflows/ci.yml) | Push / PR to `master` or `main` | **Quality gate:** Biome, TypeScript, Jest, `check:icons`, `check:imports` (Node 20, `npm ci`). |
71-
| [`.github/workflows/android-ci.yml`](../.github/workflows/android-ci.yml) | Manual (`workflow_dispatch`) | **Android:** JDK 17, Android SDK, `assembleRelease` (uses debug keystore in template `build.gradle`). |
72-
| [`.github/workflows/ios-ci.yml`](../.github/workflows/ios-ci.yml) | Manual (`workflow_dispatch`) | **iOS:** CocoaPods, **simulator** `xcodebuild` for `ReactNativeStarter` scheme (no device signing). |
70+
| [`.github/workflows/ci.yml`](../.github/workflows/ci.yml) | Push / PR to `master` or `main` | **Quality gate** (two parallel jobs): `lint`Biome + TypeScript; `test`Jest (with coverage summary) + `check:icons` + `check:imports`. Plus a `dependency-review` job on PRs. Stale runs cancelled via `concurrency`. |
71+
| [`.github/workflows/android-ci.yml`](../.github/workflows/android-ci.yml) | Manual (`workflow_dispatch`) or tag `v*` push | **Android:** JDK 17, Android SDK, Gradle cache, `.env` seeded from `.env.example`, `assembleRelease` (debug keystore — replace with real signing before store upload). Commented stubs for AAB (`bundleRelease`) and Sentry source map upload. |
72+
| [`.github/workflows/ios-ci.yml`](../.github/workflows/ios-ci.yml) | Manual (`workflow_dispatch`) or tag `v*` push | **iOS:** CocoaPods (with specs cache), `.env` seeded from `.env.example`, **simulator** `xcodebuild` for `ReactNativeStarter` scheme (no device signing). Commented stub for Sentry source map upload. |
7373

7474
### Notes
7575

76-
- **Release / Play / TestFlight** automation is not included; add Fastlane or your own jobs when you have signing secrets.
76+
- **Release / Play / TestFlight** automation is not included; add Fastlane or your own jobs when you have signing secrets. Commented stubs in each native workflow show where to add signing and upload steps.
77+
- Native workflows trigger automatically on `v*` tags (e.g. `v1.2.0`) in addition to `workflow_dispatch`.
7778
- Align **Node** with `package.json` `engines` (>= 20) across all workflows.
7879
- After renaming the app in Xcode / Gradle, update **workspace**, **scheme**, and **artifact paths** in the iOS workflow.
80+
- **Sentry source maps:** uncomment the upload step in both native workflows and set `SENTRY_AUTH_TOKEN`, `SENTRY_ORG`, `SENTRY_PROJECT` as repository secrets.
7981

8082
### Optional consolidation
8183

82-
You can delete `android-ci.yml` / `ios-ci.yml` if you only want PR checks (`ci.yml`), or merge native builds into a single file with a matrixkeep one source of truth for Node version and install steps.
84+
You can delete `android-ci.yml` / `ios-ci.yml` if you only want PR checks (`ci.yml`), or merge native builds into a single file with a matrixkeep one source of truth for Node version and install steps.
8385

8486
### Feature branches and store automation
8587

8688
- Run the same checks locally as **`ci.yml`** before push; CI runs them on push/PR to `main` / `master`.
87-
- **Store release automation** (tag-triggered builds, Google Play / TestFlight upload) is **not** in this template. Manual Android/iOS workflows produce artifacts only; add Fastlane or custom workflows when you need uploads.
89+
- **Store release automation** (Google Play / TestFlight upload) is not included. Native workflows produce artifacts on tag push; add Fastlane `supply` / `pilot` lanes and the corresponding repository secrets (`GOOGLE_SERVICE_ACCOUNT_JSON`, `APP_STORE_CONNECT_API_KEY_JSON`) when you need automated uploads.
8890

8991
## Android: native clean and CMake (`codegen/jni`)
9092

0 commit comments

Comments
 (0)