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 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