TF-4269 Fix Sentry release version sync across platforms

Use --dart-define=SENTRY_RELEASE=<full-tag> in Fastlane so the app
reports the same version string to Sentry as CI uses when uploading
symbols, bypassing iOS CFBundleShortVersionString stripping.

- Android Fastfile: add --dart-define=SENTRY_RELEASE (build-name unchanged)
- iOS Fastfile: pass DART_DEFINES via xcargs (increment_version_number unchanged)
- Dart: read SENTRY_RELEASE dart-define first, fall back to PackageInfo.version
- NSE/Web unaffected: NSE reads from Keychain, Web falls back to PackageInfo
This commit is contained in:
dab246
2026-04-21 15:15:32 +07:00
parent be7c39018b
commit 99b68d1fc5
4 changed files with 36 additions and 8 deletions
+3 -2
View File
@@ -30,10 +30,11 @@ platform :android do
track: track, track: track,
json_key_data: ENV["PLAY_STORE_CONFIG_JSON"] json_key_data: ENV["PLAY_STORE_CONFIG_JSON"]
)[0].to_i )[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 # Add: --obfuscate --split-debug-info=build/app/outputs/symbols
# Note: We run `cd ..` first, so paths are relative to repository root. # 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( upload_to_play_store(
json_key_data: ENV["PLAY_STORE_CONFIG_JSON"], json_key_data: ENV["PLAY_STORE_CONFIG_JSON"],
track: track, track: track,
+19 -3
View File
@@ -78,24 +78,40 @@ class SentryConfig {
&& sentryEnvironment.trim().isNotEmpty; && sentryEnvironment.trim().isNotEmpty;
if (!isConfigValid) return null; if (!isConfigValid) return null;
final appVersion = await ApplicationManager().getAppVersion(); final release = await _resolveRelease();
const sentryDist = String.fromEnvironment('SENTRY_DIST'); const sentryDist = String.fromEnvironment('SENTRY_DIST');
logTrace( logTrace(
'SentryConfig::load: sentryDist is $sentryDist, ' 'SentryConfig::load: sentryDist is $sentryDist, '
'appVersion is $appVersion', 'release is $release',
webConsoleEnabled: true, webConsoleEnabled: true,
); );
return SentryConfig( return SentryConfig(
dsn: sentryDSN, dsn: sentryDSN,
environment: sentryEnvironment, environment: sentryEnvironment,
release: appVersion, release: release,
isAvailable: isAvailable, isAvailable: isAvailable,
dist: sentryDist.isNotEmpty ? sentryDist : null, dist: sentryDist.isNotEmpty ? sentryDist : null,
); );
} }
/// Resolves the Sentry release string.
///
/// Priority:
/// 1. `--dart-define=SENTRY_RELEASE=<version>` 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<String> _resolveRelease() async {
const dartDefineRelease = String.fromEnvironment('SENTRY_RELEASE');
if (dartDefineRelease.isNotEmpty) return dartDefineRelease;
return ApplicationManager().getAppVersion();
}
static const String sentryConfigKeyChain = 'sentry_config_data'; static const String sentryConfigKeyChain = 'sentry_config_data';
Map<String, dynamic> toJson() { Map<String, dynamic> toJson() {
+9 -1
View File
@@ -50,11 +50,19 @@ platform :ios do
increment_version_number( increment_version_number(
version_number: last_git_tag.gsub("v", "").split("-").first 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( build_app(
scheme: "Runner", scheme: "Runner",
configuration: "Release", configuration: "Release",
workspace: "Runner.xcworkspace", workspace: "Runner.xcworkspace",
export_method: "app-store" export_method: "app-store",
xcargs: "DART_DEFINES=#{sentry_release_define}",
) )
upload_to_testflight( upload_to_testflight(
skip_waiting_for_build_processing: true, skip_waiting_for_build_processing: true,
@@ -41,12 +41,15 @@ class SentryConfigLinagoraEcosystem extends LinagoraEcosystemProperties {
extension SentryConfigLinagoraEcosystemExtension on SentryConfigLinagoraEcosystem { extension SentryConfigLinagoraEcosystemExtension on SentryConfigLinagoraEcosystem {
Future<SentryConfig> toSentryConfig() async { Future<SentryConfig> toSentryConfig() async {
final appVersion = await ApplicationManager().getAppVersion(); const dartDefineRelease = String.fromEnvironment('SENTRY_RELEASE');
final release = dartDefineRelease.isNotEmpty
? dartDefineRelease
: await ApplicationManager().getAppVersion();
return SentryConfig( return SentryConfig(
dsn: dsn ?? '', dsn: dsn ?? '',
environment: environment ?? '', environment: environment ?? '',
release: appVersion, release: release,
isAvailable: enabled ?? false, isAvailable: enabled ?? false,
); );
} }