Skip to content

[DRAFT] Add Metalava API signature generation and compatibility tracking#1616

Draft
rahul-lohra wants to merge 2 commits intodevelopfrom
claude/stupefied-murdock
Draft

[DRAFT] Add Metalava API signature generation and compatibility tracking#1616
rahul-lohra wants to merge 2 commits intodevelopfrom
claude/stupefied-murdock

Conversation

@rahul-lohra
Copy link
Contributor

STILL IN DRAFT, CI PPL IS NOT TESTED

Goal

Add automated public API surface tracking using Metalava to detect breaking API changes before they reach develop. This gives us a Java/Android-aware API signature file (api/current.txt) per module — complementing the existing binary-compatibility-validator .api files.

Implementation

Convention Plugin (io.getstream.video.android.metalava)

All metalava setup is encapsulated in a reusable convention plugin inside build-logic/. This keeps module build files minimal and makes it easy to share across repos.

Files added:

  • build-logic/convention/src/main/kotlin/MetalavaConventionPlugin.kt — Plugin entry point
  • build-logic/convention/src/main/kotlin/io/getstream/video/MetalavaSetup.kt — Shared configuration logic

What the convention plugin does automatically:

  • Applies the me.tylerbwong.gradle.metalava plugin (v0.5.0)
  • Outputs API signature to api/current.txt
  • Suppresses known lint issues for internal API references (ReferencesHidden, HiddenTypeParameter, UnavailableSymbol, IoError)
  • Hooks metalavaGenerateSignatureRelease into apiDump so both files are generated together
  • Respects metalava.enabled Gradle property for toggling on/off

CI Workflow (.github/workflows/api-compatibility-check.yml)

Runs on PRs to develop/main:

  1. Checks API compatibility against committed api/current.txt
  2. If breaking changes detected → generates a diff in the Job Summary
  3. Blocks merge unless the approved-api-change label is added
  4. Re-triggers automatically when the label is added

How to Integrate Into a Module

Simple module (no customization needed) — 1 line:

plugins {
    id("io.getstream.video.android.library")
    id("io.getstream.video.android.metalava")  // ← add this
}

Module with hidden annotations (e.g., internal APIs):

plugins {
    id("io.getstream.video.android.library")
    id("io.getstream.video.android.metalava")
}

metalava {
    hiddenAnnotations.set(
        setOf("com.example.internal.InternalApi"),
    )
}

Available Gradle Tasks

Task Description
apiDump img
Task Description
apiDump Generates both .api and api/current.txt files (metalava hooks into this automatically)
metalavaGenerateSignatureRelease Generates api/current.txt for release variant
metalavaGenerateSignatureDebug Generates api/current.txt for debug variant
metalavaCheckCompatibilityRelease Checks current code against committed api/current.txt — fails on breaking changes
metalavaCheckCompatibilityDebug Same as above for debug variant

Examples:

# Generate API files (recommended — runs both binary-compat-validator + metalava)
./gradlew apiDump

# Check for breaking changes
./gradlew metalavaCheckCompatibilityRelease

# Run for a specific module
./gradlew :stream-video-android-core:metalavaCheckCompatibilityRelease

How to Disable Metalava

# Per-invocation
./gradlew apiDump -Pmetalava.enabled=false

# Permanently (in gradle.properties)
metalava.enabled=false

When disabled, apiDump still generates .api files as before — only metalava tasks are skipped.

Modules Enabled

[x] stream-video-android-core
[x] stream-video-android-ui-core

🎨 UI Changes

None

Testing

Todo [WIP]

Run ./gradlew apiDump and verify both api/current.txt and .api files are generated
Run ./gradlew metalavaCheckCompatibilityRelease and verify it passes with no changes
Make a breaking API change (e.g., remove a public method), run metalavaCheckCompatibilityRelease, and verify it fails
Run ./gradlew apiDump -Pmetalava.enabled=false and verify metalava tasks are skipped
Verify CI workflow runs on PR and blocks merge on breaking changes
Verify adding approved-api-change label allows the PR to pass

rahul-lohra and others added 2 commits February 13, 2026 02:33
- Add metalava-gradle plugin (v0.5.0) for API surface tracking
- Create convention plugin (io.getstream.video.android.metalava) in build-logic
  to encapsulate all metalava setup into a single plugin ID per module
- Apply to stream-video-android-core and stream-video-android-ui-core modules
- Hook metalavaGenerateSignatureRelease into apiDump task automatically
- Add metalava.enabled gradle property to toggle on/off
- Add CI workflow (api-compatibility-check.yml) that blocks PRs with
  breaking API changes unless approved-api-change label is added
- Fix git hook copy in root build.gradle.kts to handle worktree environments

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@rahul-lohra rahul-lohra self-assigned this Feb 13, 2026
@github-actions
Copy link
Contributor

github-actions bot commented Feb 13, 2026

PR checklist ❌

The following issues were detected:

  • Missing required label: at least one label starting with pr:.

What we check

  1. Title is concise (5–18 words) unless labeled pr:ignore-for-release.
  2. At least one pr: label exists (e.g., pr:bug, pr:new-feature).
  3. Sections ### Goal, ### Implementation, and ### Testing contain content.

@rahul-lohra rahul-lohra changed the title Add Metalava API signature generation and compatibility tracking [DRAFT] Add Metalava API signature generation and compatibility tracking Feb 13, 2026
@aleksandar-apostolov
Copy link
Contributor

Note to self: We should look for a way to add binary compatibility check in conventions.

@github-actions
Copy link
Contributor

SDK Size Comparison 📏

SDK Before After Difference Status
stream-video-android-core 12.00 MB 12.00 MB 0.00 MB 🟢
stream-video-android-ui-xml 5.68 MB 5.68 MB 0.00 MB 🟢
stream-video-android-ui-compose 6.27 MB 6.27 MB 0.00 MB 🟢

@sonarqubecloud
Copy link

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