Skip to content

chore: merge main into workstation/6.0-Release#734

Merged
denischilik merged 27 commits into
workstation/6.0-Releasefrom
chore/merge-main-into-6.0-release
Jul 17, 2026
Merged

chore: merge main into workstation/6.0-Release#734
denischilik merged 27 commits into
workstation/6.0-Releasefrom
chore/merge-main-into-6.0-release

Conversation

@denischilik

Copy link
Copy Markdown
Contributor

Summary

Merges main into workstation/6.0-Release to bring the 6.0 release branch up to date before the final merge back to main.

What main brings in

  • Device-based consent feature (MParticleOptions.Builder.deviceBasedConsentEnabled(), MParticle.getDeviceConsentState() / setDeviceConsentState()) and related core changes in upload/batch/config handling, plus a new instrumented UploadServiceTest.
  • CI maintenance from main (actions/checkout pinned to v6.0.3, removal of cross-platform-tests.yml).

Conflict resolutions

  • 33 kit submodules + release.yml: kept the 6.0 branch deletions (kits live in-tree now; Rokt release workflows replace release.yml).
  • build.gradle: kept 6.0 versioning from the VERSION file; dropped main's 5.80.0-SNAPSHOT block.
  • MParticleOptions.java: kept main's new consent APIs and kept the 6.0 removal of deprecated isAndroidIdDisabled() / androidIdDisabled().
  • MParticleBaseClientImpl.java: kept the 6.0 domain-mapping warning condition (suppresses the false warning when the mapping equals the default URL).
  • ApiVisibilityTest.kt: recounted the public API surface after the merge (66 base − 4 removed on 6.0 + 3 added on main = 65); verified by running the test.
  • daily.yml / pull-request.yml: kept the 6.0 monorepo kit paths, split instrumented jobs, and VERSION-based versioning; adopted main's checkout@v6.0.3 pin; dropped submodules: recursive (no submodules on 6.0).
  • CHANGELOG.md: rebuilt as an ordered union (6.0 sections, then main's 5.78.3–5.80.0 sections, then shared history); regenerated at release time anyway.

Test plan

  • ./gradlew test passes locally (core + kit-base, debug and release variants)
  • ApiVisibilityTest verified with recounted public method count
  • trunk check clean on changed files
  • CI instrumented tests (covers main's new UploadServiceTest and upload/consent core changes)

mparticle-automation and others added 24 commits March 11, 2026 18:09
## [5.78.3](v5.78.2...v5.78.3) (2026-03-11)

### Updates & Maintenance

* bump actions/upload-artifact from 6 to 7 ([#649](#649)) ([0a188b1](0a188b1))
* Update submodules ([cbb17d7](cbb17d7))
## [5.78.4](v5.78.3...v5.78.4) (2026-03-23)

### Updates & Maintenance

* Update submodules ([08dab75](08dab75))
## [5.78.5](v5.78.4...v5.78.5) (2026-03-25)

### Updates & Maintenance

* Update submodules ([86d8d97](86d8d97))
* fix: increase MPLatch timeout from 5s to 30s

The 5-second timeout is too short for WebView JS bridge tests running
on newer GitHub Actions runner images (ubuntu24/20260309.50+). The
MParticleJSInterfaceITest tests consistently fail because JS execution
in the emulator WebView doesn't complete within 5 seconds on these
environments.

Increasing to 30 seconds provides sufficient margin while still
catching genuine hangs via the workflow-level timeout-minutes: 15.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: use explicit 30s timeout in JS bridge tests only

Instead of increasing the global MPLatch timeout (used by 20+ test
files), use an explicit 30-second await in MParticleJSInterfaceITest
only. WebView JS execution needs more time on newer CI runner images,
but other tests don't need the longer timeout.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* TRIAGE-608: Add max persistence age override option

* TRIAGE-608: Update throttl ts on success + tests

* TRIAGE-608: Make properties @VisibleForTesting

* TRIAGE-608: Fix retry-on-failure throttle logic
* feat: add customBaseURL CNAME support to NetworkOptions

Adds NetworkOptions.Builder.setCustomBaseURL(String) which routes all
mParticle endpoint traffic (config, events, identity, alias, audience)
through a single HTTPS CNAME host. When set, customBaseURL takes
priority over individual domain mappings and rewrites paths to match
CDN routing: /config/v4/, /nativeevents/v2/, /identity/v1/,
/nativeevents/v1/identity/, /nativeevents/v1/<key>/audience.

Also adds R8 keep rules for MParticle$Internal and
ConfigManager.getNetworkOptions() so kits can read customBaseURL after
minification.

The Rokt kit reads NetworkOptions.customBaseURL and forwards it to the
Rokt SDK: mparticle-integrations/mparticle-android-integration-rokt#143

Mirrors iOS work from mparticle-apple-sdk#760.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix: persist customBaseURL across NetworkOptions JSON round-trip

NetworkOptions.toJson() and withNetworkOptions(String) did not include
customBaseURL, so any value was silently dropped when UploadSettings
serialized NetworkOptions to the upload database. Events and alias
uploads read back NetworkOptions without customBaseURL and routed to
the default mParticle endpoints instead of the partner CNAME.

Also:
- Extract the customBaseURL/DomainMapping host-resolution branch out of
  getUrl() into a private resolveHost() helper plus a small ResolvedHost
  value type, lowering getUrl()'s cyclomatic complexity.
- Switch java.net.URL / java.net.MalformedURLException to imports.
- Add two androidTest cases covering the round-trip.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* test(android-core): cover custom base URL upload storage

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: Thomson Thomas <thomson.thomas@rokt.com>
## [5.79.0](v5.78.5...v5.79.0) (2026-05-14)

### Features

* add customBaseURL CNAME support to NetworkOptions ([#701](#701)) ([5285149](5285149)), closes [mparticle-apple-sdk#760](mParticle/mparticle-apple-sdk#760)
* Add max persistence age override option [TRIAGE-608] ([#699](#699)) ([ca88322](ca88322))

### Bug Fixes

* increase MPLatch timeout from 5s to 30s ([#695](#695)) ([20f723f](20f723f))

### Updates & Maintenance

* Update submodules ([59a4a9a](59a4a9a))
Bumps [trunk-io/trunk-action](https://github.com/trunk-io/trunk-action) from 1.2.4 to 1.3.1.
- [Release notes](https://github.com/trunk-io/trunk-action/releases)
- [Commits](trunk-io/trunk-action@75699af...04ba50e)

---
updated-dependencies:
- dependency-name: trunk-io/trunk-action
  dependency-version: 1.3.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: James Newman <james.newman@rokt.com>
…714)

The isolated urbanairship-kit lint/test steps in daily.yml and the
kit-compatibility test in pull-request.yml run `./gradlew` from inside
the kit dir without `-Pversion=...`. The kit's standalone build.gradle
defaults `project.version = '+'`, so its `com.mparticle:android-kit-plugin`
dependency resolves to the highest version on Maven Central — now
`6.0.0-rc.1` (published 2026-05-22), which renamed/removed kit-base
symbols and broke the kit's compile.

Mirror the pattern already used in the Sonatype Release job: extract the
SDK version via `./gradlew -q properties` and pass it as `-Pversion=...`
to every standalone kit invocation, so it resolves the freshly-published
mavenLocal artifact instead of the RC.

Affected steps:
- lint-checks → Run Isolated Kit Lint (urbanairship-kit)
- kotlin-lint-checks → Run Isolated Kit Kotlin Lint (urbanairship-kit)
- update-kits → Test Isolated Kits (urbanairship-kit)
- kit-compatibility-test → Run Isolated Kit Compatibility Tests (urbanairship-kit)

The companion defensive fix in mparticle-android-integration-urbanairship
pins the kit's standalone `project.version` to `[5.0,6.0)`.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
## [5.79.1](v5.79.0...v5.79.1) (2026-05-27)

### Bug Fixes

* **ci:** pin isolated-kit gradle version to prevent 6.0.0-rc.1 pull ([#714](#714)) ([eff10ea](eff10ea))

### Updates & Maintenance

* bump trunk-io/trunk-action from 1.2.4 to 1.3.1 ([#705](#705)) ([f4ceca7](f4ceca7))
* Update submodules ([e435979](e435979))
These checks have been failing on nearly every recent PR. The
cross-platform tests are known broken, and the semantic PR title /
branch name checks are no longer enforced.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Bumps [actions/checkout](https://github.com/actions/checkout) from 6.0.2 to 6.0.3.
- [Release notes](https://github.com/actions/checkout/releases)
- [Commits](actions/checkout@v6.0.2...v6.0.3)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: 6.0.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
## [5.79.2](v5.79.1...v5.79.2) (2026-06-22)

### Updates & Maintenance

* bump actions/checkout from 6.0.2 to 6.0.3 ([#720](#720)) ([d904edb](d904edb))
* remove cross-platform-tests and semantic PR/branch checks ([#712](#712)) ([6cdacf2](6cdacf2))
* Update submodules ([976dd0d](976dd0d))
Enables Inspire-style flows where consent is collected before MPID changes at checkout, so kit forwarding rules and uploads keep the correct consent state.
## [5.80.0](v5.79.2...v5.80.0) (2026-06-25)

### Features

* add device-based consent to override MPID-scoped consent ([#726](#726)) ([e92d352](e92d352))
…-6.0-release

# Conflicts:
#	.github/workflows/cross-platform-tests.yml
#	.github/workflows/daily.yml
#	.github/workflows/pull-request.yml
#	.github/workflows/release.yml
#	CHANGELOG.md
#	android-core/src/main/java/com/mparticle/MParticleOptions.java
#	android-core/src/main/java/com/mparticle/networking/MParticleBaseClientImpl.java
#	android-core/src/test/kotlin/com/mparticle/external/ApiVisibilityTest.kt
#	build.gradle
#	kits/adjust-kit
#	kits/adobe-kit
#	kits/adobemedia-kit
#	kits/appboy-kit
#	kits/appsflyer-kit
#	kits/apptentive-kit
#	kits/apptimize-kit
#	kits/apteligent-kit
#	kits/branch-kit
#	kits/button-kit
#	kits/clevertap-kit
#	kits/comscore-kit
#	kits/flurry-kit
#	kits/foresee-kit
#	kits/googleanalyticsfirebase-kit
#	kits/googleanalyticsfirebasega4-kit
#	kits/iterable-kit
#	kits/kochava-kit
#	kits/leanplum-kit
#	kits/localytics-kit
#	kits/onetrust-kit
#	kits/optimizely-kit
#	kits/pilgrim-kit
#	kits/radar-kit
#	kits/responsys-kit
#	kits/revealmobile-kit
#	kits/rokt-kit
#	kits/singular-kit
#	kits/skyhook-kit
#	kits/taplytics-kit
#	kits/tune-kit
#	kits/urbanairship-kit
#	kits/wootric-kit
@denischilik
denischilik requested a review from a team as a code owner July 16, 2026 18:09
@cursor

cursor Bot commented Jul 16, 2026

Copy link
Copy Markdown

PR Summary

Medium Risk
Introduces consent override and upload-time DB pruning that affect event forwarding and local data retention; scope is large but covered by new tests—CI instrumented runs remain the main validation gap.

Overview
Syncs workstation/6.0-Release with main so the 6.0 line picks up recent core SDK and CI work ahead of merging back to main.

Core behavior from main: Adds device-based consent (deviceBasedConsentEnabled, device consent get/set on MParticle, getEffectiveConsentState for kits and batch uploads). Adds optional persistenceMaxAgeSeconds with age-based pruning of messages, uploads, and sessions during upload (90-day default, 24-hour sweep throttle). Hardens NetworkOptions / domain-mapping JSON (skip invalid mappings, legacy overridesSubdirectory default).

CI / repo hygiene: Deletes cross-platform-tests.yml, pins actions/checkout to v6.0.3, bumps Trunk to v1.3.1, and drops semantic PR title/branch workflow jobs from pull-request.yml while keeping 6.0’s in-tree kit paths and split instrumented jobs.

Tests & docs: New/expanded instrumented and unit coverage for persistence deletes and consent; WebView JS tests use 30s latch timeouts; ApiVisibilityTest expects 65 public MParticle methods; CHANGELOG.md and README sample versions updated for merged release notes.

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

@BrandonStalnaker BrandonStalnaker left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

There's a few documentation related nits that you might want to fix or do a separate PR for but the actual code looks good. At lest in relation to the changes I fully understand.

Comment thread CHANGELOG.md Outdated

- add device-based consent to override MPID-scoped consent ([#726](https://github.com/mParticle/mparticle-android-sdk/issues/726)) ([e92d352](https://github.com/mParticle/mparticle-android-sdk/commit/e92d3522a350be90a1f15eb3b81d5e6f089f1aed))

## Unreleased

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think we've got 2 Unreleased Sections #1

Comment thread CHANGELOG.md
@@ -1,3 +1,3 @@
<!-- markdownlint-disable MD024 MD041 -->

## [Unreleased]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

#2 Unreleased section

Comment thread README.md
```groovy
dependencies {
implementation 'com.mparticle:android-core:5.78.2'
implementation 'com.mparticle:android-core:5.80.0'

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

For the 6.0 branch shouldn't this be something like 6.0.0-rc.1

steps:
- name: Checkout
uses: actions/checkout@0c366fd6a839edf440554fa01a7085ccba70ac98 #v5.0.0
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 #v5.0.0

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think this is actually the sha for v6.0.3

@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 d0df6b4. Configure here.

mConfigManager.setDeviceConsentState(state);
}
ConsentState newState = getConsentState(mpid);
mKitManager.onConsentStateUpdated(oldState, newState, mpid);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

MPID consent ignored with override

Medium Severity

When a device consent override is still stored but deviceBasedConsentEnabled is off, setConsentState updates MPID storage only. getEffectiveConsentState keeps returning the device override, so uploads, user-facing consent reads, and onConsentStateUpdated can see no change after an MPID consent update.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit d0df6b4. Configure here.

@sonarqubecloud

Copy link
Copy Markdown

@denischilik
denischilik merged commit 5cd12dd into workstation/6.0-Release Jul 17, 2026
43 checks passed
@denischilik
denischilik deleted the chore/merge-main-into-6.0-release branch July 17, 2026 13:43
denischilik added a commit that referenced this pull request Jul 21, 2026
* feat: migrate appsflyer-kit from submodule to regular directory (#650)

* feat: migrate appsflyer-kit from submodule to regular directory

* feat: relocate appsflyer-kit to kits/appsflyer/appsflyer-6 and update settings-kits.gradle

* Add kit lint/ktlint to PR workflow; ignore appsflyer-6 in Trunk

Made-with: Cursor

* Fix Trunk ignore: use glob patterns for appsflyer-6 and gradlew

Made-with: Cursor

* feat: remove .gitignore

* feat: Braze 38 Kit Migrate (#651)

* feat: migrate appboy-kit from submodule to regular directory

* feat: relocate appboy-kit to kits/braze/braze-38 and update settings-kits.gradle

Made-with: Cursor

* fix: add braze-38 to settings-kits.gradle (alphabetical order)

Made-with: Cursor

* feat: GA 23 Kit Migrate (#652)

* feat: migrate googleanalyticsfirebase-kit from submodule to regular directory

* feat: relocate googleanalyticsfirebase-kit to kits/ga/ga-23 and update settings-kits.gradle

Made-with: Cursor

* fix agent typo

* add bracket

* feat: GA4 23 Kit Migrate (#653)

* feat: migrate googleanalyticsfirebasega4-kit from submodule to regular directory

* feat: relocate googleanalyticsfirebasega4-kit to kits/ga4/ga4-23 and update settings-kits.gradle

* fix typo

* feat: Migrate Rokt kit (#659)

* feat: migrate rokt-kit from submodule to regular directory

* feat: relocate rokt-kit to kits/rokt/rokt

* feat: add rokt to settings-kits.gradle, remove accidental kit adds

Made-with: Cursor

* feat: Kochava 5 Kit Migrate (#654)

* feat: migrate kochava-kit from submodule to regular directory

* feat: relocate kochava-kit to kits/kochava/kochava-5 and update settings-kits.gradle

Made-with: Cursor

* fix typo

* feat: Migrate Adjust kit (#656)

* feat: migrate adjust-kit from submodule to regular directory

* feat: relocate adjust-kit to kits/adjust/adjust-5

* feat: add adjust-5 to settings-kits.gradle

Made-with: Cursor

* feat: Migrate Localytics kit (#661)

* feat: migrate localytics-kit from submodule to regular directory

* feat: relocate localytics-kit to kits/localytics/localytics-6

Made-with: Cursor

* feat: update settings-kits.gradle for localytics-6 path

Made-with: Cursor

* feat: Split instrumented tests in CI for parallel execution (#662)

* feat: split instrumented tests in CI for parallel execution

- Split instrumented tests into 4 parallel jobs: core, kit-base, testutils, orchestrator
- Reduced timeout from 30 to 20 min per job
- Each job runs only its module for faster feedback
- Add kit directories for isolated testing (adjust, googleanalyticsfirebase, kochava, localytics, rokt)
- Replace 2 shard jobs with matrix strategy (shards 0-3)
- Each shard runs ~25% of tests in parallel
- Timeout 12 min per shard, fail-fast: false
- extract common part in instrumented-tests.yml

* chore: remove rokt-kit submodule (migrated to monorepo)

Rokt kit is now in kits/rokt/rokt, no longer a submodule.

Made-with: Cursor

* fix: add explicit permissions to instrumented-tests workflow for Checkov CKV2_GHA_1

Made-with: Cursor

* fix: remove actions: write permission from instrumented-tests workflow

Made-with: Cursor

* feat: Leanplum 7 Kit Migrate (#655)

* feat: migrate leanplum-kit from submodule to regular directory
feat: relocate leanplum-kit to kits/leanplum/leanplum-7 and update settings-kits.gradle
fix: replace exposed Google API key with placeholder in leanplum example

Made-with: Cursor

* chore: update .mobsf to suppress MobSF false positives

- Add ignore-paths for src/test, example apps
- Add webview_javascript_interface ignore (intentional JS bridge for WebView SDK)

Made-with: Cursor

* fix security issues

* feat: Migrate CleverTap kit (#660)

* feat: migrate clevertap-kit from submodule to regular directory

* feat: relocate clevertap-kit to kits/clevertap/clevertap-7

Made-with: Cursor

* feat: update settings-kits.gradle for clevertap-7 kit path

Made-with: Cursor

* feat: Migrate Apptentive kit (#657)

feat: migrate apptentive-kit from submodule to regular directory
feat: relocate apptentive-kit to kits/apptentive/apptentive-6
feat: add apptentive-6 to settings-kits.gradle

* feat: Migrate Apptimize kit (#658)

* feat: migrate apptimize-kit from submodule to regular directory

* feat: relocate apptimize-kit to kits/apptimize/apptimize-3

* feat: add apptimize-3 to settings-kits.gradle

Made-with: Cursor

* feat: Migrate Adobe Media 5 kit (#671)

* feat: migrate adobemedia-kit from submodule to regular directory

* feat: relocate adobemedia-kit to kits/adobemedia/adobemedia-5

Made-with: Cursor

* feat: add adobemedia-5 to settings-kits.gradle

Made-with: Cursor

* feat: Migrate Adobe 5 kit (#670)

* feat: migrate adobe-kit from submodule to regular directory

* feat: relocate adobe-kit to kits/adobe/adobe-5

Made-with: Cursor

* feat: add adobe-5 to settings-kits.gradle

Made-with: Cursor

* feat: Migrate Iterable 3 kit (#669)

* feat: migrate iterable-kit from submodule to regular directory

* feat: relocate iterable-kit to kits/iterable/iterable-3

Made-with: Cursor

* feat: add iterable-3 to settings-kits.gradle

Made-with: Cursor

* feat: Migrate ComScore 6 kit (#668)

* feat: migrate comscore-kit from submodule to regular directory

* feat: relocate comscore-kit to kits/comscore/comscore-6

Made-with: Cursor

* feat: add comscore-6 to settings-kits.gradle

Made-with: Cursor

* feat: Migrate Radar kit (#665)

* feat: migrate radar-kit from submodule to regular directory

* feat: relocate radar-kit to kits/radar/radar-3

Made-with: Cursor

* feat: update settings-kits.gradle for radar-3

Made-with: Cursor

* feat: Migrate Singular 12 kit (#667)

* feat: migrate singular-kit from submodule to regular directory

* feat: relocate singular-kit to kits/singular/singular-12

Made-with: Cursor

* feat: add singular-12 to settings-kits.gradle

Made-with: Cursor

* feat: Migrate Optimizely kit (#664)

* feat: migrate optimizely-kit from submodule to regular directory

* feat: relocate optimizely-kit to kits/optimizely/optimizely-3

Made-with: Cursor

* feat: update settings-kits.gradle for optimizely-3

Made-with: Cursor

* feat: Migrate Branch 5 kit (#666)

* feat: migrate branch-kit from submodule to regular directory

* feat: relocate branch-kit to kits/branch/branch-5

* feat: add branch-5 to settings-kits.gradle

Made-with: Cursor

* fix: remove old branch-kit path from settings-kits.gradle

Made-with: Cursor

* fix: resolve MobSF/mobsfscan security findings

- Remove sensitive value from CustomDataParser log (android_kotlin_logging)
- Add SampleApplication to ignore-paths and manifest rules to .mobsf
  (assetlinks, task hijacking for Branch sample app)

Made-with: Cursor

* Add nosemgrep to SampleApplication gradlew to fix Semgrep CI

Made-with: Cursor

* feat: Migrate Urban Airship kit (#673)

* feat: migrate urbanairship-kit from submodule to regular directory

* feat: relocate urbanairship-kit to kits/urbanairship/urbanairship-20

Made-with: Cursor

* feat: add urbanairship-20 to settings-kits.gradle (commented, Kotlin 2.2.x standalone)

Made-with: Cursor

* fix: update CI and ONBOARDING for urbanairship standalone path (kits/urbanairship/urbanairship-20)

Made-with: Cursor

* Add nosemgrep to urbanairship PushSample gradlew to fix Semgrep CI

Made-with: Cursor

* Fix MobSF findings: remove sensitive logging, use SecureRandom in tests

Made-with: Cursor

* feat: Migrate OneTrust kit (#672)

* feat: migrate onetrust-kit from submodule to regular directory

* feat: relocate onetrust-kit to kits/onetrust/onetrust-5

Made-with: Cursor

* feat: add onetrust-5 to settings-kits.gradle

Made-with: Cursor

* fix: use version 202411 from OneTrust SDK dependency (com.onetrust.cmp:native-sdk:202411.2.0.0)

Made-with: Cursor

* fix: OneTrust kit uses path without version (kits/onetrust/onetrust)

Made-with: Cursor

* Add nosemgrep to onetrust gradlew to fix Semgrep CI

Made-with: Cursor

* disable AVD cache because of the issues in CI

* chore: Remove submodules, migrate kits to monorepo (#674)

chore: remove submodules, migrate to monorepo

- Remove .gitmodules and 12 kit submodules (apteligent, button, example,
  flurry, foresee, pilgrim, responsys, revealmobile, skyhook, taplytics,
  tune, wootric)
- Update settings-kits.gradle to remove deleted kit references
- Remove submodule steps from CI (pull-request.yml, release.yml, daily.yml)
- Update ONBOARDING.md: kits are in monorepo, no submodule init needed
- Update CONTRIBUTING.md: urbanairship path
- Update urbanairship paths in release.yml and daily.yml

Made-with: Cursor

* chore: migrate to Rokt release process (#663)

* chore: Migrate to Rokt release process

* Fix trunk issues

* Fixes for versions

* Separate versions for coroutines

* Change jvm version and fix lower case issue

* Update KitPlugin.groovy

* Pin actions versions up lint timeout

---------

Signed-off-by: James Newman <james.newman@rokt.com>

* fix: resolve trunk issues for all kits (#675)

* fix: resolve trunk issues for adjust kit

Made-with: Cursor

* fix: resolve trunk issues for adobe kit

Made-with: Cursor

* fix: resolve trunk issues for adobemedia kit

Made-with: Cursor

* fix: resolve trunk issues for apptentive kit

Made-with: Cursor

* fix: resolve trunk issues for appsflyer kit

Made-with: Cursor

* fix: resolve trunk issues for apptimize kit

Made-with: Cursor

* fix: resolve trunk issues for branch kit

Made-with: Cursor

* fix: resolve trunk issues for braze kit

Made-with: Cursor

* fix: resolve trunk issues for clevertap kit

Made-with: Cursor

* fix: resolve trunk issues for comscore kit

Made-with: Cursor

* fix: resolve trunk issues for iterable kit

Made-with: Cursor

* fix: resolve trunk issues for ga kit

Made-with: Cursor

* fix: resolve trunk issues for ga4 kit

Made-with: Cursor

* fix: resolve trunk issues for kochava kit

Made-with: Cursor

* fix: resolve trunk issues for leanplum kit

Made-with: Cursor

* fix: resolve trunk issues for localytics kit

Made-with: Cursor

* fix: resolve trunk issues for onetrust kit

Made-with: Cursor

* fix: resolve trunk issues for optimizely kit

Made-with: Cursor

* fix: resolve trunk issues for radar kit

Made-with: Cursor

* fix: resolve trunk issues for rokt kit

Made-with: Cursor

* fix: resolve trunk issues for singular kit

Made-with: Cursor

* feat: Removing deprecations - Part 1 (#676)

feat: Removing deprecations

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: add Braze 39 kit (#677)

* feat: copy Braze 39 kit from braze-38

* feat: update Braze 39 SDK to 39.0.0

* feat: Add Braze SDK 41 kit (braze-41) (#680)

feat: add Braze SDK 41 kit (braze-41)

- Add kits/braze/braze-41 with Braze android-sdk-ui:41.0.0
- Unique SonarQube project key and namespace (appboy41)
- Maven artifact: com.mparticle:braze-41
- Include in settings-kits.gradle

Made-with: Cursor

* feat: Add Braze SDK 40 kit (braze-40) (#679)

feat: add Braze SDK 40 kit (braze-40)

- Add kits/braze/braze-40 with Braze android-sdk-ui:40.0.0
- Unique SonarQube project key and namespace (appboy40)
- Maven artifact: com.mparticle:braze-40
- Include in settings-kits.gradle

Made-with: Cursor

Signed-off-by: denischilik <denis.chilik@rokt.com>

* chore: Remove deprecated KitIntegration.getUserIdentities() (#681)

* Remove deprecated KitIntegration.getUserIdentities()

Made-with: Cursor

* docs: Add CHANGELOG entry for KitIntegration.getUserIdentities removal

Made-with: Cursor

* test: Fix DataplanBlockingUserTests after KitIntegration.getUserIdentities removal

Use getCurrentUser()?.userIdentities instead of removed kit-level API.

Made-with: Cursor

* chore: Remove deprecated KitIntegration.getAllUserAttributes() (#682)

* chore: Remove deprecated KitIntegration.getAllUserAttributes()

- Remove tests that only covered the removed API
- Add CHANGELOG entry for custom kit migration path

Made-with: Cursor

* docs: Link CHANGELOG to PR 682 for getAllUserAttributes removal

Made-with: Cursor

* test: Fix DataplanBlockingUserTests after KitIntegration.getAllUserAttributes removal

Use getCurrentUser().userAttributes instead of removed allUserAttributes property.

Made-with: Cursor

* feat: split LogoutListener from AttributeListener (#685)

* feat: split LogoutListener from AttributeListener
* feat: use local versions in ci during the checks

* feat: inline user attribute removal in onRemoveUserAttribute (#687)

* Add BaseAttributeListener for shared supportsAttributeLists()

Introduce KitIntegration.BaseAttributeListener as the common superinterface
for AttributeListener and UserAttributeListener. Document it as a temporary
contract to enable incremental migration and smaller PRs.

Made-with: Cursor

* KitManagerImpl: call supportsAttributeLists once per provider

Resolve via BaseAttributeListener before AttributeListener/UserAttributeListener
branches in onUserAttributesReceived and setUserAttribute(list).

Made-with: Cursor

* Braze kit: delegate onRemoveUserAttribute to removeUserAttribute

UserAttributeListener.onRemoveUserAttribute now forwards to the existing
AttributeListener.removeUserAttribute implementation for braze-38 through braze-41.

Made-with: Cursor

* Move onRemoveUserAttribute to BaseAttributeListener

Declare onRemoveUserAttribute on KitIntegration.BaseAttributeListener so
AttributeListener and UserAttributeListener implementors must implement it.
KitManagerImpl now dispatches removal once via BaseAttributeListener.

AttributeListener-only kits delegate onRemoveUserAttribute to removeUserAttribute;
AttributeListenerTestKit updated accordingly.

Made-with: Cursor

* Remove removeUserAttribute from AttributeListener; keep kit helpers

Drop void removeUserAttribute(String) from KitIntegration.AttributeListener.
Kits keep the same logic as private-style helpers (fun removeUserAttribute
without override) and still satisfy BaseAttributeListener via
onRemoveUserAttribute. AdobeKitBase implements onRemoveUserAttribute by
delegating to removeUserAttribute.

Made-with: Cursor

* Inline remove-user-attribute logic into onRemoveUserAttribute

Move kit-specific handling from removed helper methods into
BaseAttributeListener.onRemoveUserAttribute implementations.
Rename AttributeListenerTestKit callback to removeUserAttributeListener.
Fix Braze custom-key branch for Kotlin smart-cast in Braze callback.

Made-with: Cursor

* chore: add no-op comments for Sonar empty-method rules

Document intentional empty overrides in Adobe, AppsFlyer, Branch, Braze,
and Kochava kits to satisfy SonarQube analysis.

Made-with: Cursor

* chore(kochava): Sonar no-op comment on onRemoveUserAttribute

Made-with: Cursor

* refactor(braze): use when in onRemoveUserAttribute success path

Replace if/else chain with when for standard vs custom user attribute removal; behavior unchanged across braze 38-41 kits.

Made-with: Cursor

* feat: Migrate setUserAttribute (#689)

* feat: align onSetUserAttribute with UserAttributeListener (nullable params, naming)

- SingularKit: key/value/user naming, null checks for Java interop
- AppsFlyerKit, Braze AppboyKit: consistent UserAttributeListener overrides

Made-with: Cursor

* feat: move onSetUserAttribute to BaseAttributeListener

- KitIntegration: declare onSetUserAttribute on BaseAttributeListener; remove from UserAttributeListener
- KitManagerImpl: dispatch scalar and CSV list paths via BaseAttributeListener; avoid double calls for dual-interface kits
- AttributeListener-only kits: delegate onSetUserAttribute to setUserAttribute
- AttributeListenerTestKit: implement onSetUserAttribute

Made-with: Cursor

* Remove setUserAttribute from AttributeListener; route via onSetUserAttribute

- Drop setUserAttribute from KitIntegration.AttributeListener; kits keep
  setUserAttribute as a regular method (no override).
- KitManagerImpl: use BaseAttributeListener.onSetUserAttribute for scalar and
  joined list paths; prefer UserAttributeListener when both interfaces apply.
- AttributeListenerTestKit: rename callback to setUserAttributeCallback;
  update DataplanBlockingUserTests.

Made-with: Cursor

* Inline user attribute handling in onSetUserAttribute; remove kit setUserAttribute

- Move scalar attribute logic from removed setUserAttribute helpers into
  onSetUserAttribute (or private helpers shared with setAllUserAttributes).
- Braze: applyScalarUserAttribute for onSet + initial sync; update unit tests
  to call onSetUserAttribute with a mocked FilteredMParticleUser.
- AttributeListenerTestKit: inline callback/onAttributeReceived in
  onSetUserAttribute.

Made-with: Cursor

* KitManagerImpl: restore AttributeListener before UserAttributeListener for list attrs

Re-run both branches when a kit implements both interfaces; UserAttributeListener
join path calls UserAttributeListener.onSetUserAttribute again.

Made-with: Cursor

* Braze kit: extract scalar user attribute branches into helpers

Split applyScalarUserAttribute into applyScalarUserAttributeOnUser plus
focused helpers for age, email/push subscribe, gender, subscription groups,
and unmapped custom keys (braze-38 through braze-41).

Made-with: Cursor

* KitManagerImplTest: verify onSetUserAttribute for list-as-CSV path

AttributeListener no longer has setUserAttribute; assert BaseAttributeListener
onSetUserAttribute with joined value and FilteredMParticleUser.

Made-with: Cursor

* KitManagerImplTest: expect null FilteredMParticleUser in list CSV verify

FilteredMParticleUser.getInstance returns null in JVM unit tests; Mockito
any(Class) does not match null. Use isNull() for the third onSetUserAttribute arg.

Made-with: Cursor

* Align onSetUserAttribute Kotlin overrides with nullable key and value

- Use String? and Any? for parameters matching Java Object/null call paths
- Add early returns when key or value is null where needed
- CleverTap: rename parameters to key/value; use mappedKey/mappedValue for mutations

Made-with: Cursor

* Use nullable FilteredMParticleUser in onSetUserAttribute overrides

Third parameter is user: FilteredMParticleUser? to match KitManagerImpl and
FilteredMParticleUser.getInstance. GA/GA4 use parameter name user.

Made-with: Cursor

* feat: move onSetUserAttributeList to BaseAttributeListener (#690)

* Delegate onSetUserAttributeList to setUserAttributeList (dual-interface kits)

Braze, AppsFlyer, and Singular implement both AttributeListener and
UserAttributeListener; wire empty onSetUserAttributeList to existing
setUserAttributeList behavior.

Made-with: Cursor

* Move onSetUserAttributeList to BaseAttributeListener

- Declare onSetUserAttributeList on BaseAttributeListener; remove from UserAttributeListener.
- KitManagerImpl calls BaseAttributeListener.onSetUserAttributeList for list attributes.
- AttributeListener-only kits delegate onSetUserAttributeList to setUserAttributeList.
- AttributeListenerTestKit implements onSetUserAttributeList via setUserAttributeList.

Made-with: Cursor

* test: KitManagerImplTest expect onSetUserAttributeList for list path

KitManagerImpl forwards list-valued attributes via BaseAttributeListener.onSetUserAttributeList when supportsAttributeLists is true.

Made-with: Cursor

* refactor: remove setUserAttributeList from AttributeListener

- Drop legacy two-arg setUserAttributeList from KitIntegration.AttributeListener;
  KitManagerImpl already forwards list attributes via onSetUserAttributeList.
- Kits: use private helpers (Braze, Localytics) or inline no-ops; Adobe kits call
  syncIds from onSetUserAttributeList only.
- AttributeListenerTestKit invokes list callback from onSetUserAttributeList.

Made-with: Cursor

* refactor: inline list attribute helpers into onSetUserAttributeList

- Braze: remove private setUserAttributeList; duplicate Braze getCurrentUser
  flow in onSetUserAttributeList and setAllUserAttributes initial sync.
- Localytics: call Localytics.setProfileAttribute directly from
  onSetUserAttributeList and setAllUserAttributes.

Made-with: Cursor

* Align onSetUserAttributeList parameter names with BaseAttributeListener

Rename Kotlin overrides and call sites to use attributeKey, attributeValueList,
and user consistently across kits and test kits.

Made-with: Cursor

* Document empty onSetUserAttributeList overrides with // not supported

Add a consistent comment for no-op kit implementations; align AppsFlyer
wording with other kits.

Made-with: Cursor

* refactor: Route bulk user attribute sync through onSetAllUserAttributes (#691)

* Delegate onSetAllUserAttributes to setAllUserAttributes in dual-listener kits

AppsFlyer and Braze: forward snapshot maps to AttributeListener.setAllUserAttributes.
Singular: align override parameter names with UserAttributeListener and delegate.

Made-with: Cursor

* Move onSetAllUserAttributes to BaseAttributeListener; route sync via one call

- Declare onSetAllUserAttributes on BaseAttributeListener; remove from UserAttributeListener
- KitManagerImpl: call BaseAttributeListener.onSetAllUserAttributes only (no duplicate setAllUserAttributes)
- AttributeListener-only kits: delegate onSetAllUserAttributes to setAllUserAttributes
- AttributeListenerTestKit: align setAllUserAttributes maps with Java API

Made-with: Cursor

* Hoist FilteredMParticleUser in onUserAttributesReceived

Compute getInstance(mpid, provider) once before the supportsAttributeLists branch.

Made-with: Cursor

* Remove setAllUserAttributes from AttributeListener

Drop the method from KitIntegration.AttributeListener; full sync is delivered
via BaseAttributeListener.onSetAllUserAttributes. Kits keep setAllUserAttributes
as ordinary helpers (no override). Update KitManagerImplTest and
AttributeListenerTestKit accordingly.

Made-with: Cursor

* refactor(kits): inline setAllUserAttributes into onSetAllUserAttributes

Remove redundant setAllUserAttributes helpers from kits and AttributeListenerTestKit.
Update BaseAttributeListener Javadoc in KitIntegration.

Made-with: Cursor

* refactor: Rename AttributeListener to ModifyIdentityListener (#692)

* refactor: decouple AttributeListener from BaseAttributeListener

AttributeListener now only declares identity APIs; kits implement
BaseAttributeListener alongside it for user attribute callbacks.
Update affected kits, AttributeListenerTestKit, and KitManagerImplTest mocks.

Made-with: Cursor

* Rename AttributeListener to ModifyIdentityListener

Replace KitIntegration.AttributeListener with ModifyIdentityListener for
set/remove user identity forwarding. Update KitManagerImpl, affected kits,
and rename AttributeListenerTestKit to ModifyIdentityListenerTestKit.
Clarify BaseAttributeListener Javadoc links and KitManagerImpl section comment.

Made-with: Cursor

* Remove BaseAttributeListener; fold into UserAttributeListener

Drop the deprecated BaseAttributeListener type and merge its callbacks into
UserAttributeListener. KitManagerImpl now forwards user attributes using
UserAttributeListener only; incrementUserAttribute calls both increment and
setUserAttribute on the same listener.

Kits that previously implemented BaseAttributeListener without the extended
callbacks now implement UserAttributeListener with no-op onIncrementUserAttribute,
onSetUserTag, and onConsentStateUpdated. Update ModifyIdentityListenerTestKit and
KitManagerImplTest accordingly.

Made-with: Cursor

* refactor: KitManagerImpl user-attribute forwarding and UserAttributeListener cleanup (#693)

* Add activeKits() helper and unit test

Introduce activeKits() to return non-disabled kit integrations from the
providers map. Add KitManagerImplTest.testActiveKitsExcludesDisabled to
verify disabled kits are omitted.

Made-with: Cursor

* Refactor KitManagerImpl user-attribute and identity forwarding

Use activeKits() for user attribute and identity paths; inline former
setUserAttribute helpers to avoid duplicate isDisabled checks. Flatten
syncUserIdentities with early returns and drop redundant null check on
identities map.

Made-with: Cursor

* UserAttributeListener: expose kit identity; use activeKits in onUserAttributesReceived

Declare getConfiguration() and getName() on UserAttributeListener so callers
can access kit metadata consistently. Route onUserAttributesReceived through
activeKits() and align variable naming with other active-kit paths.

Made-with: Cursor

* Remove FilteredMParticleUser from UserAttributeListener callbacks

Drop the user parameter from KitIntegration.UserAttributeListener methods;
update KitManagerImpl forwarding, instrumented/unit tests, and kit
implementations (Adobe, AppsFlyer, Apptentive, Braze, CleverTap, etc.).

Made-with: Cursor

* Refactor UserAttributeListener forwarding in KitManagerImpl

Add getConfiguration() and getName() to UserAttributeListener so callers
can use the listener type without casting. Introduce userAttributeListeners()
and iterate with variable name listener; keep activeKits() package-visible
for tests.

Made-with: Cursor

* test(appsflyer): align onConsentStateUpdated calls with UserAttributeListener API

Remove third argument and unused FilteredMParticleUser mock setup from unit tests.

Made-with: Cursor

* Fix DataplanBlockingUserTests onRemoveUserAttribute lambda arity

UserAttributeListenerTestKit exposes (String?) -> Unit; a two-parameter
lambda failed Kotlin type inference in compileDebugAndroidTestKotlin.

Made-with: Cursor

* Fix Braze kit tests for two-arg onConsentStateUpdated

KitIntegration.UserAttributeListener now passes only old and new
ConsentState. Drop the removed FilteredMParticleUser argument and
unused mock from AppboyKitTests across braze-38 through braze-41.

Made-with: Cursor

* Fix GA and GA4 kit tests for two-arg onConsentStateUpdated

Align GoogleAnalyticsFirebaseKitTest and GoogleAnalyticsFirebaseGA4KitTest
with KitIntegration: drop the removed FilteredMParticleUser argument and
unused mock from consent tests.

Made-with: Cursor

* ci: generate CHANGELOG on release draft (#696)

* ci: generate CHANGELOG on release draft

Run ROKT/rokt-workflows generate-changelog after mavenLocal smoke; use
default tag-prefix so semver matches VERSION and GitHub release tags.

Made-with: Cursor

* ci: pin generate-changelog action to commit SHA

Semgrep blocks mutable @main and unpinned third-party actions; use
ROKT/rokt-workflows@c5c93e92107c520fb8b8cf71070995abdf4c403f.

Made-with: Cursor

* refactor: centralize active kit filtering in KitManagerImpl (#697)

* refactor: use activeKits in getRoktKitApi

Use activeKits() in getRoktKitApi to centralize filtering of disabled kits and remove duplicated disabled checks.

Made-with: Cursor

* refactor: use activeKits in setWrapperSdkVersion

Use activeKits() in setWrapperSdkVersion to centralize disabled-kit filtering and remove duplicate disabled checks.

Made-with: Cursor

* refactor: use activeKits in kit event forwarding

Apply activeKits() in setLocation, logNetworkPerformance, and logCommerceEvent to centralize disabled-kit filtering and remove duplicated disabled checks.

Made-with: Cursor

* refactor: use activeKits for push and lifecycle forwarding

Apply activeKits() in push callbacks, breadcrumb/error forwarding, and selected activity/session listeners to centralize disabled-kit filtering and remove repeated checks.

Made-with: Cursor

* refactor: use activeKits for identity and referrer callbacks

Apply activeKits() in installReferrerUpdated and identity/consent callback forwarding methods to centralize disabled-kit filtering and remove duplicated checks.

Made-with: Cursor

* address sonar cube comments

* refactor: migrate Rokt contracts and facade ownership to rokt-kit (#700)

* feat: move Rokt object creation into rokt kit

Stop instantiating and storing Rokt inside android-core MParticle, and create it from rokt-kit extensions instead to start decoupling Rokt object ownership from the core SDK.

* feat: move Rokt facade and tests into rokt kit

Relocate the Rokt facade class and its unit tests from android-core to the rokt kit so Rokt-specific API ownership continues shifting out of core while preserving current behavior and test coverage.

* refactor: route Rokt facade calls through resolveRoktKit

Use a single helper in the Rokt facade to resolve the kit API for all operations, making the upcoming decoupling from the legacy roktKitApi chain incremental and safer.

* refactor: move Rokt request preprocessing into rokt kit helper

* refactor: route RoktKit attribute preparation through kit helper

* refactor: remove roktKitApi from core kit manager contract

* refactor: remove remaining roktKitApi bridge and tests

* refactor: move rokt contract types into rokt kit module

* refactor: move RoktEvent type into rokt kit module

* refactor: move MpRoktEventCallback into rokt kit module

* refactor: use native RoktEvent in rokt kit

Remove the mParticle RoktEvent wrapper and return native Rokt SDK events directly to simplify the event pipeline and reduce duplicate mapping logic.

* refactor: use native unload reasons in rokt callback

Remove the mParticle unload reason wrapper and pass Rokt SDK unload reasons through directly to simplify callback handling and eliminate redundant mapping.

* refactor: use native rokt callback types

Replace MpRoktEventCallback with the native RoktCallback across the rokt kit and tests to remove callback wrappers and simplify callback delegation.

* refactor: use native placement options type

Replace the local PlacementOptions wrapper with the native Rokt SDK PlacementOptions across the rokt kit and remove the now-redundant conversion layer.

* refactor: use native rokt config types

Replace mParticle RoktConfig and CacheConfig wrappers with native Rokt SDK config types and remove the now-unnecessary config conversion layer and tests.

* refactor: move rokt facade and embedded view types to kits package

Relocate Rokt, RoktEmbeddedView, RoktLayoutDimensionCallBack, and RoktTest into com.mparticle.kits to keep kit-owned types co-located and simplify package boundaries.

* refactor: replace rokt isEnabled reflection with callback provider

Avoid runtime method lookup for isEnabled by injecting an explicit enablement callback and wiring it to core callbacks with a safe opt-out fallback, preserving behavior under obfuscation.

* refactor: route Rokt enabled check through kit manager contract

Add isEnabled to KitManager and use it from the Rokt facade so enablement is resolved through a stable kit-layer API without reflection or config manager coupling.

* chore: remove unused imports in KitManagerImpl tests

Clean up stale imports in KitManagerImplTest so android-kit-base ktlint test source checks pass in CI.

* fix: resolve rokt and buildSrc lint and ci compatibility issues

Replace replaceFirstChar in buildSrc for older Kotlin compatibility and address rokt ktlint violations by suppressing Java-style accessor naming and wrapping long warning messages.

* refactor: tighten Rokt accessor API and restore legacy docs

Keep only the no-arg public Rokt accessor with explicit start precondition, restore original public method documentation text, and make prepareAttributesAsync internal per review feedback.

* refactor: align MParticleRokt package with kit module path

Update MParticleRokt package to com.mparticle.kits so declaration matches the file location and resolves package/path review feedback.

* refactor: cache MParticleRokt accessor instance

Keep a synchronized singleton Rokt instance in MParticleRokt to avoid repeated allocations while preserving the explicit start precondition.

* feat: migrate Rokt kit to Rokt SDK 5.x and remove MpRoktEventCallback (#704)

* feat: migrate Rokt kit to Rokt SDK 5.x and remove MpRoktEventCallback

Bumps com.rokt:roktsdk 4.14.0 → 5.1.0 and adopts the 5.x event-driven API:
- Rokt.execute(...) → Rokt.selectPlacements(...)
- RoktEvent.id renamed to identifier; SDK-side CartItemInstantPurchase.placementId
  renamed to identifier
- com.rokt.roktsdk.RoktLayout switched to onEvent: (RoktEvent) -> Unit
- Drops removed Rokt.RoktCallback / Rokt.RoktInitCallback / Rokt.UnloadReasons
  and RoktWidgetDimensionCallBack.onMarginChanged

Removes the legacy callback surface from the mParticle public API, since 5.x
customers consume Rokt.events(identifier): Flow<RoktEvent> instead:
- Delete MpRoktEventCallback and UnloadReasons
- Drop callbacks param from com.mparticle.Rokt.selectPlacements
- Drop mpRoktEventCallback from RoktKitApi, RoktKitApiImpl,
  KitIntegration.RoktListener, and RoktKit.selectPlacements
- Rename RoktKit.runComposableWithCallback to prepareComposableAttributes;
  RoktLayout composable no longer takes a callback parameter

BREAKING CHANGE: MpRoktEventCallback and UnloadReasons are removed and the
callbacks parameter has been dropped from Rokt.selectPlacements and the
mParticle RoktLayout composable. Use Rokt.events(identifier) to observe
placement events as a Flow.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* refactor: align mParticle Rokt API naming with Rokt SDK 5.x

Renames public API symbols to match Rokt 5.x's vocabulary:
- com.mparticle.RoktEvent.*.placementId → identifier on all event
  classes (OfferEngagement, PositiveEngagement, FirstPositiveEngagement,
  PlacementInteractive, PlacementReady, PlacementClosed, PlacementCompleted,
  PlacementFailure, OpenUrl, CartItemInstantPurchase)
- Rokt.purchaseFinalized(placementId, ..., status) →
  (identifier, ..., success); propagated through RoktKitApi,
  RoktKitApiImpl, KitIntegration.RoktListener, and RoktKit

Rename-only — no behavior change.

BREAKING CHANGE: RoktEvent.placementId is renamed to identifier and
Rokt.purchaseFinalized parameters renamed from (placementId, status) to
(identifier, success).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* refactor: drop dead onMarginChanged from RoktLayoutDimensionCallBack

Rokt SDK 5.x removed onMarginChanged from RoktWidgetDimensionCallBack;
the kit already dropped its override, but mParticle's mirror interface
still forced customers to implement an onMarginChanged that never fires.

onHeightChanged remains the only method on RoktLayoutDimensionCallBack
and is still the way to observe Widget height changes — 5.x exposes no
event-based equivalent.

BREAKING CHANGE: RoktLayoutDimensionCallBack.onMarginChanged is removed.
Customers implementing this interface should drop the override.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* feat: add customBaseURL CNAME support to NetworkOptions (#702)

* feat: add customBaseURL CNAME support to NetworkOptions

Adds NetworkOptions.Builder.setCustomBaseURL(String) which routes all
mParticle endpoint traffic (config, events, identity, alias, audience)
through a single HTTPS CNAME host. When set, customBaseURL takes
priority over individual domain mappings and rewrites paths to match
CDN routing: /config/v4/, /nativeevents/v2/, /identity/v1/,
/nativeevents/v1/identity/, /nativeevents/v1/<key>/audience.

Also adds R8 keep rules for MParticle$Internal and
ConfigManager.getNetworkOptions() so kits can read customBaseURL after
minification.

The Rokt kit reads NetworkOptions.customBaseURL and forwards it to the
Rokt SDK: https://github.com/mparticle-integrations/mparticle-android-integration-rokt/pull/143

Mirrors iOS work from mparticle-apple-sdk#760.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* feat: pass mParticle CNAME through to Rokt SDK

When the integrating app sets a custom CNAME on MParticleOptions via
NetworkOptions.customBaseURL, forward it to the Rokt SDK so Rokt traffic
routes through the same first-party domain. No-op when customBaseURL is
unset, empty, or MParticle is uninitialized.

Mirrors the iOS Rokt kit behavior added in mparticle-apple-sdk#760.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix: persist customBaseURL across NetworkOptions JSON round-trip

NetworkOptions.toJson() and withNetworkOptions(String) did not include
customBaseURL, so any value was silently dropped when UploadSettings
serialized NetworkOptions to the upload database. Events and alias
uploads read back NetworkOptions without customBaseURL and routed to
the default mParticle endpoints instead of the partner CNAME.

Also:
- Extract the customBaseURL/DomainMapping host-resolution branch out of
  getUrl() into a private resolveHost() helper plus a small ResolvedHost
  value type, lowering getUrl()'s cyclomatic complexity.
- Switch java.net.URL / java.net.MalformedURLException to imports.
- Add two androidTest cases covering the round-trip.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* Bump Rokt dependency version

* fix: only warn on domain-mapping conflict when mapping is non-default

NetworkOptionsManager.validateAndResolve auto-populates a default
DomainMapping for every endpoint, so the previous check fired the
"customBaseURL is set; domain mapping for X is ignored" warning on
every getUrl() call for every endpoint — even when the integrator
never configured a custom mapping. Compare against the default URL
so the warning only fires for genuinely user-configured mappings
that conflict with customBaseURL.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* ci: support alpha beta and release candidate versions (#708)

* ci(release): support alpha beta and release candidate versions

Add qualified release version handling to the draft workflow so alpha, beta, and release candidate versions can be prepared from the selected branch.

Publish workflow releases now run from workstation branches and mark qualified versions as GitHub pre-releases instead of latest stable releases.

Document the new release flow and record the workflow capability in the changelog.

* fix: support older Kotlin in publish helper

* ci: use SDK Gradle wrapper for cross-platform tests

* ci: patch cross-platform Gradle settings

* ci: update cross-platform javadoc patch

* ci: align cross-platform Android plugin version

* ci: relax cross-platform JVM target validation

* ci: patch cross-platform SDK API usage

* ci: normalize cross-platform user attribute lists

* ci: remove cross-platform compatibility workarounds

* ci: use release-prep branch for draft releases

* build(rokt): update Rokt kit dependency stack (#707)

* build(rokt): update Rokt kit dependency stack

Align the Rokt kit build with the upcoming Rokt SDK alpha by
updating Kotlin, Compose, and coroutine dependencies. Pin the Maven
artifact id so the kit continues publishing as android-rokt-kit.

#agentic

* build(rokt): use Rokt SDK 6.0.0 release candidate

Point the Rokt kit at the Maven Central release candidate so the
kit can compile and test without relying on unpublished alpha artifacts.

#agentic

* build(rokt): guard publish metadata for standalone builds

Only configure the Rokt kit Maven publish metadata when the
mparticleMavenPublish extension is available. This keeps standalone kit
builds working while preserving the monorepo publish artifact id.

#agentic

* Prepare release 6.0.0-rc.1 (#709)

* chore: prepare release 6.0.0-rc.1

* build(rokt): update Rokt SDK to 6.0.1-rc.1

---------

Co-authored-by: thomson-t <125323226+thomson-t@users.noreply.github.com>
Co-authored-by: Thomson Thomas <thomson.thomas@rokt.com>

* feat(rokt): add kit API parity access (#711)

Add Kotlin MParticle.rokt access so partners can call Rokt kit APIs from the active mParticle instance again.

Forward native Rokt SDK Compose events through the kit RoktLayout wrapper and document the Kotlin and Java entry points.

* docs: add v6 Rokt migration guidance (#706)

docs: add v6 Rokt migration notes

Document v6 Rokt migration details so integrators can update imports and type usage after moving Rokt APIs into rokt-kit.

* feat: add adjust sample apps and CI example builds (#723)

* feat(kits): add adjust sample apps and CI example builds

Introduce Kotlin/Java sample apps for adjust-5 and wire a CI-only settings
file so example modules stay isolated from kit settings and settings-kits.gradle.

* ci: pin build-kits workflow actions to commit SHAs

Fix semgrep blocking findings for mutable GitHub Actions tag references.

* fix(kits): align Gradle project paths with android- kit names

Use explicit android- prefixed includes and projectDir mappings so kit
examples, dependencies, and CI matrix tasks resolve the same modules.

* revert: restore settings-kits.gradle rename pattern

Keep kit registration unchanged and rely on the existing android- rename
so example modules and CI matrix paths continue to resolve correctly.

* chore(kits): remove Adjust Java sample app

Keep only the Kotlin example and drop Java example wiring from CI matrix
and kit example settings.

* feat: add Kotlin sample apps for all integrated kits (#724)

* feat(kits): add Kotlin sample apps for all integrated kits

Replicate the Adjust example-app pattern across every kit in
settings-kits.gradle, wire them in settings-kit-examples.gradle and
kits/matrix.json, and add a generator script. Skip CI example builds for
kits that need custom Maven repos or AGP 8.6+.

* fix(kits): enable vendor Maven repos in sample app builds

Add kit-specific repositories and multidex to example apps that need
vendor Maven resolution, and drop skip_example_builds for those kits.

* feat: pin kit SDK dependencies to current supported ranges (#725)

* feat: pin kit SDK dependencies to current supported ranges

* refactor(adobemedia): rename kit to adobemedia-3 and lock to Adobe SDK BOM

Adobe's Experience Platform SDK is at major 3.x, so the kit directory now
follows the wrapped-SDK-major convention (adobemedia-5 -> adobemedia-3).

Replace the mixed per-artifact pins with the Adobe sdk-bom. The legacy
sdk-core (deprecated 2024-06-30) and mobileservices (unsupported on Android)
artifacts are dropped; modern `core` now arrives via the BOM. The BOM range
[3.0.0,4.0.0) auto-tracks the latest 3.x minor/patch, the Gradle equivalent
of iOS SPM .upToNextMajor(from: "3.0.0").

Updated matrix.json, settings-kits.gradle, settings-kit-examples.gradle, the
example module project ref, and the README install line.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* refactor(adobe): rename adobe-5 to adobe (no SDK, S2S only) and drop adobemedia BOM comments

The adobe kit is a server-to-server integration with no Adobe SDK dependency
(no com.adobe.* imports), so the wrapped-SDK-major suffix does not apply —
renamed adobe-5 -> adobe, matching the no-number convention used by onetrust
and rokt. Updated matrix.json, settings-kits.gradle, settings-kit-examples.gradle,
and the example module project ref. The published artifact version
(android-adobe-kit:5+) is unchanged, consistent with other no-number kits.

Also removed the explanatory comments from the adobemedia-3 BOM block.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>

* fix: align braze-38 SDK range with its directory major (#730)

The kit directory suffix N encodes the wrapped vendor SDK's intended major
version, but braze/braze-38 pinned com.braze:android-sdk-ui:[37.0.0,38.0.0)
(major 37). Bumped to [38.0.0,39.0.0) to match the braze-38 directory; siblings
braze-39/40/41 already align and there is no braze-37 directory.

The GA kit (ga-23/ga4-23) major-23 alignment is deferred to a separate PR that
also bumps the repo Kotlin toolchain, because firebase-analytics 23.x ships
Kotlin 2.1/2.2 metadata that the current Kotlin 2.0.20 compiler cannot read.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>

* feat: upgrade Kotlin to 2.1.20 across core SDK and kits (#732)

* feat: Upgrade Kotlin to 2.1.20 across core SDK and kits

* fix: construct kit test config JSON explicitly for Kotlin 2.1 overload resolution

* fix: align GA kits with directory major 23 (+ per-kit Kotlin 2.2.20) (#731)

* fix: align GA kits with directory major 23 and bump Kotlin to read 23.x metadata

The ga-23 and ga4-23 directories encode wrapped firebase-analytics major 23,
but both pinned firebase-analytics:[22.1.0,23.0.0) (major 22). Bumped the
firebase-analytics and lockstep play-services-measurement-api ranges to
[23.0.0,24.0.0).

firebase-analytics 23.x ships Kotlin 2.1/2.2 metadata (23.0.0 -> 2.1.0,
23.2.0 -> 2.2.0), which the kits' Kotlin 2.0.20 compiler cannot read, so the
range bump alone fails compileReleaseKotlin. Bumped these two kits'
ext.kotlin_version to 2.2.20, matching the existing per-kit override pattern
already used by urbanairship-20 (2.2.20) and rokt (2.1.20).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* ci: build ga-23/ga4-23 as isolated kits (Kotlin 2.2.x)

firebase-analytics 23.x ships Kotlin 2.1/2.2 metadata that the repo's root
Kotlin Gradle plugin (2.0.20) cannot read, so the GA kits cannot compile in
the aggregate settings-kits.gradle build. Per-kit ext.kotlin_version has no
effect there because the aggregate compiler is fixed by the root buildscript.

Follow the established urbanairship-20 isolated-kit pattern so the GA kits are
built standalone with their own Kotlin 2.2.20:

- Remove ga-23/ga4-23 from kits/matrix.json (no aggregate build-kits jobs).
- Comment them out of settings-kits.gradle and remove their example modules
  from settings-kit-examples.gradle.
- Add isolated compatibility (pull-request.yml) and lint/ktlint/test
  (daily.yml) steps that run `-p kits/ga/ga-23` / `-p kits/ga4/ga4-23`.
- Document both kits under "Currently isolated" in ONBOARDING.md.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Signed-off-by: Nickolas Dimitrakas <nickolas.dimitrakas@rokt.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>

* fix(braze): correct example app applicationId to match push category (#729)

The braze-38/39/40/41 example apps set applicationId to
"com.mparticle.com.mparticle.kits.braze.example" (duplicated prefix) while the
manifest package and the MPReceiver FCM intent-filter category are
"com.mparticle.kits.braze.example". Since the effective package equals the
applicationId, the push category no longer matched, so push registration and
receipt in the sample apps could fail. Align the applicationId with the package
and category across all four tracks.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>

* chore: merge main into workstation/6.0-Release (#734)

* chore: Update submodules

* chore: 5.78.3 (release)

## [5.78.3](https://github.com/mParticle/mparticle-android-sdk/compare/v5.78.2...v5.78.3) (2026-03-11)

### Updates & Maintenance

* bump actions/upload-artifact from 6 to 7 ([#649](https://github.com/mParticle/mparticle-android-sdk/issues/649)) ([0a188b1](https://github.com/mParticle/mparticle-android-sdk/commit/0a188b1f88efde471f8d6bff2aa8611b1b4bf956))
* Update submodules ([cbb17d7](https://github.com/mParticle/mparticle-android-sdk/commit/cbb17d7e359d41d8d7577a9516cf7788c7288442))

* chore: Update submodules

* chore: 5.78.4 (release)

## [5.78.4](https://github.com/mParticle/mparticle-android-sdk/compare/v5.78.3...v5.78.4) (2026-03-23)

### Updates & Maintenance

* Update submodules ([08dab75](https://github.com/mParticle/mparticle-android-sdk/commit/08dab75e3715733f6f5655fbf39fbce16a2e01a2))

* chore: Update submodules

* chore: 5.78.5 (release)

## [5.78.5](https://github.com/mParticle/mparticle-android-sdk/compare/v5.78.4...v5.78.5) (2026-03-25)

### Updates & Maintenance

* Update submodules ([86d8d97](https://github.com/mParticle/mparticle-android-sdk/commit/86d8d9748a0c7a796dd0b0be6722f92acef301ea))

* fix: increase MPLatch timeout from 5s to 30s (#695)

* fix: increase MPLatch timeout from 5s to 30s

The 5-second timeout is too short for WebView JS bridge tests running
on newer GitHub Actions runner images (ubuntu24/20260309.50+). The
MParticleJSInterfaceITest tests consistently fail because JS execution
in the emulator WebView doesn't complete within 5 seconds on these
environments.

Increasing to 30 seconds provides sufficient margin while still
catching genuine hangs via the workflow-level timeout-minutes: 15.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: use explicit 30s timeout in JS bridge tests only

Instead of increasing the global MPLatch timeout (used by 20+ test
files), use an explicit 30-second await in MParticleJSInterfaceITest
only. WebView JS execution needs more time on newer CI runner images,
but other tests don't need the longer timeout.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: Add max persistence age override option [TRIAGE-608] (#699)

* TRIAGE-608: Add max persistence age override option

* TRIAGE-608: Update throttl ts on success + tests

* TRIAGE-608: Make properties @VisibleForTesting

* TRIAGE-608: Fix retry-on-failure throttle logic

* feat: add customBaseURL CNAME support to NetworkOptions (#701)

* feat: add customBaseURL CNAME support to NetworkOptions

Adds NetworkOptions.Builder.setCustomBaseURL(String) which routes all
mParticle endpoint traffic (config, events, identity, alias, audience)
through a single HTTPS CNAME host. When set, customBaseURL takes
priority over individual domain mappings and rewrites paths to match
CDN routing: /config/v4/, /nativeevents/v2/, /identity/v1/,
/nativeevents/v1/identity/, /nativeevents/v1/<key>/audience.

Also adds R8 keep rules for MParticle$Internal and
ConfigManager.getNetworkOptions() so kits can read customBaseURL after
minification.

The Rokt kit reads NetworkOptions.customBaseURL and forwards it to the
Rokt SDK: https://github.com/mparticle-integrations/mparticle-android-integration-rokt/pull/143

Mirrors iOS work from mparticle-apple-sdk#760.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix: persist customBaseURL across NetworkOptions JSON round-trip

NetworkOptions.toJson() and withNetworkOptions(String) did not include
customBaseURL, so any value was silently dropped when UploadSettings
serialized NetworkOptions to the upload database. Events and alias
uploads read back NetworkOptions without customBaseURL and routed to
the default mParticle endpoints instead of the partner CNAME.

Also:
- Extract the customBaseURL/DomainMapping host-resolution branch out of
  getUrl() into a private resolveHost() helper plus a small ResolvedHost
  value type, lowering getUrl()'s cyclomatic complexity.
- Switch java.net.URL / java.net.MalformedURLException to imports.
- Add two androidTest cases covering the round-trip.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* test(android-core): cover custom base URL upload storage

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: Thomson Thomas <thomson.thomas@rokt.com>

* chore: Update submodules

* chore: 5.79.0 (release)

## [5.79.0](https://github.com/mParticle/mparticle-android-sdk/compare/v5.78.5...v5.79.0) (2026-05-14)

### Features

* add customBaseURL CNAME support to NetworkOptions ([#701](https://github.com/mParticle/mparticle-android-sdk/issues/701)) ([5285149](https://github.com/mParticle/mparticle-android-sdk/commit/5285149118b58cbd5cf4fb90cb58627deb7538b9)), closes [mparticle-apple-sdk#760](https://github.com/mParticle/mparticle-apple-sdk/issues/760)
* Add max persistence age override option [TRIAGE-608] ([#699](https://github.com/mParticle/mparticle-android-sdk/issues/699)) ([ca88322](https://github.com/mParticle/mparticle-android-sdk/commit/ca88322ac7ef8649ed111cf28afb81d99cdb271a))

### Bug Fixes

* increase MPLatch timeout from 5s to 30s ([#695](https://github.com/mParticle/mparticle-android-sdk/issues/695)) ([20f723f](https://github.com/mParticle/mparticle-android-sdk/commit/20f723f27cf296c879ceebc9d234edca039ab371))

### Updates & Maintenance

* Update submodules ([59a4a9a](https://github.com/mParticle/mparticle-android-sdk/commit/59a4a9a68e3addfaf5c4eea1afd396889721819d))

* chore: bump trunk-io/trunk-action from 1.2.4 to 1.3.1 (#705)

Bumps [trunk-io/trunk-action](https://github.com/trunk-io/trunk-action) from 1.2.4 to 1.3.1.
- [Release notes](https://github.com/trunk-io/trunk-action/releases)
- [Commits](https://github.com/trunk-io/trunk-action/compare/75699af9e26881e564e9d832ef7dc3af25ec031b...04ba50e7658c81db7356da96657e6e77f220bfa3)

---
updated-dependencies:
- dependency-name: trunk-io/trunk-action
  dependency-version: 1.3.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Handle legacy persisted domain mappings safely (#703)

Co-authored-by: James Newman <james.newman@rokt.com>

* fix(ci): pin isolated-kit gradle version to prevent 6.0.0-rc.1 pull (#714)

The isolated urbanairship-kit lint/test steps in daily.yml and the
kit-compatibility test in pull-request.yml run `./gradlew` from inside
the kit dir without `-Pversion=...`. The kit's standalone build.gradle
defaults `project.version = '+'`, so its `com.mparticle:android-kit-plugin`
dependency resolves to the highest version on Maven Central — now
`6.0.0-rc.1` (published 2026-05-22), which renamed/removed kit-base
symbols and broke the kit's compile.

Mirror the pattern already used in the Sonatype Release job: extract the
SDK version via `./gradlew -q properties` and pass it as `-Pversion=...`
to every standalone kit invocation, so it resolves the freshly-published
mavenLocal artifact instead of the RC.

Affected steps:
- lint-checks → Run Isolated Kit Lint (urbanairship-kit)
- kotlin-lint-checks → Run Isolated Kit Kotlin Lint (urbanairship-kit)
- update-kits → Test Isolated Kits (urbanairship-kit)
- kit-compatibility-test → Run Isolated Kit Compatibility Tests (urbanairship-kit)

The companion defensive fix in mparticle-android-integration-urbanairship
pins the kit's standalone `project.version` to `[5.0,6.0)`.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore: Update submodules

* chore: 5.79.1 (release)

## [5.79.1](https://github.com/mParticle/mparticle-android-sdk/compare/v5.79.0...v5.79.1) (2026-05-27)

### Bug Fixes

* **ci:** pin isolated-kit gradle version to prevent 6.0.0-rc.1 pull ([#714](https://github.com/mParticle/mparticle-android-sdk/issues/714)) ([eff10ea](https://github.com/mParticle/mparticle-android-sdk/commit/eff10ead69167f0ea3df248b2bbed089397600cd))

### Updates & Maintenance

* bump trunk-io/trunk-action from 1.2.4 to 1.3.1 ([#705](https://github.com/mParticle/mparticle-android-sdk/issues/705)) ([f4ceca7](https://github.com/mParticle/mparticle-android-sdk/commit/f4ceca7de2c2ba01ea87c98698ef7bb84991b4ab))
* Update submodules ([e435979](https://github.com/mParticle/mparticle-android-sdk/commit/e435979e1e966ef2b318bb29135852f9d55df55a))

* ci: remove cross-platform-tests and semantic PR/branch checks (#712)

These checks have been failing on nearly every recent PR. The
cross-platform tests are known broken, and the semantic PR title /
branch name checks are no longer enforced.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore: bump actions/checkout from 6.0.2 to 6.0.3 (#720)

Bumps [actions/checkout](https://github.com/actions/checkout) from 6.0.2 to 6.0.3.
- [Release notes](https://github.com/actions/checkout/releases)
- [Commits](https://github.com/actions/checkout/compare/v6.0.2...v6.0.3)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: 6.0.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* chore: Update submodules

* chore: 5.79.2 (release)

## [5.79.2](https://github.com/mParticle/mparticle-android-sdk/compare/v5.79.1...v5.79.2) (2026-06-22)

### Updates & Maintenance

* bump actions/checkout from 6.0.2 to 6.0.3 ([#720](https://github.com/mParticle/mparticle-android-sdk/issues/720)) ([d904edb](https://github.com/mParticle/mparticle-android-sdk/commit/d904edb0a944a2ce813e7dc31c026f0b2f7ccecb))
* remove cross-platform-tests and semantic PR/branch checks ([#712](https://github.com/mParticle/mparticle-android-sdk/issues/712)) ([6cdacf2](https://github.com/mParticle/mparticle-android-sdk/commit/6cdacf2926e02e2359352dbcf12b4e4bb66236fa))
* Update submodules ([976dd0d](https://github.com/mParticle/mparticle-android-sdk/commit/976dd0d13d6aa27f805a6b06a73d923f1a207e80))

* feat: add device-based consent to override MPID-scoped consent (#726)

Enables Inspire-style flows where consent is collected before MPID changes at checkout, so kit forwarding rules and uploads keep the correct consent state.

* chore: 5.80.0 (release)

## [5.80.0](https://github.com/mParticle/mparticle-android-sdk/compare/v5.79.2...v5.80.0) (2026-06-25)

### Features

* add device-based consent to override MPID-scoped consent ([#726](https://github.com/mParticle/mparticle-android-sdk/issues/726)) ([e92d352](https://github.com/mParticle/mparticle-android-sdk/commit/e92d3522a350be90a1f15eb3b81d5e6f089f1aed))

* chore: normalize CHANGELOG list markers after merge

* ci: pin actions/checkout to commit SHA to satisfy security lint

* docs: remove duplicate Unreleased changelog section

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: mparticle-automation <developers@mparticle.com>
Co-authored-by: Robert Ing <ring@mparticle.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: junias-rokt <junias.ngoyi@rokt.com>
Co-authored-by: James Newman <james.newman@rokt.com>
Co-authored-by: Thomson Thomas <thomson.thomas@rokt.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: ankitsingh08 <ankit.tomar08@gmail.com>

* feat: add Rokt Shoppable Ads support (#713)

feat(rokt): add Shoppable Ads support

Add Rokt kit facade APIs for payment extension registration and Shoppable Ads selection so host apps can wire optional payment providers through mParticle.

Forward Shoppable Ads requests through the existing identity confirmation and attribute enrichment pipeline, pass dashboard stripePublishableKey into the Rokt SDK registration config, and cover the behavior with kit and facade tests.

* docs: address 6.0 merge review comments (#735)

docs: address 6.0 merge review comments (README version, checkout pin comment)

* feat(rokt-sdk-plus): add com.rokt:rokt-sdk-plus umbrella artifact (#721)

Introduce a single Android dependency that bundles the mParticle core SDK, the
mParticle Rokt kit, and the Rokt Payment Extension (Shoppable Ads), mirroring the
iOS RoktSDKPlus umbrella. Partners adopting Shoppable Ads can depend on one
artifact instead of wiring up core + kit + payment extension by hand.

- New rokt-sdk-plus module: thin com.android.library (empty AAR) that api-aggregates
  android-core, android-rokt-kit, and com.rokt:payment-extension, plus a RoktSdkPlus
  version constant. The mParticle Rokt kit deliberately omits the payment extension;
  this umbrella is what adds it on top.
- Published as com.rokt:rokt-sdk-plus via an isolated settings-rokt-sdk-plus.gradle so
  it builds/publishes in its own Gradle invocation with Rokt Maven Central credentials.
- Centralize the Rokt SDK / payment extension versions in gradle.properties
  (roktSdkVersion, roktPaymentExtensionVersion); the Rokt kit now reads roktSdkVersion.
- Extend the publish convention plugin with optional POM url/license overrides
  (backward-compatible) so the com.rokt artifact carries Rokt branding.
- release-publish.yml: publish the Rokt kit to mavenLocal so the umbrella resolves its
  mParticle deps locally (avoiding Maven Central propagation races), then publish the
  umbrella to Central with the Rokt credentials.

The umbrella version tracks the mParticle SDK line; the bundled Rokt artifacts ride
their own line.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* feat: extend Rokt kit Kotlin example for joint SDK testing (#736)

* feat: extend Rokt kit Kotlin example for joint SDK testing

* fix: use NoActionBar theme and inset-aware layout in Rokt kit example

* feat: add runtime credential switching and bottom sheet button to Rokt kit example

* feat: build Rokt kit example against rokt-sdk-plus umbrella

Depend on the single com.rokt:rokt-sdk-plus umbrella instead of wiring
android-core + android-rokt-kit by hand. Bump AGP to 8.9.1 and compileSdk
to 36 (required by the payment-extension Compose deps the umbrella pulls
in), and pin the mParticle chain to the umbrella version so the kit's
dynamic android-kit-base version resolves from Maven Local.

---------

Signed-off-by: James Newman <james.newman@rokt.com>
Signed-off-by: denischilik <denis.chilik@rokt.com>
Signed-off-by: Nickolas Dimitrakas <nickolas.dimitrakas@rokt.com>
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: James Newman <james.newman@rokt.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Thomson Thomas <125323226+thomson-t@users.noreply.github.com>
Co-authored-by: mParticle Bot User <developers@mparticle.com>
Co-authored-by: Thomson Thomas <thomson.thomas@rokt.com>
Co-authored-by: Nickolas Dimitrakas <nickolas.dimitrakas@rokt.com>
Co-authored-by: Robert Ing <ring@mparticle.com>
Co-authored-by: junias-rokt <junias.ngoyi@rokt.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: ankitsingh08 <ankit.tomar08@gmail.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.

7 participants