From e95475f84539908131c470fc12a8b0bbdf2e4650 Mon Sep 17 00:00:00 2001 From: edde746 <86283021+edde746@users.noreply.github.com> Date: Wed, 22 Apr 2026 12:44:37 +0200 Subject: [PATCH] feat(sentry): symbol upload and hang tracking --- .github/workflows/build.yml | 58 ++++++++++++++++++++++++++---- android/fastlane/Fastfile | 7 ++-- ios/fastlane/Fastfile | 5 ++- lib/main.dart | 2 ++ scripts/upload-symbols.ps1 | 71 +++++++++++++++++++++++++++++++++++++ scripts/upload-symbols.sh | 53 +++++++++++++++++++++++++++ 6 files changed, 185 insertions(+), 11 deletions(-) create mode 100644 scripts/upload-symbols.ps1 create mode 100755 scripts/upload-symbols.sh diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 8746b093..2c648c61 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -64,7 +64,13 @@ jobs: EOF - name: Build APKs - run: flutter build apk --release --split-per-abi --dart-define=ENABLE_UPDATE_CHECK=true ${{ env.SENTRY_DART_DEFINE }} ${{ env.GIT_COMMIT_DART_DEFINE }} ${{ env.SENTRY_ENV_DART_DEFINE }} ${{ env.DONATIONS_DART_DEFINE }} + run: flutter build apk --release --split-per-abi --dart-define=ENABLE_UPDATE_CHECK=true ${{ env.SENTRY_DART_DEFINE }} ${{ env.GIT_COMMIT_DART_DEFINE }} ${{ env.SENTRY_ENV_DART_DEFINE }} ${{ env.DONATIONS_DART_DEFINE }} --obfuscate --split-debug-info=debug-info/android-apk + + - name: Upload symbols to bugs.plezy.app + if: github.repository == 'edde746/plezy' + env: + BUGS_ADMIN_TOKEN: ${{ secrets.BUGS_ADMIN_TOKEN }} + run: ./scripts/upload-symbols.sh android-apk - name: Clean up keystore if: always() @@ -132,7 +138,13 @@ jobs: run: flutter pub get - name: Build iOS (no codesign) - run: flutter build ios --release --no-codesign --dart-define=ENABLE_UPDATE_CHECK=true ${{ env.SENTRY_DART_DEFINE }} ${{ env.GIT_COMMIT_DART_DEFINE }} ${{ env.SENTRY_ENV_DART_DEFINE }} ${{ env.DONATIONS_DART_DEFINE }} + run: flutter build ios --release --no-codesign --dart-define=ENABLE_UPDATE_CHECK=true ${{ env.SENTRY_DART_DEFINE }} ${{ env.GIT_COMMIT_DART_DEFINE }} ${{ env.SENTRY_ENV_DART_DEFINE }} ${{ env.DONATIONS_DART_DEFINE }} --split-debug-info=debug-info/ios + + - name: Upload symbols to bugs.plezy.app + if: github.repository == 'edde746/plezy' + env: + BUGS_ADMIN_TOKEN: ${{ secrets.BUGS_ADMIN_TOKEN }} + run: ./scripts/upload-symbols.sh ios - name: Create IPA run: | @@ -190,7 +202,13 @@ jobs: run: flutter pub get - name: Build macOS - run: flutter build macos --release --dart-define=ENABLE_UPDATE_CHECK=true ${{ env.SENTRY_DART_DEFINE }} ${{ env.GIT_COMMIT_DART_DEFINE }} ${{ env.SENTRY_ENV_DART_DEFINE }} ${{ env.DONATIONS_DART_DEFINE }} + run: flutter build macos --release --dart-define=ENABLE_UPDATE_CHECK=true ${{ env.SENTRY_DART_DEFINE }} ${{ env.GIT_COMMIT_DART_DEFINE }} ${{ env.SENTRY_ENV_DART_DEFINE }} ${{ env.DONATIONS_DART_DEFINE }} --split-debug-info=debug-info/macos + + - name: Upload symbols to bugs.plezy.app + if: github.repository == 'edde746/plezy' + env: + BUGS_ADMIN_TOKEN: ${{ secrets.BUGS_ADMIN_TOKEN }} + run: ./scripts/upload-symbols.sh macos - name: Import Code Signing Certificate env: @@ -341,7 +359,14 @@ jobs: run: flutter pub get - name: Build Windows x64 - run: flutter build windows --release --dart-define=ENABLE_UPDATE_CHECK=true ${{ env.SENTRY_DART_DEFINE }} ${{ env.GIT_COMMIT_DART_DEFINE }} ${{ env.SENTRY_ENV_DART_DEFINE }} ${{ env.DONATIONS_DART_DEFINE }} + run: flutter build windows --release --dart-define=ENABLE_UPDATE_CHECK=true ${{ env.SENTRY_DART_DEFINE }} ${{ env.GIT_COMMIT_DART_DEFINE }} ${{ env.SENTRY_ENV_DART_DEFINE }} ${{ env.DONATIONS_DART_DEFINE }} --split-debug-info=debug-info/windows-x64 + + - name: Upload symbols to bugs.plezy.app + if: github.repository == 'edde746/plezy' + env: + BUGS_ADMIN_TOKEN: ${{ secrets.BUGS_ADMIN_TOKEN }} + shell: pwsh + run: ./scripts/upload-symbols.ps1 windows-x64 - name: Upload x64 build uses: actions/upload-artifact@v4 @@ -378,7 +403,14 @@ jobs: run: flutter pub get - name: Build Windows arm64 - run: flutter build windows --release --dart-define=ENABLE_UPDATE_CHECK=true ${{ env.SENTRY_DART_DEFINE }} ${{ env.GIT_COMMIT_DART_DEFINE }} ${{ env.SENTRY_ENV_DART_DEFINE }} ${{ env.DONATIONS_DART_DEFINE }} + run: flutter build windows --release --dart-define=ENABLE_UPDATE_CHECK=true ${{ env.SENTRY_DART_DEFINE }} ${{ env.GIT_COMMIT_DART_DEFINE }} ${{ env.SENTRY_ENV_DART_DEFINE }} ${{ env.DONATIONS_DART_DEFINE }} --split-debug-info=debug-info/windows-arm64 + + - name: Upload symbols to bugs.plezy.app + if: github.repository == 'edde746/plezy' + env: + BUGS_ADMIN_TOKEN: ${{ secrets.BUGS_ADMIN_TOKEN }} + shell: pwsh + run: ./scripts/upload-symbols.ps1 windows-arm64 - name: Upload arm64 build uses: actions/upload-artifact@v4 @@ -522,10 +554,16 @@ jobs: run: flutter pub get - name: Build Linux x64 - run: flutter build linux --release --dart-define=ENABLE_UPDATE_CHECK=true ${{ env.SENTRY_DART_DEFINE }} ${{ env.GIT_COMMIT_DART_DEFINE }} ${{ env.SENTRY_ENV_DART_DEFINE }} ${{ env.DONATIONS_DART_DEFINE }} + run: flutter build linux --release --dart-define=ENABLE_UPDATE_CHECK=true ${{ env.SENTRY_DART_DEFINE }} ${{ env.GIT_COMMIT_DART_DEFINE }} ${{ env.SENTRY_ENV_DART_DEFINE }} ${{ env.DONATIONS_DART_DEFINE }} --split-debug-info=debug-info/linux-x64 env: PKG_CONFIG_PATH: ${{ github.workspace }}/libmpv-prefix/lib/pkgconfig:${{ github.workspace }}/libmpv-prefix/lib/x86_64-linux-gnu/pkgconfig + - name: Upload symbols to bugs.plezy.app + if: github.repository == 'edde746/plezy' + env: + BUGS_ADMIN_TOKEN: ${{ secrets.BUGS_ADMIN_TOKEN }} + run: ./scripts/upload-symbols.sh linux-x64 + - name: Build Linux Packages run: ARCH_SUFFIX=x64 OUTPUT_DIR=$GITHUB_WORKSPACE python3 linux/packaging/build-packages.py @@ -630,10 +668,16 @@ jobs: run: flutter pub get - name: Build Linux arm64 - run: flutter build linux --release --dart-define=ENABLE_UPDATE_CHECK=true ${{ env.SENTRY_DART_DEFINE }} ${{ env.GIT_COMMIT_DART_DEFINE }} ${{ env.SENTRY_ENV_DART_DEFINE }} ${{ env.DONATIONS_DART_DEFINE }} + run: flutter build linux --release --dart-define=ENABLE_UPDATE_CHECK=true ${{ env.SENTRY_DART_DEFINE }} ${{ env.GIT_COMMIT_DART_DEFINE }} ${{ env.SENTRY_ENV_DART_DEFINE }} ${{ env.DONATIONS_DART_DEFINE }} --split-debug-info=debug-info/linux-arm64 env: PKG_CONFIG_PATH: ${{ github.workspace }}/libmpv-prefix/lib/pkgconfig:${{ github.workspace }}/libmpv-prefix/lib/aarch64-linux-gnu/pkgconfig + - name: Upload symbols to bugs.plezy.app + if: github.repository == 'edde746/plezy' + env: + BUGS_ADMIN_TOKEN: ${{ secrets.BUGS_ADMIN_TOKEN }} + run: ./scripts/upload-symbols.sh linux-arm64 + - name: Find bundle directory id: find-bundle run: | diff --git a/android/fastlane/Fastfile b/android/fastlane/Fastfile index 627989e5..5d082be0 100644 --- a/android/fastlane/Fastfile +++ b/android/fastlane/Fastfile @@ -19,11 +19,11 @@ platform :android do UI.user_error!("Could not extract version from pubspec.yaml") end - debug_info_dir = "./debug-info/#{version_name}+#{version_code}" git_commit = `git rev-parse --short HEAD`.strip # Build the Flutter app - sh("cd #{ENV['PWD']}/.. && flutter build appbundle --dart-define=ENABLE_IN_APP_REVIEW=true --dart-define=ENABLE_SENTRY=true --dart-define=GIT_COMMIT=#{git_commit} --dart-define=SENTRY_ENVIRONMENT=play-store --obfuscate --split-debug-info=#{debug_info_dir}/aab") + sh("cd #{ENV['PWD']}/.. && flutter build appbundle --dart-define=ENABLE_IN_APP_REVIEW=true --dart-define=ENABLE_SENTRY=true --dart-define=GIT_COMMIT=#{git_commit} --dart-define=SENTRY_ENVIRONMENT=play-store --obfuscate --split-debug-info=debug-info/android-aab") + sh("cd #{ENV['PWD']}/.. && ./scripts/upload-symbols.sh android-aab") upload_to_play_store( track: "production", @@ -33,7 +33,8 @@ platform :android do ) # Build universal APK for Amazon Appstore (doesn't accept AABs, excludes x86 via env var) - sh("cd #{ENV['PWD']}/.. && AMAZON=1 flutter build apk --release --dart-define=ENABLE_SENTRY=true --dart-define=GIT_COMMIT=#{git_commit} --dart-define=SENTRY_ENVIRONMENT=amazon --obfuscate --split-debug-info=#{debug_info_dir}/apk") + sh("cd #{ENV['PWD']}/.. && AMAZON=1 flutter build apk --release --dart-define=ENABLE_SENTRY=true --dart-define=GIT_COMMIT=#{git_commit} --dart-define=SENTRY_ENVIRONMENT=amazon --obfuscate --split-debug-info=debug-info/android-apk") + sh("cd #{ENV['PWD']}/.. && ./scripts/upload-symbols.sh android-apk") upload_to_amazon_appstore( apk_paths: [ diff --git a/ios/fastlane/Fastfile b/ios/fastlane/Fastfile index cce5c357..beaf07f8 100644 --- a/ios/fastlane/Fastfile +++ b/ios/fastlane/Fastfile @@ -9,7 +9,10 @@ platform :ios do git_commit = `git rev-parse --short HEAD`.strip # Build the Flutter app - sh("cd #{ENV['PWD']}/.. && flutter build ipa --dart-define=ENABLE_IN_APP_REVIEW=true --dart-define=ENABLE_SENTRY=true --dart-define=GIT_COMMIT=#{git_commit} --dart-define=SENTRY_ENVIRONMENT=app-store") + sh("cd #{ENV['PWD']}/.. && flutter build ipa --dart-define=ENABLE_IN_APP_REVIEW=true --dart-define=ENABLE_SENTRY=true --dart-define=GIT_COMMIT=#{git_commit} --dart-define=SENTRY_ENVIRONMENT=app-store --split-debug-info=debug-info/ios") + + # Upload debug symbols + sh("cd #{ENV['PWD']}/.. && ./scripts/upload-symbols.sh ios") # Upload to App Store upload_to_app_store( diff --git a/lib/main.dart b/lib/main.dart index d43681a6..de2d17d5 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -102,6 +102,8 @@ Future main() async { options.enableAutoSessionTracking = false; options.recordHttpBreadcrumbs = false; options.captureNativeFailedRequests = false; + options.enableAppHangTracking = !kDebugMode; + options.appHangTimeoutInterval = const Duration(seconds: 3); options.beforeSend = _beforeSend; options.beforeBreadcrumb = _beforeBreadcrumb; }, appRunner: _bootstrapApp); diff --git a/scripts/upload-symbols.ps1 b/scripts/upload-symbols.ps1 new file mode 100644 index 00000000..6e165e66 --- /dev/null +++ b/scripts/upload-symbols.ps1 @@ -0,0 +1,71 @@ +#!/usr/bin/env pwsh +# Usage: upload-symbols.ps1 +# Env: BUGS_ADMIN_TOKEN (required), BUGS_URL (default https://bugs.plezy.app) +# Platforms: windows-x64 | windows-arm64 +param( + [Parameter(Mandatory = $true)] + [string]$Platform +) + +$ErrorActionPreference = 'Stop' + +$Token = $env:BUGS_ADMIN_TOKEN +if ([string]::IsNullOrEmpty($Token)) { + Write-Error 'BUGS_ADMIN_TOKEN env var required' + exit 1 +} + +$Url = if ([string]::IsNullOrEmpty($env:BUGS_URL)) { 'https://bugs.plezy.app' } else { $env:BUGS_URL } + +$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Definition +$Root = Split-Path -Parent $ScriptDir +Set-Location $Root + +$Release = "plezy@$(git rev-parse --short HEAD)" +$Stage = New-Item -ItemType Directory -Path ([System.IO.Path]::GetTempPath()) -Name ([System.IO.Path]::GetRandomFileName()) -Force + +try { + $DebugInfoDir = Join-Path $Root "debug-info\$Platform" + if (Test-Path $DebugInfoDir) { + Copy-Item -Path "$DebugInfoDir\*" -Destination $Stage -Recurse -Force + } + + switch ($Platform) { + { $_ -eq 'windows-x64' -or $_ -eq 'windows-arm64' } { + $Arch = $Platform -replace '^windows-', '' + $PdbRoot = Join-Path $Root "build\windows\$Arch\runner\Release" + if (Test-Path $PdbRoot) { + Get-ChildItem -Path $PdbRoot -Filter '*.pdb' -Recurse | ForEach-Object { + Copy-Item $_.FullName -Destination $Stage -Force + } + } + } + default { + Write-Error "unknown platform: $Platform" + exit 2 + } + } + + if (-not (Get-ChildItem -Path $Stage -Force)) { + Write-Error "no symbols found for platform $Platform" + exit 3 + } + + $Zip = Join-Path ([System.IO.Path]::GetTempPath()) "symbols-$([System.IO.Path]::GetRandomFileName()).zip" + Compress-Archive -Path (Join-Path $Stage '*') -DestinationPath $Zip -Force + + $Headers = @{ 'Authorization' = "Bearer $Token" } + $Form = @{ + file = Get-Item $Zip + release = $Release + } + + Invoke-RestMethod -Method Post -Uri "$Url/api/0/projects/plezy/plezy/files/dsyms/" ` + -Headers $Headers -Form $Form +} +finally { + Remove-Item -Path $Stage -Recurse -Force -ErrorAction SilentlyContinue + if ($Zip -and (Test-Path $Zip)) { + Remove-Item -Path $Zip -Force -ErrorAction SilentlyContinue + } +} diff --git a/scripts/upload-symbols.sh b/scripts/upload-symbols.sh new file mode 100755 index 00000000..fa2f468d --- /dev/null +++ b/scripts/upload-symbols.sh @@ -0,0 +1,53 @@ +#!/usr/bin/env bash +# Usage: upload-symbols.sh +# Env: BUGS_ADMIN_TOKEN (required), BUGS_URL (default https://bugs.plezy.app) +# Platforms: macos | ios | android-apk | android-aab | linux-x64 | linux-arm64 +set -euo pipefail + +PLATFORM="${1:?platform arg required}" +TOKEN="${BUGS_ADMIN_TOKEN:?BUGS_ADMIN_TOKEN env var required}" +URL="${BUGS_URL:-https://bugs.plezy.app}" + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" +cd "$ROOT" + +RELEASE="plezy@$(git rev-parse --short HEAD)" +STAGE="$(mktemp -d)" +trap 'rm -rf "$STAGE"' EXIT + +if [ -d "debug-info/${PLATFORM}" ]; then + cp -a "debug-info/${PLATFORM}"/. "$STAGE"/ +fi + +case "$PLATFORM" in + macos) + find build/macos/Build/Products/Release -name '*.dSYM' -exec cp -a {} "$STAGE"/ \; 2>/dev/null || true + ;; + ios) + find build/ios -name '*.dSYM' -exec cp -a {} "$STAGE"/ \; 2>/dev/null || true + ;; + linux-x64|linux-arm64) + find build/linux -path '*/release/bundle/plezy' -exec cp {} "$STAGE"/ \; 2>/dev/null || true + ;; + android-apk|android-aab) + find build/app/intermediates/merged_native_libs -name '*.so' -exec cp {} "$STAGE"/ \; 2>/dev/null || true + ;; + *) + echo "unknown platform: $PLATFORM" >&2 + exit 2 + ;; +esac + +if [ -z "$(ls -A "$STAGE" 2>/dev/null)" ]; then + echo "no symbols found for platform ${PLATFORM}" >&2 + exit 3 +fi + +(cd "$STAGE" && zip -qr symbols.zip .) + +curl --fail --silent --show-error -X POST \ + -H "Authorization: Bearer ${TOKEN}" \ + -F "file=@${STAGE}/symbols.zip" \ + -F "release=${RELEASE}" \ + "${URL}/api/0/projects/plezy/plezy/files/dsyms/"