From b1390f8025a1b1fba40a26877f0d735ba874618b Mon Sep 17 00:00:00 2001 From: Nelson Osacky Date: Fri, 30 Jan 2026 16:37:45 +0100 Subject: [PATCH 1/3] feat(distribution): Add installGroupsOverride parameter to distribution options Allows filtering distribution updates by install groups. Users can now configure installGroupsOverride in SentryOptions.DistributionOptions to restrict updates to specific install groups. Co-Authored-By: Claude Sonnet 4.5 --- .../io/sentry/android/distribution/DistributionIntegration.kt | 1 + sentry/api/sentry.api | 1 + sentry/src/main/java/io/sentry/SentryOptions.java | 3 +++ 3 files changed, 5 insertions(+) diff --git a/sentry-android-distribution/src/main/java/io/sentry/android/distribution/DistributionIntegration.kt b/sentry-android-distribution/src/main/java/io/sentry/android/distribution/DistributionIntegration.kt index daf702263ff..4a53b557a03 100644 --- a/sentry-android-distribution/src/main/java/io/sentry/android/distribution/DistributionIntegration.kt +++ b/sentry-android-distribution/src/main/java/io/sentry/android/distribution/DistributionIntegration.kt @@ -150,6 +150,7 @@ public class DistributionIntegration(context: Context) : Integration, IDistribut versionCode = versionCode, versionName = versionName, buildConfiguration = buildConfiguration, + installGroupsOverride = sentryOptions.distribution.installGroupsOverride, ) } catch (e: PackageManager.NameNotFoundException) { sentryOptions.logger.log(SentryLevel.ERROR, e, "Failed to get package info") diff --git a/sentry/api/sentry.api b/sentry/api/sentry.api index 7020c8e216d..8a31fdaca73 100644 --- a/sentry/api/sentry.api +++ b/sentry/api/sentry.api @@ -3754,6 +3754,7 @@ public final class io/sentry/SentryOptions$Cron { public final class io/sentry/SentryOptions$DistributionOptions { public field buildConfiguration Ljava/lang/String; + public field installGroupsOverride Ljava/util/List; public field orgAuthToken Ljava/lang/String; public field orgSlug Ljava/lang/String; public field projectSlug Ljava/lang/String; diff --git a/sentry/src/main/java/io/sentry/SentryOptions.java b/sentry/src/main/java/io/sentry/SentryOptions.java index c370672dd97..f4cff584b6f 100644 --- a/sentry/src/main/java/io/sentry/SentryOptions.java +++ b/sentry/src/main/java/io/sentry/SentryOptions.java @@ -664,6 +664,9 @@ public static final class DistributionOptions { /** Optional build configuration name for filtering (e.g., "debug", "release", "staging") */ public @Nullable String buildConfiguration = null; + + /** Optional install groups for filtering updates */ + public @Nullable List installGroupsOverride = null; } private @NotNull DistributionOptions distribution = new DistributionOptions(); From ac0f14b288f6dc791075c50e5aff451d48922a7d Mon Sep 17 00:00:00 2001 From: Nelson Osacky Date: Fri, 30 Jan 2026 16:50:20 +0100 Subject: [PATCH 2/3] feat(distribution): Read installGroupsOverride from properties file Adds support for reading installGroupsOverride from sentry-distribution.properties file at runtime. This allows the Gradle plugin to configure install groups that will be automatically loaded when the SDK initializes. The property supports comma-separated values: io.sentry.distribution.install-groups-override=internal,beta-testers,qa Co-Authored-By: Claude Sonnet 4.5 --- .../util/DebugMetaPropertiesApplier.java | 30 ++++++- .../util/DebugMetaPropertiesApplierTest.kt | 83 +++++++++++++++++++ 2 files changed, 112 insertions(+), 1 deletion(-) diff --git a/sentry/src/main/java/io/sentry/util/DebugMetaPropertiesApplier.java b/sentry/src/main/java/io/sentry/util/DebugMetaPropertiesApplier.java index a6ff901b907..8bb89fbcd8e 100644 --- a/sentry/src/main/java/io/sentry/util/DebugMetaPropertiesApplier.java +++ b/sentry/src/main/java/io/sentry/util/DebugMetaPropertiesApplier.java @@ -98,11 +98,14 @@ private static void applyDistributionOptions( final @Nullable String projectSlug = getDistributionProjectSlug(properties); final @Nullable String orgAuthToken = getDistributionAuthToken(properties); final @Nullable String buildConfiguration = getDistributionBuildConfiguration(properties); + final @Nullable String installGroupsOverride = + getDistributionInstallGroupsOverride(properties); if (orgSlug != null || projectSlug != null || orgAuthToken != null - || buildConfiguration != null) { + || buildConfiguration != null + || installGroupsOverride != null) { final @NotNull SentryOptions.DistributionOptions distributionOptions = options.getDistribution(); @@ -139,6 +142,26 @@ private static void applyDistributionOptions( distributionOptions.buildConfiguration = buildConfiguration; } + if (installGroupsOverride != null + && !installGroupsOverride.isEmpty() + && distributionOptions.installGroupsOverride == null) { + final @NotNull String[] groups = installGroupsOverride.split(",", -1); + final @NotNull List groupList = new java.util.ArrayList<>(); + for (final String group : groups) { + final String trimmedGroup = group.trim(); + if (!trimmedGroup.isEmpty()) { + groupList.add(trimmedGroup); + } + } + if (!groupList.isEmpty()) { + options + .getLogger() + .log( + SentryLevel.DEBUG, "Distribution install groups override found: %s", groupList); + distributionOptions.installGroupsOverride = groupList; + } + } + // We only process the first properties file that contains distribution options // to maintain consistency with other properties like proguardUuid break; @@ -165,4 +188,9 @@ private static void applyDistributionOptions( final @NotNull Properties debugMetaProperties) { return debugMetaProperties.getProperty("io.sentry.distribution.build-configuration"); } + + private static @Nullable String getDistributionInstallGroupsOverride( + final @NotNull Properties debugMetaProperties) { + return debugMetaProperties.getProperty("io.sentry.distribution.install-groups-override"); + } } diff --git a/sentry/src/test/java/io/sentry/util/DebugMetaPropertiesApplierTest.kt b/sentry/src/test/java/io/sentry/util/DebugMetaPropertiesApplierTest.kt index 63c8a62c913..ab06c851f8c 100644 --- a/sentry/src/test/java/io/sentry/util/DebugMetaPropertiesApplierTest.kt +++ b/sentry/src/test/java/io/sentry/util/DebugMetaPropertiesApplierTest.kt @@ -138,4 +138,87 @@ class DebugMetaPropertiesApplierTest { assertEquals("", options.distribution.orgAuthToken) assertNull(options.distribution.buildConfiguration) } + + @Test + fun `applies installGroupsOverride from properties`() { + val properties = Properties() + properties.setProperty( + "io.sentry.distribution.install-groups-override", + "internal,beta-testers", + ) + + val options = SentryOptions() + DebugMetaPropertiesApplier.apply(options, listOf(properties)) + + assertEquals(listOf("internal", "beta-testers"), options.distribution.installGroupsOverride) + } + + @Test + fun `applies installGroupsOverride with trimming`() { + val properties = Properties() + properties.setProperty( + "io.sentry.distribution.install-groups-override", + " internal , beta-testers , qa ", + ) + + val options = SentryOptions() + DebugMetaPropertiesApplier.apply(options, listOf(properties)) + + assertEquals( + listOf("internal", "beta-testers", "qa"), + options.distribution.installGroupsOverride, + ) + } + + @Test + fun `applies single installGroupsOverride value`() { + val properties = Properties() + properties.setProperty("io.sentry.distribution.install-groups-override", "internal") + + val options = SentryOptions() + DebugMetaPropertiesApplier.apply(options, listOf(properties)) + + assertEquals(listOf("internal"), options.distribution.installGroupsOverride) + } + + @Test + fun `does not override existing installGroupsOverride`() { + val properties = Properties() + properties.setProperty("io.sentry.distribution.install-groups-override", "properties-group") + + val options = SentryOptions() + options.distribution.installGroupsOverride = listOf("existing-group") + + DebugMetaPropertiesApplier.apply(options, listOf(properties)) + + assertEquals(listOf("existing-group"), options.distribution.installGroupsOverride) + } + + @Test + fun `does not apply empty installGroupsOverride`() { + val properties = Properties() + properties.setProperty("io.sentry.distribution.install-groups-override", "") + + val options = SentryOptions() + DebugMetaPropertiesApplier.apply(options, listOf(properties)) + + assertNull(options.distribution.installGroupsOverride) + } + + @Test + fun `ignores empty values in installGroupsOverride list`() { + val properties = Properties() + properties.setProperty( + "io.sentry.distribution.install-groups-override", + "internal,,beta-testers, ,qa", + ) + + val options = SentryOptions() + DebugMetaPropertiesApplier.apply(options, listOf(properties)) + + assertEquals( + listOf("internal", "beta-testers", "qa"), + options.distribution.installGroupsOverride, + ) + } } From e997d5a2a43cb340d480cdf043c678b56df19db6 Mon Sep 17 00:00:00 2001 From: Nelson Osacky Date: Fri, 30 Jan 2026 17:33:29 +0100 Subject: [PATCH 3/3] docs(changelog): Update entry for installGroupsOverride feature Split the combined changelog entry to properly attribute the installGroupsOverride parameter to this PR (#5066) and separate it from the installGroups property added in PR #5062. Co-Authored-By: Claude Sonnet 4.5 --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 72431094bca..3edd3e447e3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,8 @@ ### Features -- Add `installGroupsOverride` parameter and `installGroups` property to Build Distribution SDK ([#5062](https://github.com/getsentry/sentry-java/pull/5062)) +- Add `installGroupsOverride` parameter to Build Distribution SDK for programmatic filtering, with support for configuration via properties file using `io.sentry.distribution.install-groups-override` ([#5066](https://github.com/getsentry/sentry-java/pull/5066)) +- Add `installGroups` property to Build Distribution SDK ([#5062](https://github.com/getsentry/sentry-java/pull/5062)) - Update Android targetSdk to API 36 (Android 16) ([#5016](https://github.com/getsentry/sentry-java/pull/5016)) - Add AndroidManifest support for Spotlight configuration via `io.sentry.spotlight.enable` and `io.sentry.spotlight.url` ([#5064](https://github.com/getsentry/sentry-java/pull/5064))