diff --git a/android/fastlane/Fastfile b/android/fastlane/Fastfile index 811d7d07e..66e97bd3d 100644 --- a/android/fastlane/Fastfile +++ b/android/fastlane/Fastfile @@ -30,10 +30,11 @@ platform :android do track: track, json_key_data: ENV["PLAY_STORE_CONFIG_JSON"] )[0].to_i - build_name = last_git_tag.gsub("v", "").split("-").first + sentry_release = last_git_tag.gsub("v", "") + build_name = sentry_release.split("-").first # Add: --obfuscate --split-debug-info=build/app/outputs/symbols # Note: We run `cd ..` first, so paths are relative to repository root. - sh "cd .. && flutter build appbundle --verbose --release --obfuscate --split-debug-info=build/app/outputs/symbols --dart-define=SERVER_URL=$SERVER_URL --build-number=#{latest_build_number+1} --build-name=#{build_name}" + sh "cd .. && flutter build appbundle --verbose --release --obfuscate --split-debug-info=build/app/outputs/symbols --dart-define=SERVER_URL=$SERVER_URL --dart-define=SENTRY_RELEASE=#{sentry_release} --build-number=#{latest_build_number+1} --build-name=#{build_name}" upload_to_play_store( json_key_data: ENV["PLAY_STORE_CONFIG_JSON"], track: track, diff --git a/core/lib/utils/sentry/sentry_config.dart b/core/lib/utils/sentry/sentry_config.dart index 875de64a7..aaa9a7660 100644 --- a/core/lib/utils/sentry/sentry_config.dart +++ b/core/lib/utils/sentry/sentry_config.dart @@ -78,24 +78,40 @@ class SentryConfig { && sentryEnvironment.trim().isNotEmpty; if (!isConfigValid) return null; - final appVersion = await ApplicationManager().getAppVersion(); + final release = await _resolveRelease(); const sentryDist = String.fromEnvironment('SENTRY_DIST'); logTrace( 'SentryConfig::load: sentryDist is $sentryDist, ' - 'appVersion is $appVersion', + 'release is $release', webConsoleEnabled: true, ); return SentryConfig( dsn: sentryDSN, environment: sentryEnvironment, - release: appVersion, + release: release, isAvailable: isAvailable, dist: sentryDist.isNotEmpty ? sentryDist : null, ); } + /// Resolves the Sentry release string. + /// + /// Priority: + /// 1. `--dart-define=SENTRY_RELEASE=` injected at build time by + /// Fastlane/CI — guarantees the same string the CI uses to upload symbols. + /// 2. `PackageInfo.version` as fallback (local dev / non-release builds). + /// + /// Why dart-define takes priority: iOS CFBundleShortVersionString strips + /// pre-release suffixes (e.g. "0.28.3-rc09" → "0.28.3"), so PackageInfo + /// returns a different value than what CI tags the symbols with. + static Future _resolveRelease() async { + const dartDefineRelease = String.fromEnvironment('SENTRY_RELEASE'); + if (dartDefineRelease.isNotEmpty) return dartDefineRelease; + return ApplicationManager().getAppVersion(); + } + static const String sentryConfigKeyChain = 'sentry_config_data'; Map toJson() { diff --git a/ios/fastlane/Fastfile b/ios/fastlane/Fastfile index c83b883da..4f785d7ed 100644 --- a/ios/fastlane/Fastfile +++ b/ios/fastlane/Fastfile @@ -50,11 +50,19 @@ platform :ios do increment_version_number( version_number: last_git_tag.gsub("v", "").split("-").first ) + # Pass the full release tag (e.g. "0.28.3-rc09") to the Dart layer so the + # app reports the same string to Sentry as CI uses when uploading dSYMs. + # This is separate from increment_version_number (which stays numeric for + # App Store compatibility). Each dart-define must be base64-encoded. + require 'base64' + sentry_release = last_git_tag.gsub("v", "") + sentry_release_define = Base64.strict_encode64("SENTRY_RELEASE=#{sentry_release}") build_app( scheme: "Runner", configuration: "Release", workspace: "Runner.xcworkspace", - export_method: "app-store" + export_method: "app-store", + xcargs: "DART_DEFINES=#{sentry_release_define}", ) upload_to_testflight( skip_waiting_for_build_processing: true, diff --git a/lib/features/mailbox_dashboard/domain/linagora_ecosystem/sentry_config_linagora_ecosystem.dart b/lib/features/mailbox_dashboard/domain/linagora_ecosystem/sentry_config_linagora_ecosystem.dart index 7f13757b2..43ba8f6bf 100644 --- a/lib/features/mailbox_dashboard/domain/linagora_ecosystem/sentry_config_linagora_ecosystem.dart +++ b/lib/features/mailbox_dashboard/domain/linagora_ecosystem/sentry_config_linagora_ecosystem.dart @@ -41,12 +41,15 @@ class SentryConfigLinagoraEcosystem extends LinagoraEcosystemProperties { extension SentryConfigLinagoraEcosystemExtension on SentryConfigLinagoraEcosystem { Future toSentryConfig() async { - final appVersion = await ApplicationManager().getAppVersion(); + const dartDefineRelease = String.fromEnvironment('SENTRY_RELEASE'); + final release = dartDefineRelease.isNotEmpty + ? dartDefineRelease + : await ApplicationManager().getAppVersion(); return SentryConfig( dsn: dsn ?? '', environment: environment ?? '', - release: appVersion, + release: release, isAvailable: enabled ?? false, ); }