Skip to content

fix(ci): install the pinned Android SDK CMake in the release build - #1113

Merged
FelipePSoares merged 2 commits into
masterfrom
install-pinned-android-cmake
Oct 31, 2026
Merged

FelipePSoares merged 2 commits into
masterfrom
install-pinned-android-cmake

Conversation

@FelipePSoares

@FelipePSoares FelipePSoares commented Oct 31, 2026 •

Copy link
Copy Markdown
Owner

Problem

The release pipeline failed on master in the Release workflow, job android-build, step Build standalone release APK (run 41234254542):

> Task :app:configureCMakeRelWithDebInfo[arm64-v8a] FAILED
> Task :react-native-screens:configureCMakeRelWithDebInfo[arm64-v8a] FAILED
[CXX1300] CMake '3.30.4' was not found in SDK, PATH, or by cmake.dir property.

Root cause

The build pins the CMake version through android.cmakeVersion (written by plugins/with-detox-android.js into the generated gradle.properties). That is not a preference: Expo's ExpoRootProjectPlugin assigns it to every module —

android.externalNativeBuild.cmake.version = cmakeVersion

— so AGP looks for exactly cmake/3.30.4 in the SDK. The ubuntu-latest runner image only ships SDK CMake 3.31.5, and the job never ran sdkmanager, so configureCMakeRelWithDebInfo failed for the app and for react-native-screens.

Fix

1. The release workflow installs the pinned CMake (.github/workflows/Release.yml): a new step between expo prebuild and the Gradle build —

  • reads the version from the generated gradle.properties, which exists by then, instead of repeating it;
  • fails with an explicit error if the pin ever disappears, rather than at compile time;
  • installs cmake;<version> via sdkmanager;
  • asserts the install landed (test -x …/bin/cmake) and prints cmake --version.

2. The pin gets a tracked source of truth (econoflow-mobile/app.json): the version now lives in app.json as the cmakeVersion argument of ./plugins/with-detox-android, and the plugin writes it into gradle.properties (keeping 3.30.4 as its default). android/ is gitignored and regenerated by expo prebuild, so a policy test reading gradle.properties alone is green locally and red on a fresh checkout — this puts the value somewhere a test and a reviewer can see it.

Tests

scripts/cra-compliance.test.mjs — the release workflow installs the CMake version the Android build is pinned to — asserts the pin at its source (app.json), that the workflow runs sdkmanager, reads android.cmakeVersion, and installs "cmake;${CMAKE_VERSION}".

It was red before the change, for the same reason CI failed:

  • before commit 1: .github/workflows/Release.yml never runs sdkmanager…
  • before commit 2: app.json no longer runs ./plugins/with-detox-android…

Verification

Check Result
node scripts/cra-compliance.test.mjs 31 pass / 0 fail
node scripts/npm-override-freshness.test.mjs 53 pass / 0 fail
cd econoflow-mobile && npm test 91 suites / 1023 tests pass
npm run typecheck / npm run lint clean
npx expo config --type prebuild valid

No backend or frontend code touched.

FelipePSoares added 2 commits October 31, 2026 20:53
The master release build failed in `Build standalone release APK` with

  [CXX1300] CMake '3.30.4' was not found in SDK, PATH, or by cmake.dir property.

`econoflow-mobile/android/gradle.properties` pins `android.cmakeVersion=3.30.4`
and Expo's root project plugin assigns it straight to
`externalNativeBuild.cmake.version` on every module, so AGP requires exactly
that CMake. The ubuntu-latest image only ships SDK CMake 3.31.5, and the job
installed nothing, so `configureCMakeRelWithDebInfo` failed for the app and for
react-native-screens.

Release.yml now installs the pinned version via sdkmanager before Gradle runs,
reading the version from gradle.properties so the two cannot drift, and fails
early (instead of at compile time) if the pin ever disappears.

cra-compliance.test.mjs gains a policy test asserting that the pin still exists
and that the release workflow installs exactly that SDK CMake version; it was
red before the workflow change.
The version the release build must install was only recorded in
`econoflow-mobile/android/gradle.properties`, which is gitignored: `android/` is
regenerated by `expo prebuild`, so the value lives there but its source of
truth did not, and a policy test reading it passes locally and fails on a
fresh checkout.

`app.json` now passes `cmakeVersion` to `./plugins/with-detox-android`, and the
plugin writes it into the generated gradle.properties (defaulting to the
previous 3.30.4 when the argument is absent, so a bare plugin entry keeps
working). The release workflow keeps reading the generated file after prebuild,
and `scripts/cra-compliance.test.mjs` asserts the pin at its source in app.json.

setup.md records that the pin now comes from app.json.
@FelipePSoares
FelipePSoares force-pushed the install-pinned-android-cmake branch from 8cbb810 to a32b507 Compare October 31, 2026 19:57
@FelipePSoares
FelipePSoares merged commit 43c987c into master Oct 31, 2026
9 checks passed
@FelipePSoares
FelipePSoares deleted the install-pinned-android-cmake branch October 31, 2026 20:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant