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.
This commit is contained in:
Jorge Martin Espinosa
2025-01-29 13:47:06 +01:00
committed by GitHub
parent 2150eaa504
commit c935783a78
11 changed files with 52 additions and 14 deletions

View File

@@ -45,6 +45,7 @@ jobs:
ELEMENT_ANDROID_MAPTILER_API_KEY: ${{ secrets.MAPTILER_KEY }} ELEMENT_ANDROID_MAPTILER_API_KEY: ${{ secrets.MAPTILER_KEY }}
ELEMENT_ANDROID_MAPTILER_LIGHT_MAP_ID: ${{ secrets.MAPTILER_LIGHT_MAP_ID }} ELEMENT_ANDROID_MAPTILER_LIGHT_MAP_ID: ${{ secrets.MAPTILER_LIGHT_MAP_ID }}
ELEMENT_ANDROID_MAPTILER_DARK_MAP_ID: ${{ secrets.MAPTILER_DARK_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 run: ./gradlew :app:assembleGplayDebug app:assembleFDroidDebug -PallWarningsAsErrors=true $CI_GRADLE_ARG_PROPERTIES
- name: Upload debug APKs - name: Upload debug APKs
if: ${{ matrix.variant == 'debug' }} if: ${{ matrix.variant == 'debug' }}

View File

@@ -53,6 +53,7 @@ jobs:
ELEMENT_ANDROID_MAPTILER_API_KEY: ${{ secrets.MAPTILER_KEY }} ELEMENT_ANDROID_MAPTILER_API_KEY: ${{ secrets.MAPTILER_KEY }}
ELEMENT_ANDROID_MAPTILER_LIGHT_MAP_ID: ${{ secrets.MAPTILER_LIGHT_MAP_ID }} ELEMENT_ANDROID_MAPTILER_LIGHT_MAP_ID: ${{ secrets.MAPTILER_LIGHT_MAP_ID }}
ELEMENT_ANDROID_MAPTILER_DARK_MAP_ID: ${{ secrets.MAPTILER_DARK_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 run: ./gradlew :app:assembleGplayDebug -PallWarningsAsErrors=true $CI_GRADLE_ARG_PROPERTIES
- name: Upload debug Enterprise APKs - name: Upload debug Enterprise APKs
if: ${{ matrix.variant == 'debug' }} if: ${{ matrix.variant == 'debug' }}

View File

@@ -29,6 +29,7 @@ jobs:
ELEMENT_ANDROID_MAPTILER_API_KEY: ${{ secrets.MAPTILER_KEY }} ELEMENT_ANDROID_MAPTILER_API_KEY: ${{ secrets.MAPTILER_KEY }}
ELEMENT_ANDROID_MAPTILER_LIGHT_MAP_ID: ${{ secrets.MAPTILER_LIGHT_MAP_ID }} ELEMENT_ANDROID_MAPTILER_LIGHT_MAP_ID: ${{ secrets.MAPTILER_LIGHT_MAP_ID }}
ELEMENT_ANDROID_MAPTILER_DARK_MAP_ID: ${{ secrets.MAPTILER_DARK_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_KEYID: ${{ secrets.ELEMENT_ANDROID_NIGHTLY_KEYID }}
ELEMENT_ANDROID_NIGHTLY_KEYPASSWORD: ${{ secrets.ELEMENT_ANDROID_NIGHTLY_KEYPASSWORD }} ELEMENT_ANDROID_NIGHTLY_KEYPASSWORD: ${{ secrets.ELEMENT_ANDROID_NIGHTLY_KEYPASSWORD }}
ELEMENT_ANDROID_NIGHTLY_STOREPASSWORD: ${{ secrets.ELEMENT_ANDROID_NIGHTLY_STOREPASSWORD }} ELEMENT_ANDROID_NIGHTLY_STOREPASSWORD: ${{ secrets.ELEMENT_ANDROID_NIGHTLY_STOREPASSWORD }}

View File

@@ -35,6 +35,7 @@ jobs:
ELEMENT_ANDROID_MAPTILER_API_KEY: ${{ secrets.MAPTILER_KEY }} ELEMENT_ANDROID_MAPTILER_API_KEY: ${{ secrets.MAPTILER_KEY }}
ELEMENT_ANDROID_MAPTILER_LIGHT_MAP_ID: ${{ secrets.MAPTILER_LIGHT_MAP_ID }} ELEMENT_ANDROID_MAPTILER_LIGHT_MAP_ID: ${{ secrets.MAPTILER_LIGHT_MAP_ID }}
ELEMENT_ANDROID_MAPTILER_DARK_MAP_ID: ${{ secrets.MAPTILER_DARK_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_KEYID: ${{ secrets.ELEMENT_ANDROID_NIGHTLY_KEYID }}
ELEMENT_ANDROID_NIGHTLY_KEYPASSWORD: ${{ secrets.ELEMENT_ANDROID_NIGHTLY_KEYPASSWORD }} ELEMENT_ANDROID_NIGHTLY_KEYPASSWORD: ${{ secrets.ELEMENT_ANDROID_NIGHTLY_KEYPASSWORD }}
ELEMENT_ANDROID_NIGHTLY_STOREPASSWORD: ${{ secrets.ELEMENT_ANDROID_NIGHTLY_STOREPASSWORD }} ELEMENT_ANDROID_NIGHTLY_STOREPASSWORD: ${{ secrets.ELEMENT_ANDROID_NIGHTLY_STOREPASSWORD }}

View File

@@ -31,6 +31,7 @@ jobs:
ELEMENT_ANDROID_MAPTILER_API_KEY: ${{ secrets.MAPTILER_KEY }} ELEMENT_ANDROID_MAPTILER_API_KEY: ${{ secrets.MAPTILER_KEY }}
ELEMENT_ANDROID_MAPTILER_LIGHT_MAP_ID: ${{ secrets.MAPTILER_LIGHT_MAP_ID }} ELEMENT_ANDROID_MAPTILER_LIGHT_MAP_ID: ${{ secrets.MAPTILER_LIGHT_MAP_ID }}
ELEMENT_ANDROID_MAPTILER_DARK_MAP_ID: ${{ secrets.MAPTILER_DARK_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 run: ./gradlew bundleGplayRelease $CI_GRADLE_ARG_PROPERTIES
- name: Upload bundle as artifact - name: Upload bundle as artifact
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4

View File

@@ -2,10 +2,16 @@
<!--- TOC --> <!--- TOC -->
* [TODO](#todo) * [Sentry](#sentry)
<!--- END --> <!--- END -->
## 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
```

View File

@@ -5,20 +5,13 @@
* Please see LICENSE files in the repository root for full details. * Please see LICENSE files in the repository root for full details.
*/ */
import java.util.Properties import extension.readLocalProperty
plugins { plugins {
id("io.element.android-compose-library") id("io.element.android-compose-library")
id("kotlin-parcelize") 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 { android {
namespace = "io.element.android.features.location.api" namespace = "io.element.android.features.location.api"

View File

@@ -13,6 +13,7 @@ import org.gradle.api.provider.ValueSourceParameters
import org.gradle.process.ExecOperations import org.gradle.process.ExecOperations
import java.io.ByteArrayOutputStream import java.io.ByteArrayOutputStream
import java.io.IOException import java.io.IOException
import java.util.Properties
import javax.inject.Inject import javax.inject.Inject
abstract class GitRevisionValueSource : ValueSource<String, ValueSourceParameters.None> { abstract class GitRevisionValueSource : ValueSource<String, ValueSourceParameters.None> {
@@ -47,3 +48,10 @@ private fun ExecOperations.runCommand(cmd: String): String {
} }
return String(outputStream.toByteArray()).trim() 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)

View File

@@ -1,3 +1,4 @@
import extension.readLocalProperty
import extension.setupAnvil import extension.setupAnvil
/* /*
@@ -12,6 +13,21 @@ plugins {
android { android {
namespace = "io.element.android.services.analyticsproviders.sentry" 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() setupAnvil()

View File

@@ -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.api.AnalyticsProvider
import io.element.android.services.analyticsproviders.sentry.log.analyticsTag import io.element.android.services.analyticsproviders.sentry.log.analyticsTag
import io.sentry.Sentry import io.sentry.Sentry
import io.sentry.SentryLevel
import io.sentry.SentryOptions import io.sentry.SentryOptions
import io.sentry.android.core.SentryAndroid import io.sentry.android.core.SentryAndroid
import timber.log.Timber import timber.log.Timber
@@ -35,13 +36,20 @@ class SentryAnalyticsProvider @Inject constructor(
override fun init() { override fun init() {
Timber.tag(analyticsTag.value).d("Initializing Sentry") Timber.tag(analyticsTag.value).d("Initializing Sentry")
if (Sentry.isEnabled()) return 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 -> SentryAndroid.init(context) { options ->
options.dsn = SentryConfig.DNS options.dsn = dsn
options.beforeSend = SentryOptions.BeforeSendCallback { event, _ -> event } options.beforeSend = SentryOptions.BeforeSendCallback { event, _ -> event }
options.tracesSampleRate = 1.0 options.tracesSampleRate = 1.0
options.isEnableUserInteractionTracing = true options.isEnableUserInteractionTracing = true
options.environment = buildMeta.buildType.toSentryEnv() options.environment = buildMeta.buildType.toSentryEnv()
options.diagnosticLevel
} }
} }
@@ -51,9 +59,11 @@ class SentryAnalyticsProvider @Inject constructor(
} }
override fun capture(event: VectorAnalyticsEvent) { override fun capture(event: VectorAnalyticsEvent) {
Sentry.captureMessage("Event: ${event.getName()}", SentryLevel.INFO)
} }
override fun screen(screen: VectorAnalyticsScreen) { override fun screen(screen: VectorAnalyticsScreen) {
Sentry.captureMessage("Screen: ${screen.getName()}", SentryLevel.INFO)
} }
override fun updateUserProperties(userProperties: UserProperties) { override fun updateUserProperties(userProperties: UserProperties) {

View File

@@ -9,7 +9,7 @@ package io.element.android.services.analyticsproviders.sentry
object SentryConfig { object SentryConfig {
const val NAME = "Sentry" 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_DEBUG = "DEBUG"
const val ENV_RELEASE = "RELEASE" const val ENV_RELEASE = "RELEASE"
} }