Skip to content

[SDK-790] ci: run CI on master and run Android bridge unit tests - #919

Merged
joaodordio merged 9 commits into
masterfrom
chore/SDK-790-ci-trigger-master
Oct 9, 2026
Merged

joaodordio merged 9 commits into
masterfrom
chore/SDK-790-ci-trigger-master

Conversation

@joaodordio

@joaodordio joaodordio commented Oct 8, 2026 •

Copy link
Copy Markdown
Member

📝 Summary

Make ci.yml run on master (it has never run) and run the Android bridge unit tests on every PR.

🎟️ Jira Ticket: SDK-790

📖 Description

ci.yml triggered on main, but this repo's default branch is master. The workflow has 0 runs since the Sept 2024 scaffold (a5677631), so lint, typecheck, circular check, build-library, build-android and build-ios have never gated a PR. That is how 3.2.0 shipped an Android module that does not compile (fixed in #918).

  • ci.yml: main to master for push and pull_request.
  • unit-test.yml: new Android bridge unit tests job running :iterable_react-native-sdk:testDebugUnitTest (JDK 17, same setup steps as build-android).
  • CONTRIBUTING.md: how to run JS and Android bridge tests locally.

Stacked on #918. This branch is cut from #918 so build-android and the new test job can pass. Until #918 merges the diff here includes its two commits; it shrinks to the three files above once #918 lands.

This is the first time ci.yml will ever run, so any jobs that fail on this PR are existing breakage that was never visible. I'll fix them in follow-up commits here or call them out.

Repo settings follow-up (needs an admin): master has no required status checks (required_status_checks.contexts is []). After this is green, mark build-android, build-ios, lint and Android bridge unit tests as required.

🧪 How to test?

CI on this PR is the test: the CI workflow should appear in the checks for the first time.

🧾 Changelog

No customer facing changes

… compiles against native 3.10.1

The published iterableapi 3.10.1 AAR is compiled with Kotlin 1.9 without jvm-default,
so onEmbeddedMessagingSyncSucceeded and onEmbeddedMessagingSyncFailed are abstract
to Java implementers. RNIterableAPIModuleImpl did not override them, so the module
failed javac. Add no-op overrides that match the native defaults.
Iterable.inAppManager.showMessage called IterableInAppManager.showMessage on the React
Native native-modules thread. Since native Android 3.9.0, a host activity that is not a
FragmentActivity takes the Dialog path, whose LifecycleRegistry.addObserver call throws
IllegalStateException off the main thread and kills the process.

- Post the native call with UiThreadUtil.runOnUiThread, matching setAutoDisplayPaused
  and the native iOS SDK.
- Reject when the message id is missing instead of passing null into native (NPE).
- Resolve null when the message is dismissed without a URL instead of NPE on toString.
- Fix the empty messageId check, which used reference equality.

Adds the first JVM unit tests for the Android bridge (Robolectric + Mockito, versions
mirrored from iterable-android-sdk) and excludes them from the npm package.
ci.yml triggered on main while the default branch is master, so it has never run.
Add a job that runs the Android bridge JVM tests on every PR.
@joaodordio
joaodordio requested a review from a team as a code owner October 8, 2026 17:12
Comment thread .github/workflows/unit-test.yml Fixed
@qltysh

qltysh Bot commented Oct 8, 2026 •

Copy link
Copy Markdown

All good ✅

@github-actions

github-actions Bot commented Oct 8, 2026 •

Copy link
Copy Markdown
Lines Statements Branches Functions
Coverage: 72%
71.92% (579/805) 61.22% (229/374) 67.18% (174/259)

@qltysh

qltysh Bot commented Oct 8, 2026

Copy link
Copy Markdown

Qlty


Coverage Impact

This PR will not change total coverage.

🚦 See full report on Qlty Cloud »

🛟 Help
  • Diff Coverage: Coverage for added or modified lines of code (excludes deleted files). Learn more.

  • Total Coverage: Coverage for the whole repository, calculated as the sum of all File Coverage. Learn more.

  • File Coverage: Covered Lines divided by Covered Lines plus Missed Lines. (Excludes non-executable lines including blank lines and comments.)

    • Indirect Changes: Changes to File Coverage for files that were not modified in this PR. Learn more.

…yarn

React Native 0.85 requires Xcode 16.1+, macos-14 ships 15.4. Mirror the CodeQL Swift job.
Run the Android bridge tests via an example script so autolinking finds the RN CLI.
Comment on lines +54 to +84
name: Android bridge unit tests
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3

- name: Setup
uses: ./.github/actions/setup

- name: Install JDK
uses: actions/setup-java@v3
with:
distribution: 'zulu'
java-version: '17'

- name: Finalize Android SDK
run: |
/bin/bash -c "yes | $ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager --licenses > /dev/null"

- name: Cache Gradle
uses: actions/cache@v3
with:
path: |
~/.gradle/wrapper
~/.gradle/caches
key: ${{ runner.os }}-gradle-${{ hashFiles('example/android/gradle/wrapper/gradle-wrapper.properties') }}
restore-keys: |
${{ runner.os }}-gradle-

- name: Run Android bridge unit tests
run: yarn example test:android
…cache

The tasks run in the example workspace, so inputs resolve relative to example/ and
directory names without ** match no files. The cache only hashed example/package.json and
example/src, so SDK android/ and ios/ changes would hit the cache and skip native builds.
Also hash android/build.gradle into the Gradle cache key for the bridge test job.
@joaodordio

Copy link
Copy Markdown
Member Author

Review follow-up: fixed turbo.json inputs. The native build tasks run in the example workspace, so the old inputs resolved relative to example/ and bare directory names matched no files. The turbo hash only covered example/package.json and example/src/*, which means once a cache existed, SDK android/ and ios/ changes would hit the cache and skip build-android / build-ios. Inputs now point at ../android/**, ../ios/**, ../*.podspec, ../.github/workflows/ci.yml (pins Xcode/JDK) and the example native dirs, with build outputs excluded. Verified with yarn turbo run build:android --dry=json (46 files) and build:ios (37 files). Also added android/build.gradle to the Gradle cache key of the bridge test job so new test dependencies get cached.

The CocoaPods cache restores Pods but not the codegen output in ios/build/generated, so
skipping pod install on a cache hit left ReactAppDependencyProvider missing.
@joaodordio

Copy link
Copy Markdown
Member Author

Second latent CI bug, surfaced on the run after the turbo fix: build-ios skipped pod install whenever the CocoaPods cache hit. That cache restores Pods/ but not the codegen output in example/ios/build/generated, so the RN CLI's own pod install failed with No podspec found for ReactAppDependencyProvider. The first green run only passed because the cache was empty. pod install now always runs (fast with cached Pods). Reproduced locally and verified on CI with a CocoaPods cache hit: all checks green.

@joaodordio joaodordio mentioned this pull request Oct 9, 2026
8 tasks done

@jferrao-itrbl jferrao-itrbl left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Branch protection on master: a red build still does not block merge

What the code does: .github/workflows/ci.yml runs on master, and the new Android test job is in .github/workflows/unit-test.yml. Branch protection for master still has required_status_checks.contexts: [] and checks: [].

What the spec says: SDK-790 says that when CI runs on a change that breaks Android compilation, the pull request is blocked, and the required checks on master include the Android and iOS builds.

Why it conflicts: The jobs run and can go red. Merge is still allowed. The pull request describes this as an admin follow-up, so the criterion is unchanged since the last review.

Suggested action: An admin marks build-android, build-ios, and Android bridge unit tests required on master before SDK-790 is closed. lint already covers typecheck.

Comment thread turbo.json Outdated
Comment on lines +10 to +14
"!../android/build/**",
"!../android/.gradle/**",
"!../android/.cxx/**",
"../src/*.ts",
"../src/*.tsx",

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nested library sources and the example app are still outside the cache hash
Also in ~L31–32

What the code does: build:android and build:ios hash ../src/*.ts and ../src/*.tsx only, one directory deep. A dry run includes ../src/index.tsx and excludes ../src/api/NativeRNIterableAPI.ts and ../src/core/classes/Iterable.ts. The same edit removed the example-package src/*.ts and src/*.tsx inputs, so example/src/index.tsx and example/src/NativeJwtTokenModule.ts are no longer hashed either.

What the spec says: A change that breaks Android compilation must fail CI. The example build is the compile gate for that.

Why it conflicts: Native android/** and ios/** now bust the cache, so the 3.2.0 javac failure would miss and rebuild. A change under src/ that breaks codegen, or a change under example/src that breaks the example bundle, still hashes the same and build-android / build-ios can replay a hit.

Suggested action: Hash the library source tree that codegen compiles, and hash the example app sources the example build compiles. Confirm with a dry run that src/api/NativeRNIterableAPI.ts and example/src/index.tsx show up as inputs.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 014eced. Both tasks now hash ../src/**/*.ts(x) and the example's src/**/*.ts(x), index.js, app.json and react-native.config.js (autolinking). Dry run confirms ../src/api/NativeRNIterableAPI.ts (codegen jsSrcsDir), ../src/core/classes/Iterable.ts, src/index.tsx and src/NativeJwtTokenModule.ts are inputs for both build:android (232 files) and build:ios (223 files), with no build/Pods/.gradle/.cxx outputs.

Inputs only covered src/*.ts one level deep and dropped example/src, so codegen spec or
example app changes could replay a cached native build. Hash src/** for the library and
the example, plus the example entry points and autolinking config.
@joaodordio

Copy link
Copy Markdown
Member Author

@jferrao-itrbl on branch protection: agreed it has to happen before SDK-790 closes, and I have admin to do it. I'm sequencing it rather than doing it now: until this PR merges, ci.yml doesn't run on any other PR (it triggers on main on master), so making build-android, build-ios and Android bridge unit tests required today would leave every open PR, including the 3.2.1 release (#917), waiting on checks that never report. Plan: ship 3.2.1, merge this, then immediately mark those three checks required on master (keeping strict and the 1-approval rule) and note it on SDK-790. Open PRs will need a master merge to pick up the new trigger.

@jferrao-itrbl
jferrao-itrbl self-requested a review October 9, 2026 18:16
@joaodordio
joaodordio merged commit fd3d16b into master Oct 9, 2026
22 checks passed
@joaodordio
joaodordio deleted the chore/SDK-790-ci-trigger-master branch October 9, 2026 18:17
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.

3 participants