From 9eccc66f9d2af797408324098d34c149fc6ea499 Mon Sep 17 00:00:00 2001 From: alichherawalla Date: Fri, 24 Jul 2026 20:42:47 +0530 Subject: [PATCH 1/2] =?UTF-8?q?chore(ci):=20drop=20android-build=20job=20?= =?UTF-8?q?=E2=80=94=20run=20the=20Android=20build=20locally=20instead?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The hosted android-build runner repeatedly hung for 3+ hours on the native C++ builds (react-native-audio-api, op-sqlite) and burned hours per PR. Move it to a LOCAL pre-merge gate: `cd android && ./gradlew assembleDebug assembleRelease` before merging any native/ Android/gradle/deps change (recorded in rules.md). JS-only / docs PRs don't need it. --- .github/workflows/ci.yml | 41 +++++----------------------------------- 1 file changed, 5 insertions(+), 36 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 23ef03bdb..0b6ac8dd5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -200,42 +200,11 @@ jobs: path: android/app/build/reports/tests/ if-no-files-found: ignore - android-build: - runs-on: ubuntu-latest - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: '22' - cache: 'npm' - - - name: Setup Java - uses: actions/setup-java@v4 - with: - distribution: 'temurin' - java-version: '17' - - - name: Free disk space - # The native C++ builds (react-native-audio-api, op-sqlite) exhausted the runner - # disk ("LLVM ERROR: IO failure on output stream: No space left on device"). - # Reclaim large preinstalled toolchains we don't use; keep the Android SDK/NDK. - run: | - sudo rm -rf /usr/share/dotnet /opt/ghc /usr/local/.ghcup /opt/hostedtoolcache/CodeQL || true - sudo docker image prune --all --force || true - df -h - - - name: Install dependencies - run: npm ci - - - name: Build Android Debug - run: cd android && ./gradlew assembleDebug - - - name: Build Android Release - run: cd android && ./gradlew assembleRelease + # NOTE: the Android build is NOT run in CI — it is a LOCAL pre-merge gate instead (the hosted + # runner repeatedly hung for 3+ hours on the native C++ builds and burned hours). Run it locally + # before merging any change that touches native/Android/gradle/deps: + # cd android && ./gradlew assembleDebug assembleRelease + # (see rules.md → On-device testing & verification). Docs-only / JS-only PRs don't need it. # NOTE: SonarCloud runs via Automatic Analysis (SonarCloud-side, on the public core project) — # no CI job. A CI scan would only add coverage import, which Codecov (in the `test` job) already From 71b3cee1b99c9c04739d21512b398a8b6869b157 Mon Sep 17 00:00:00 2001 From: alichherawalla Date: Fri, 24 Jul 2026 20:53:12 +0530 Subject: [PATCH 2/2] chore(hooks): run Android + iOS native builds on pre-push (local gate) Replaces the removed CI android-build with a LOCAL pre-push gate, and adds the iOS build too: - Android: `assembleDebug assembleRelease` when .kt/.kts, android/, or package*.json change. - iOS: simulator build (CODE_SIGNING_ALLOWED=NO) when .swift, ios/, or Podfile change. JS-only / docs pushes skip both and stay fast. --- .husky/pre-push | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/.husky/pre-push b/.husky/pre-push index 804c2a5c3..4836ba753 100755 --- a/.husky/pre-push +++ b/.husky/pre-push @@ -40,6 +40,12 @@ PUSHED_JS=$(printf '%s\n' "$CHANGED_FILES" | grep -E '\.(ts|tsx|js|jsx)$' || tru PUSHED_SWIFT=$(printf '%s\n' "$CHANGED_FILES" | grep '\.swift$' | grep -v 'Pods/' | grep -v 'build/' || true) PUSHED_KOTLIN=$(printf '%s\n' "$CHANGED_FILES" | grep -E '\.(kt|kts)$' || true) +# Native BUILD gate — moved OUT of CI (the hosted android-build runner hung for 3+ hours on the +# native C++ builds). Run the full native builds LOCALLY on push when native / gradle / pods / deps +# change. JS-only and docs-only pushes skip these (they stay fast). +PUSHED_ANDROID_NATIVE=$(printf '%s\n' "$CHANGED_FILES" | grep -E '\.(kt|kts)$|^android/|^package(-lock)?\.json$' | grep -v '/build/' || true) +PUSHED_IOS_NATIVE=$(printf '%s\n' "$CHANGED_FILES" | grep -E '\.swift$|^ios/|Podfile' | grep -v 'Pods/' | grep -v '/build/' || true) + if [ -n "$PUSHED_JS" ]; then echo "▶ JS/TS lint (push range)..." echo "$PUSHED_JS" | tr '\n' '\0' | xargs -0 eslint --max-warnings=999 @@ -83,6 +89,24 @@ if [ -n "$PUSHED_KOTLIN" ]; then npm run test:android fi +if [ -n "$PUSHED_ANDROID_NATIVE" ]; then + echo "▶ Android build (assembleDebug + assembleRelease) — local gate, replaces CI android-build..." + (cd android && ./gradlew assembleDebug assembleRelease) +fi + +if [ -n "$PUSHED_IOS_NATIVE" ]; then + echo "▶ iOS build (simulator, no code-signing) — local gate..." + (cd ios && xcodebuild \ + -workspace OffgridMobile.xcworkspace \ + -scheme OffgridMobile \ + -configuration Debug \ + -sdk iphonesimulator \ + -destination 'generic/platform=iOS Simulator' \ + -derivedDataPath build/prepush-ios \ + CODE_SIGNING_ALLOWED=NO \ + build) +fi + if [ -n "$PUSHED_JS$PUSHED_SWIFT$PUSHED_KOTLIN" ]; then echo "▶ Sonar scan..." npm run sonar