From c935783a785e5e8e85f048c80fb7908bdc9a5849 Mon Sep 17 00:00:00 2001 From: Jorge Martin Espinosa Date: Wed, 29 Jan 2025 13:47:06 +0100 Subject: [PATCH] Use secret Sentry DSN value (#4210) * Use secret Sentry DSN value. We realised our DSN entry has been shipped along with the code and it was being used in several forks as is, resulting in wrong bug reports coming into our Sentry dashboard and making it very hard to debug actual issues in the app. --- .github/workflows/build.yml | 1 + .github/workflows/build_enterprise.yml | 1 + .github/workflows/nightly.yml | 1 + .github/workflows/nightly_enterprise.yml | 1 + .github/workflows/release.yml | 1 + docs/analytics.md | 12 +++++++++--- features/location/api/build.gradle.kts | 9 +-------- plugins/src/main/kotlin/extension/Utils.kt | 8 ++++++++ .../analyticsproviders/sentry/build.gradle.kts | 16 ++++++++++++++++ .../sentry/SentryAnalyticsProvider.kt | 14 ++++++++++++-- .../analyticsproviders/sentry/SentryConfig.kt | 2 +- 11 files changed, 52 insertions(+), 14 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e0aff05910..a0519385fd 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -45,6 +45,7 @@ jobs: ELEMENT_ANDROID_MAPTILER_API_KEY: ${{ secrets.MAPTILER_KEY }} ELEMENT_ANDROID_MAPTILER_LIGHT_MAP_ID: ${{ secrets.MAPTILER_LIGHT_MAP_ID }} ELEMENT_ANDROID_MAPTILER_DARK_MAP_ID: ${{ secrets.MAPTILER_DARK_MAP_ID }} + ELEMENT_ANDROID_SENTRY_DSN: ${{ secrets.ELEMENT_ANDROID_SENTRY_DSN }} run: ./gradlew :app:assembleGplayDebug app:assembleFDroidDebug -PallWarningsAsErrors=true $CI_GRADLE_ARG_PROPERTIES - name: Upload debug APKs if: ${{ matrix.variant == 'debug' }} diff --git a/.github/workflows/build_enterprise.yml b/.github/workflows/build_enterprise.yml index 4370c75d0c..9182a9af3c 100644 --- a/.github/workflows/build_enterprise.yml +++ b/.github/workflows/build_enterprise.yml @@ -53,6 +53,7 @@ jobs: ELEMENT_ANDROID_MAPTILER_API_KEY: ${{ secrets.MAPTILER_KEY }} ELEMENT_ANDROID_MAPTILER_LIGHT_MAP_ID: ${{ secrets.MAPTILER_LIGHT_MAP_ID }} ELEMENT_ANDROID_MAPTILER_DARK_MAP_ID: ${{ secrets.MAPTILER_DARK_MAP_ID }} + ELEMENT_ANDROID_SENTRY_DSN: ${{ secrets.ELEMENT_ANDROID_SENTRY_DSN }} run: ./gradlew :app:assembleGplayDebug -PallWarningsAsErrors=true $CI_GRADLE_ARG_PROPERTIES - name: Upload debug Enterprise APKs if: ${{ matrix.variant == 'debug' }} diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 3ad597e658..465a95bd08 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -29,6 +29,7 @@ jobs: ELEMENT_ANDROID_MAPTILER_API_KEY: ${{ secrets.MAPTILER_KEY }} ELEMENT_ANDROID_MAPTILER_LIGHT_MAP_ID: ${{ secrets.MAPTILER_LIGHT_MAP_ID }} ELEMENT_ANDROID_MAPTILER_DARK_MAP_ID: ${{ secrets.MAPTILER_DARK_MAP_ID }} + ELEMENT_ANDROID_SENTRY_DSN: ${{ secrets.ELEMENT_ANDROID_SENTRY_DSN }} ELEMENT_ANDROID_NIGHTLY_KEYID: ${{ secrets.ELEMENT_ANDROID_NIGHTLY_KEYID }} ELEMENT_ANDROID_NIGHTLY_KEYPASSWORD: ${{ secrets.ELEMENT_ANDROID_NIGHTLY_KEYPASSWORD }} ELEMENT_ANDROID_NIGHTLY_STOREPASSWORD: ${{ secrets.ELEMENT_ANDROID_NIGHTLY_STOREPASSWORD }} diff --git a/.github/workflows/nightly_enterprise.yml b/.github/workflows/nightly_enterprise.yml index 7d12ac66a8..c7700ed56b 100644 --- a/.github/workflows/nightly_enterprise.yml +++ b/.github/workflows/nightly_enterprise.yml @@ -35,6 +35,7 @@ jobs: ELEMENT_ANDROID_MAPTILER_API_KEY: ${{ secrets.MAPTILER_KEY }} ELEMENT_ANDROID_MAPTILER_LIGHT_MAP_ID: ${{ secrets.MAPTILER_LIGHT_MAP_ID }} ELEMENT_ANDROID_MAPTILER_DARK_MAP_ID: ${{ secrets.MAPTILER_DARK_MAP_ID }} + ELEMENT_ANDROID_SENTRY_DSN: ${{ secrets.ELEMENT_ANDROID_SENTRY_DSN }} ELEMENT_ANDROID_NIGHTLY_KEYID: ${{ secrets.ELEMENT_ANDROID_NIGHTLY_KEYID }} ELEMENT_ANDROID_NIGHTLY_KEYPASSWORD: ${{ secrets.ELEMENT_ANDROID_NIGHTLY_KEYPASSWORD }} ELEMENT_ANDROID_NIGHTLY_STOREPASSWORD: ${{ secrets.ELEMENT_ANDROID_NIGHTLY_STOREPASSWORD }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 99ee377c00..e9de267d3f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -31,6 +31,7 @@ jobs: ELEMENT_ANDROID_MAPTILER_API_KEY: ${{ secrets.MAPTILER_KEY }} ELEMENT_ANDROID_MAPTILER_LIGHT_MAP_ID: ${{ secrets.MAPTILER_LIGHT_MAP_ID }} ELEMENT_ANDROID_MAPTILER_DARK_MAP_ID: ${{ secrets.MAPTILER_DARK_MAP_ID }} + ELEMENT_ANDROID_SENTRY_DSN: ${{ secrets.ELEMENT_ANDROID_SENTRY_DSN }} run: ./gradlew bundleGplayRelease $CI_GRADLE_ARG_PROPERTIES - name: Upload bundle as artifact uses: actions/upload-artifact@v4 diff --git a/docs/analytics.md b/docs/analytics.md index b3f592c227..3113b94650 100644 --- a/docs/analytics.md +++ b/docs/analytics.md @@ -2,10 +2,16 @@ -* [TODO](#todo) +* [Sentry](#sentry) -## TODO +## Sentry -There is no analytics in the project yet. +To make Sentry analytics and bug reporting work, you need to provide a Sentry DSN in the `local.properties` file, or set the `ELEMENT_ANDROID_SENTRY_DSN` environment variable. + +The format used to add the DSN to your `local.properties` file is the following: + +```properties +services.analyticsproviders.sentry.dsn=https://your-sentry-dsn/project-id +``` diff --git a/features/location/api/build.gradle.kts b/features/location/api/build.gradle.kts index 2384632ec3..998529088a 100644 --- a/features/location/api/build.gradle.kts +++ b/features/location/api/build.gradle.kts @@ -5,20 +5,13 @@ * Please see LICENSE files in the repository root for full details. */ -import java.util.Properties +import extension.readLocalProperty plugins { id("io.element.android-compose-library") id("kotlin-parcelize") } -fun readLocalProperty(name: String): String? = Properties().apply { - try { - load(rootProject.file("local.properties").reader()) - } catch (ignored: java.io.IOException) { - } -}.getProperty(name) - android { namespace = "io.element.android.features.location.api" diff --git a/plugins/src/main/kotlin/extension/Utils.kt b/plugins/src/main/kotlin/extension/Utils.kt index 61be232f6c..4d19505704 100644 --- a/plugins/src/main/kotlin/extension/Utils.kt +++ b/plugins/src/main/kotlin/extension/Utils.kt @@ -13,6 +13,7 @@ import org.gradle.api.provider.ValueSourceParameters import org.gradle.process.ExecOperations import java.io.ByteArrayOutputStream import java.io.IOException +import java.util.Properties import javax.inject.Inject abstract class GitRevisionValueSource : ValueSource { @@ -47,3 +48,10 @@ private fun ExecOperations.runCommand(cmd: String): String { } return String(outputStream.toByteArray()).trim() } + +fun Project.readLocalProperty(name: String): String? = Properties().apply { + try { + load(rootProject.file("local.properties").reader()) + } catch (ignored: IOException) { + } +}.getProperty(name) diff --git a/services/analyticsproviders/sentry/build.gradle.kts b/services/analyticsproviders/sentry/build.gradle.kts index c8deb34a7a..e144cb67ea 100644 --- a/services/analyticsproviders/sentry/build.gradle.kts +++ b/services/analyticsproviders/sentry/build.gradle.kts @@ -1,3 +1,4 @@ +import extension.readLocalProperty import extension.setupAnvil /* @@ -12,6 +13,21 @@ plugins { android { namespace = "io.element.android.services.analyticsproviders.sentry" + + buildFeatures { + buildConfig = true + } + + defaultConfig { + buildConfigField( + type = "String", + name = "SENTRY_DSN", + value = (System.getenv("ELEMENT_ANDROID_SENTRY_DSN") + ?: readLocalProperty("services.analyticsproviders.sentry.dsn") + ?: "" + ).let { "\"$it\"" } + ) + } } setupAnvil() diff --git a/services/analyticsproviders/sentry/src/main/kotlin/io/element/android/services/analyticsproviders/sentry/SentryAnalyticsProvider.kt b/services/analyticsproviders/sentry/src/main/kotlin/io/element/android/services/analyticsproviders/sentry/SentryAnalyticsProvider.kt index ecf399416f..3445eba219 100644 --- a/services/analyticsproviders/sentry/src/main/kotlin/io/element/android/services/analyticsproviders/sentry/SentryAnalyticsProvider.kt +++ b/services/analyticsproviders/sentry/src/main/kotlin/io/element/android/services/analyticsproviders/sentry/SentryAnalyticsProvider.kt @@ -20,6 +20,7 @@ import io.element.android.libraries.di.ApplicationContext import io.element.android.services.analyticsproviders.api.AnalyticsProvider import io.element.android.services.analyticsproviders.sentry.log.analyticsTag import io.sentry.Sentry +import io.sentry.SentryLevel import io.sentry.SentryOptions import io.sentry.android.core.SentryAndroid import timber.log.Timber @@ -35,13 +36,20 @@ class SentryAnalyticsProvider @Inject constructor( override fun init() { Timber.tag(analyticsTag.value).d("Initializing Sentry") if (Sentry.isEnabled()) return + + val dsn = if (SentryConfig.DSN.isNotBlank()) { + SentryConfig.DSN + } else { + Timber.w("No Sentry DSN provided, Sentry will not be initialized") + return + } + SentryAndroid.init(context) { options -> - options.dsn = SentryConfig.DNS + options.dsn = dsn options.beforeSend = SentryOptions.BeforeSendCallback { event, _ -> event } options.tracesSampleRate = 1.0 options.isEnableUserInteractionTracing = true options.environment = buildMeta.buildType.toSentryEnv() - options.diagnosticLevel } } @@ -51,9 +59,11 @@ class SentryAnalyticsProvider @Inject constructor( } override fun capture(event: VectorAnalyticsEvent) { + Sentry.captureMessage("Event: ${event.getName()}", SentryLevel.INFO) } override fun screen(screen: VectorAnalyticsScreen) { + Sentry.captureMessage("Screen: ${screen.getName()}", SentryLevel.INFO) } override fun updateUserProperties(userProperties: UserProperties) { diff --git a/services/analyticsproviders/sentry/src/main/kotlin/io/element/android/services/analyticsproviders/sentry/SentryConfig.kt b/services/analyticsproviders/sentry/src/main/kotlin/io/element/android/services/analyticsproviders/sentry/SentryConfig.kt index a8002a67a6..39ade3f9ff 100644 --- a/services/analyticsproviders/sentry/src/main/kotlin/io/element/android/services/analyticsproviders/sentry/SentryConfig.kt +++ b/services/analyticsproviders/sentry/src/main/kotlin/io/element/android/services/analyticsproviders/sentry/SentryConfig.kt @@ -9,7 +9,7 @@ package io.element.android.services.analyticsproviders.sentry object SentryConfig { const val NAME = "Sentry" - const val DNS = "https://32f7ff6a6e724f90838b7654042b2e81@sentry.tools.element.io/59" + const val DSN = BuildConfig.SENTRY_DSN const val ENV_DEBUG = "DEBUG" const val ENV_RELEASE = "RELEASE" }