Skip to content

ci: report binary compatibility against the last published release - #849

Open
nickolas-dimitrakas wants to merge 1 commit into
mainfrom
ci/binary-compat-report
Open

nickolas-dimitrakas wants to merge 1 commit into
mainfrom
ci/binary-compat-report

Conversation

@nickolas-dimitrakas

Copy link
Copy Markdown
Contributor

Summary

Adds a CI job, Binary Compatibility, that compares the release artifacts of android-core and android-kit-base against the most recent version published to Maven Central and fails on any binary- or source-incompatible change.

  • scripts/api_compat_report.py builds both release AARs, extracts classes.jar from each, downloads the same artifact at the latest published version (verified against its published checksum), and runs japicmp 0.26.2 (pinned by version and SHA-256). Additions are reported but do not fail the run.
  • android-core ships R8-minified, so R8-renamed symbols are excluded before the verdict is computed. Classes whose simple name, or any nested-class segment of it, is R8-shaped (a, b1, MParticle$a, Outer$1) are dropped from both jars. Members are filtered only on evidence: the release build's R8 mapping file identifies the classes that a keep rule names only partially (today ConfigManager, MParticleIdentityClientImpl and the Kotlin access$ synthetics of InternalListenerManager), and only inside those classes are R8-shaped member names ignored. Every member of a fully kept class is compared by its real name, so removing a short-named public field such as MPUtility.AdIdInfo.id is reported.
  • scripts/test_api_compat_report.py (standard-library unittest) covers the class filter, the mapping parser and the report evaluation; CI runs it before the comparison.
  • HTML and XML reports are uploaded as the api-compat-reports workflow artifact; a one-line result goes to the job summary.
  • Documents the script and job in AGENTS.md.

The job is deliberately not in the required-check set. It runs on every pull request and on pushes to main.

Why

./gradlew apiCheck (#843) guards the compiled surface before R8. What consumers link against is the post-R8 artifact, in which only the classes android-core/proguard.pro keeps survive under their own names. This job is the check on the artifact that ships, and it also sees throws clauses and nullability annotations. japicmp runs with --ignore-missing-classes and no external classpath, so changes that only manifest through unresolved external supertypes are left to the compile-time dump.

Verification

  • Unit tests: 8 passing.
  • Local release AARs against 6.1.2 from Maven Central: android-core 115 named classes compared (180 R8-renamed dropped on each side), android-kit-base 44 compared; no changes.
  • android-core against 6.0.0: compatible; five classes with additions only. The R8-renamed members that a name-shape filter would have mis-reported are correctly ignored.
  • Synthetic check: removing AttributionError from the local AAR reports CLASS_REMOVED and each of its members, exit code 2.

🤖 Generated with Claude Code

@github-actions

github-actions Bot commented Sep 24, 2026 •

Copy link
Copy Markdown

📦 SDK Size Impact Report

What the SDK adds to a minified release APK.

Measured against an empty baseline app. Unlike the Rokt kit, android-core ships no Compose and no resources, so there is nothing here that a host app would already provide.

mParticle Core SDK

Metric Target branch This PR Change
APK size 119.78 KB 119.79 KB +1 bytes
Download size 117.60 KB 117.60 KB +1 bytes
Dex bytes 213.75 KB 213.75 KB 0 bytes

➡️ SDK size impact change is minimal.

Raw measurements

Target branch:

{"baseline_dex_bytes": 0, "baseline_download_bytes": 2513, "baseline_install_bytes": 7528, "core_dex_bytes": 218884, "core_download_bytes": 122935, "core_install_bytes": 130187}

This PR:

{"baseline_dex_bytes": 0, "baseline_download_bytes": 2515, "baseline_install_bytes": 7531, "core_dex_bytes": 218884, "core_download_bytes": 122938, "core_install_bytes": 130191}

Measured b620b9b merged into 49124e4

@nickolas-dimitrakas
nickolas-dimitrakas changed the base branch from main to build/api-dump-bcv September 24, 2026 04:48
@nickolas-dimitrakas
nickolas-dimitrakas added this pull request to stack #851 September 24, 2026 05:47
@nickolas-dimitrakas nickolas-dimitrakas self-assigned this Sep 24, 2026
@nickolas-dimitrakas
nickolas-dimitrakas marked this pull request as ready for review October 6, 2026 18:21
@nickolas-dimitrakas
nickolas-dimitrakas requested a review from a team as a code owner October 6, 2026 18:21
@cursor

cursor Bot commented Oct 6, 2026 •

Copy link
Copy Markdown

PR Summary

Low Risk
Changes are restricted to CI workflow configuration, build scripts, and documentation without affecting production runtime code.

Overview
Adds a binary compatibility check to the CI pipeline to compare android-core and android-kit-base release AARs against the latest release on Maven Central using japicmp.

The change introduces scripts/api_compat_report.py along with unit tests in scripts/test_api_compat_report.py. The script downloads the latest published AARs, builds the local release AARs, filters out R8-obfuscated classes and members based on mapping metadata, and evaluates binary and source compatibility. A new binary-compatibility workflow job is added to .github/workflows/pull-request.yml to run the tests and archive HTML/XML compatibility reports.

Reviewed by Cursor Bugbot for commit b620b9b. Bugbot is set up for automated code reviews on this repo. Configure here.

@nickolas-dimitrakas
nickolas-dimitrakas force-pushed the ci/binary-compat-report branch 2 times, most recently from 4732c7e to 32bbfbf Compare October 6, 2026 20:43

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 32bbfbf. Configure here.

distribution: "zulu"
java-version: "17"
- name: "Setup Gradle"
uses: gradle/actions/setup-gradle@9c971963bec38e04b3d30dcc455b5382be2fdbfb # v6.3.0

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Gradle setup action pinned to older version

Low Severity

The new binary-compatibility job pins gradle/actions/setup-gradle to v6.3.0 (@9c971963b...), while every other job in this file and across all other workflow files consistently uses v6.4.0 (@3f5f9adaf...). This version inconsistency could lead to different Gradle caching behavior or miss bug fixes present in the version the rest of the CI relies on.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 32bbfbf. Configure here.

@nickolas-dimitrakas
nickolas-dimitrakas force-pushed the ci/binary-compat-report branch 2 times, most recently from 5f9abed to 81d306f Compare October 6, 2026 21:31
- name: "Test the comparison script"
run: python3 -m unittest scripts/test_api_compat_report.py
- name: "Compare release artifacts with the last published release"
run: python3 scripts/api_compat_report.py --output-dir build/api-compat

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.

Would it fail the build if the compatibility is not matched?

Base automatically changed from build/api-dump-bcv to main October 6, 2026 21:50
Adds a Binary Compatibility job that builds the release AARs of android-core
and android-kit-base, downloads the same artifacts at the latest version on
Maven Central, and runs japicmp over them. android-core ships R8-minified, so
R8-renamed classes are dropped from both sides and, inside the few classes the
R8 mapping file shows to be only partially kept, R8-renamed members are
ignored; every member of a fully kept class is compared by its real name. Any
remaining binary- or source-incompatible change fails the job. The job is not
in the required-check set.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
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.

2 participants