From 02ff6af31f34bb1d548e32e71b9edb8e930fba87 Mon Sep 17 00:00:00 2001 From: ablaszkiewicz Date: Mon, 31 Aug 2026 19:13:59 +0200 Subject: [PATCH 1/2] feat(gradle-plugin): default release mode to event The proguard mapping uploads release-independent by default, and each event resolves its own release. Set posthog.releaseMode=symbol-set to keep stamping the release onto the mapping. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01Jg6r6rFUBnowrXssZyU7yR --- ...radle-plugin-event-release-mode-default.md | 5 ++ .../PostHogUploadProguardMappingsTask.kt | 7 ++- .../main/kotlin/com/posthog/android/Utils.kt | 4 +- .../posthog/android/PostHogReleaseModeTest.kt | 55 +++++++++++++++++++ 4 files changed, 66 insertions(+), 5 deletions(-) create mode 100644 .changeset/gradle-plugin-event-release-mode-default.md create mode 100644 posthog-android-gradle-plugin/src/test/java/com/posthog/android/PostHogReleaseModeTest.kt diff --git a/.changeset/gradle-plugin-event-release-mode-default.md b/.changeset/gradle-plugin-event-release-mode-default.md new file mode 100644 index 000000000..74f900ac5 --- /dev/null +++ b/.changeset/gradle-plugin-event-release-mode-default.md @@ -0,0 +1,5 @@ +--- +'posthog-android-gradle-plugin': minor +--- + +Default `posthog.releaseMode` to `event`. The proguard mapping is now uploaded release-independent, and each event resolves its own release from the `$app_namespace` / `$app_version` / `$app_build` the SDK already sends, so two releases that ship the same mapping no longer both report whichever release uploaded it first. Set `posthog.releaseMode=symbol-set`, or `POSTHOG_RELEASE_MODE=symbol-set`, to keep stamping the release onto the uploaded mapping. Event mode needs posthog-cli >= 0.12.0, and the release coordinates the build sends have to match the app's applicationId, versionName and versionCode. diff --git a/posthog-android-gradle-plugin/src/main/kotlin/com/posthog/android/PostHogUploadProguardMappingsTask.kt b/posthog-android-gradle-plugin/src/main/kotlin/com/posthog/android/PostHogUploadProguardMappingsTask.kt index 4fd14f3c7..8f521565c 100644 --- a/posthog-android-gradle-plugin/src/main/kotlin/com/posthog/android/PostHogUploadProguardMappingsTask.kt +++ b/posthog-android-gradle-plugin/src/main/kotlin/com/posthog/android/PostHogUploadProguardMappingsTask.kt @@ -105,8 +105,9 @@ public abstract class PostHogUploadProguardMappingsTask : PostHogCliExecTask() { args.add("--build") args.add(it.toString()) } - // Passed only outside the default mode, so a symbol-set build keeps working against a - // posthog-cli predating the flag. + // Passed only outside symbol-set mode, so a symbol-set build keeps working against a + // posthog-cli predating the flag. The environment variable set above pins the mode for + // binaries that do know it. releaseMode.orNull?.takeIf { it != PostHogReleaseMode.SYMBOL_SET.cliValue }?.let { args.add("--release-mode") args.add(it) @@ -122,7 +123,7 @@ public abstract class PostHogUploadProguardMappingsTask : PostHogCliExecTask() { releaseName: Provider? = null, releaseVersion: Provider? = null, build: Provider? = null, - releaseMode: PostHogReleaseMode = PostHogReleaseMode.SYMBOL_SET, + releaseMode: PostHogReleaseMode = PostHogReleaseMode.EVENT, ): TaskProvider { val uploadPostHogProguardMappingsTask = project.tasks.register( diff --git a/posthog-android-gradle-plugin/src/main/kotlin/com/posthog/android/Utils.kt b/posthog-android-gradle-plugin/src/main/kotlin/com/posthog/android/Utils.kt index a322d8233..98e06b9a8 100644 --- a/posthog-android-gradle-plugin/src/main/kotlin/com/posthog/android/Utils.kt +++ b/posthog-android-gradle-plugin/src/main/kotlin/com/posthog/android/Utils.kt @@ -145,7 +145,7 @@ internal enum class PostHogReleaseMode(val cliValue: String) { /** * Release mode for this build: the `posthog.releaseMode` gradle property, then the * `POSTHOG_RELEASE_MODE` environment variable posthog-cli and the bundler plugins already read, - * then [PostHogReleaseMode.SYMBOL_SET]. + * then [PostHogReleaseMode.EVENT]. * * An unrecognized value fails the build rather than falling back, so a typo can't silently leave * a build binding its mapping to a release it meant to keep independent. @@ -157,7 +157,7 @@ internal fun resolvePostHogReleaseMode( val value = project.findProperty(POSTHOG_RELEASE_MODE_PROPERTY)?.toString()?.trim()?.takeIf { it.isNotEmpty() } ?: environment[POSTHOG_RELEASE_MODE_ENV]?.trim()?.takeIf { it.isNotEmpty() } - ?: return PostHogReleaseMode.SYMBOL_SET + ?: return PostHogReleaseMode.EVENT return PostHogReleaseMode.from(value) ?: error( diff --git a/posthog-android-gradle-plugin/src/test/java/com/posthog/android/PostHogReleaseModeTest.kt b/posthog-android-gradle-plugin/src/test/java/com/posthog/android/PostHogReleaseModeTest.kt new file mode 100644 index 000000000..79c71ebf5 --- /dev/null +++ b/posthog-android-gradle-plugin/src/test/java/com/posthog/android/PostHogReleaseModeTest.kt @@ -0,0 +1,55 @@ +package com.posthog.android + +import org.gradle.api.Project +import org.gradle.testfixtures.ProjectBuilder +import org.junit.Test +import kotlin.test.assertEquals +import kotlin.test.assertFailsWith + +internal class PostHogReleaseModeTest { + // Not `apply`: Project has its own apply(), so the scope function would resolve to Gradle's. + private fun project(releaseMode: String? = null): Project { + val project = ProjectBuilder.builder().build() + releaseMode?.let { project.extensions.extraProperties.set(POSTHOG_RELEASE_MODE_PROPERTY, it) } + return project + } + + @Test + fun `a build that configures nothing uploads its mapping release-independent`() { + assertEquals(PostHogReleaseMode.EVENT, resolvePostHogReleaseMode(project(), emptyMap())) + } + + @Test + fun `the gradle property selects the mode`() { + assertEquals( + PostHogReleaseMode.SYMBOL_SET, + resolvePostHogReleaseMode(project(releaseMode = "symbol-set"), emptyMap()), + ) + } + + @Test + fun `the environment variable selects the mode`() { + assertEquals( + PostHogReleaseMode.SYMBOL_SET, + resolvePostHogReleaseMode(project(), mapOf(POSTHOG_RELEASE_MODE_ENV to "symbol-set")), + ) + } + + @Test + fun `the gradle property wins over the environment variable`() { + assertEquals( + PostHogReleaseMode.SYMBOL_SET, + resolvePostHogReleaseMode( + project(releaseMode = "symbol-set"), + mapOf(POSTHOG_RELEASE_MODE_ENV to "event"), + ), + ) + } + + @Test + fun `an unrecognized value fails the build instead of picking a mode`() { + assertFailsWith { + resolvePostHogReleaseMode(project(releaseMode = "symbolset"), emptyMap()) + } + } +} From dc15f4001fa72baaed2f5489539ed37704c1d3ff Mon Sep 17 00:00:00 2001 From: ablaszkiewicz Date: Tue, 1 Sep 2026 13:05:38 +0200 Subject: [PATCH 2/2] chore(gradle-plugin): name the posthog-cli version that accepts the flag The release note said 0.12.0. That version rejects --release-mode on proguard upload. 0.13.0 added the flag. 0.11.0 added it to the sourcemap commands, which is where the wrong number came from. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01Jg6r6rFUBnowrXssZyU7yR --- .changeset/gradle-plugin-event-release-mode-default.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.changeset/gradle-plugin-event-release-mode-default.md b/.changeset/gradle-plugin-event-release-mode-default.md index 74f900ac5..e202b5b37 100644 --- a/.changeset/gradle-plugin-event-release-mode-default.md +++ b/.changeset/gradle-plugin-event-release-mode-default.md @@ -2,4 +2,8 @@ 'posthog-android-gradle-plugin': minor --- -Default `posthog.releaseMode` to `event`. The proguard mapping is now uploaded release-independent, and each event resolves its own release from the `$app_namespace` / `$app_version` / `$app_build` the SDK already sends, so two releases that ship the same mapping no longer both report whichever release uploaded it first. Set `posthog.releaseMode=symbol-set`, or `POSTHOG_RELEASE_MODE=symbol-set`, to keep stamping the release onto the uploaded mapping. Event mode needs posthog-cli >= 0.12.0, and the release coordinates the build sends have to match the app's applicationId, versionName and versionCode. +Default `posthog.releaseMode` to `event`. The proguard mapping now uploads release-independent. Each event resolves its own release from the `$app_namespace` / `$app_version` / `$app_build` the SDK already sends. Two releases that ship the same mapping no longer both report whichever release uploaded it first. + +Set `posthog.releaseMode=symbol-set`, or `POSTHOG_RELEASE_MODE=symbol-set`, to keep stamping the release onto the uploaded mapping. + +Event mode needs posthog-cli 0.13.0 or newer. That version added `--release-mode` to `proguard upload`. The release coordinates the build sends must match the app's applicationId, versionName and versionCode.