From 9b37b9a237e40980460c2cf4f86d879c5e22123b Mon Sep 17 00:00:00 2001 From: bitsandfoxes Date: Mon, 18 May 2026 11:47:40 +0200 Subject: [PATCH 1/2] switched from implicit 'doLast' to explicit exec --- .../Android/DebugSymbolUpload.cs | 85 +++++++++---------- .../Android/DebugSymbolUploadTests.cs | 25 ++++-- 2 files changed, 57 insertions(+), 53 deletions(-) diff --git a/src/Sentry.Unity.Editor/Android/DebugSymbolUpload.cs b/src/Sentry.Unity.Editor/Android/DebugSymbolUpload.cs index 8c3544099..ab6c41d67 100644 --- a/src/Sentry.Unity.Editor/Android/DebugSymbolUpload.cs +++ b/src/Sentry.Unity.Editor/Android/DebugSymbolUpload.cs @@ -46,36 +46,41 @@ private string SymbolUploadTaskFormat var stringBuilder = new StringBuilder(); stringBuilder.AppendLine("// Credentials and project settings information are stored in the sentry.properties file"); stringBuilder.AppendLine("afterEvaluate {"); - stringBuilder.AppendLine("task sentryUploadSymbols {"); - stringBuilder.AppendLine(" doLast {"); - stringBuilder.AppendLine(" println 'Uploading symbols to Sentry.'"); - var logsDir = $"{ConvertSlashes(_unityProjectPath)}/Logs"; - Directory.CreateDirectory(logsDir); - stringBuilder.AppendLine($" def logFilePath = '{logsDir}/{SymbolUploadLogName}'"); - stringBuilder.AppendLine(" def sentryLogFile = new FileOutputStream(logFilePath)"); - stringBuilder.AppendLine(" def outputStream = new org.apache.tools.ant.util.TeeOutputStream(System.out, sentryLogFile)"); - stringBuilder.AppendLine(" def errorStream = new org.apache.tools.ant.util.TeeOutputStream(System.err, sentryLogFile)"); - - stringBuilder.AppendLine(" exec {"); - stringBuilder.AppendLine(" environment 'SENTRY_PROPERTIES', './sentry.properties'"); - stringBuilder.AppendLine($" executable '{SentryCliMarker}'"); - stringBuilder.AppendLine($" args = ['debug-files', 'upload'{UploadArgsMarker}]"); + stringBuilder.AppendLine(" tasks.register('sentryUploadDebugFiles', Exec) {"); + stringBuilder.AppendLine(" environment 'SENTRY_PROPERTIES', './sentry.properties'"); + stringBuilder.AppendLine($" executable '{SentryCliMarker}'"); + stringBuilder.AppendLine($" args = ['debug-files', 'upload'{UploadArgsMarker}]"); + stringBuilder.AppendLine(" doFirst {"); + stringBuilder.AppendLine(" println 'Uploading symbols to Sentry.'"); if (!_isExporting) { - stringBuilder.AppendLine(" standardOutput outputStream"); - stringBuilder.AppendLine(" errorOutput errorStream"); + var logsDir = $"{ConvertSlashes(_unityProjectPath)}/Logs"; + Directory.CreateDirectory(logsDir); + stringBuilder.AppendLine($" def sentryLogFile = new FileOutputStream('{logsDir}/{SymbolUploadLogName}')"); + stringBuilder.AppendLine(" standardOutput = new org.apache.tools.ant.util.TeeOutputStream(System.out, sentryLogFile)"); + stringBuilder.AppendLine(" errorOutput = new org.apache.tools.ant.util.TeeOutputStream(System.err, sentryLogFile)"); } stringBuilder.AppendLine(" }"); + stringBuilder.AppendLine(" }"); + + if (_isMinifyEnabled) + { + AppendProguardMappingTask(stringBuilder); + } - CheckMapping(stringBuilder); + stringBuilder.AppendLine(" tasks.register('sentryUploadSymbols') {"); + stringBuilder.AppendLine(" dependsOn 'sentryUploadDebugFiles'"); + if (_isMinifyEnabled) + { + stringBuilder.AppendLine(" dependsOn 'sentryUploadProguardMapping'"); + } stringBuilder.AppendLine(" }"); - stringBuilder.AppendLine("}"); - stringBuilder.AppendLine(string.Empty); - stringBuilder.AppendLine("tasks.assembleDebug.finalizedBy sentryUploadSymbols"); - stringBuilder.AppendLine("tasks.assembleRelease.finalizedBy sentryUploadSymbols"); - stringBuilder.AppendLine("tasks.bundleDebug.finalizedBy sentryUploadSymbols"); - stringBuilder.AppendLine("tasks.bundleRelease.finalizedBy sentryUploadSymbols"); + + stringBuilder.AppendLine(" tasks.named('assembleDebug').configure { finalizedBy 'sentryUploadSymbols' }"); + stringBuilder.AppendLine(" tasks.named('assembleRelease').configure { finalizedBy 'sentryUploadSymbols' }"); + stringBuilder.AppendLine(" tasks.named('bundleDebug').configure { finalizedBy 'sentryUploadSymbols' }"); + stringBuilder.AppendLine(" tasks.named('bundleRelease').configure { finalizedBy 'sentryUploadSymbols' }"); stringBuilder.AppendLine("}"); return stringBuilder.ToString(); @@ -164,7 +169,7 @@ public void AppendUploadToGradleFile(string sentryCliPath) symbolUploadText = symbolUploadText.Replace(ProguardArgsMarker, uploadProguardArguments); var gradleBuildFile = LoadGradleScript(); - if (gradleBuildFile.Contains(SymbolUploadTaskStartComment) || gradleBuildFile.Contains("task sentryUploadSymbols")) + if (gradleBuildFile.Contains(SymbolUploadTaskStartComment) || gradleBuildFile.Contains("sentryUploadSymbols")) { throw new InvalidOperationException($"Failed to create Debug Symbol Upload Task. Task already exists in gradle file. A clean build should resolve this.{RaiseIssuePrompt}"); } @@ -201,7 +206,7 @@ public void RemoveUploadFromGradleFile() gradleBuildFile = regex.Replace(gradleBuildFile, ""); if (gradleBuildFile.Contains(SymbolUploadTaskStartComment) || - gradleBuildFile.Contains("task sentryUploadSymbols") || + gradleBuildFile.Contains("sentryUploadSymbols") || gradleBuildFile.Contains(SymbolUploadTaskEndComment)) { throw new InvalidOperationException($"Failed to remove Debug Symbol Upload Task from gradle file. A clean build should resolve this.{RaiseIssuePrompt}"); @@ -264,32 +269,24 @@ internal List GetSymbolUploadPaths(IApplication? application = null) // Gradle doesn't support backslashes on path (Windows) so converting to forward slashes internal static string ConvertSlashes(string path) => path.Replace(@"\", "/"); - private void CheckMapping(StringBuilder stringBuilder) + private void AppendProguardMappingTask(StringBuilder stringBuilder) { - if (!_isMinifyEnabled) - return; - - stringBuilder.AppendLine(" println 'Uploading mapping file to Sentry.'"); + stringBuilder.AppendLine(" tasks.register('sentryUploadProguardMapping', Exec) {"); + stringBuilder.AppendLine(" environment 'SENTRY_PROPERTIES', './sentry.properties'"); + stringBuilder.AppendLine($" executable '{SentryCliMarker}'"); + stringBuilder.AppendLine($" args = ['upload-proguard'{ProguardArgsMarker}]"); + stringBuilder.AppendLine(" doFirst {"); + stringBuilder.AppendLine(" println 'Uploading mapping file to Sentry.'"); if (!_isExporting) { var logsDir = $"{ConvertSlashes(_unityProjectPath)}/Logs"; Directory.CreateDirectory(logsDir); - stringBuilder.AppendLine($" def mappingLogFilePath = '{logsDir}/{MappingUploadLogName}'"); - stringBuilder.AppendLine($" def mappingLogFile = new FileOutputStream(mappingLogFilePath)"); - stringBuilder.AppendLine(" def mappingOutputStream = new org.apache.tools.ant.util.TeeOutputStream(System.out, mappingLogFile)"); - stringBuilder.AppendLine(" def mappingErrorStream = new org.apache.tools.ant.util.TeeOutputStream(System.err, mappingLogFile)"); - } - stringBuilder.AppendLine(" exec {"); - stringBuilder.AppendLine(" environment 'SENTRY_PROPERTIES', './sentry.properties'"); - stringBuilder.AppendLine($" executable '{SentryCliMarker}'"); - stringBuilder.AppendLine($" args = ['upload-proguard'{ProguardArgsMarker}]"); - // stringBuilder.AppendLine($" args = ['debug-files', 'upload'{UploadArgsMarker}]"); - if (!_isExporting) - { - stringBuilder.AppendLine(" standardOutput mappingOutputStream"); - stringBuilder.AppendLine(" errorOutput mappingErrorStream"); + stringBuilder.AppendLine($" def mappingLogFile = new FileOutputStream('{logsDir}/{MappingUploadLogName}')"); + stringBuilder.AppendLine(" standardOutput = new org.apache.tools.ant.util.TeeOutputStream(System.out, mappingLogFile)"); + stringBuilder.AppendLine(" errorOutput = new org.apache.tools.ant.util.TeeOutputStream(System.err, mappingLogFile)"); } stringBuilder.AppendLine(" }"); + stringBuilder.AppendLine(" }"); } private string GetMappingFilePath(IApplication? application) diff --git a/test/Sentry.Unity.Editor.Tests/Android/DebugSymbolUploadTests.cs b/test/Sentry.Unity.Editor.Tests/Android/DebugSymbolUploadTests.cs index 4bbb3163c..f863af8c7 100644 --- a/test/Sentry.Unity.Editor.Tests/Android/DebugSymbolUploadTests.cs +++ b/test/Sentry.Unity.Editor.Tests/Android/DebugSymbolUploadTests.cs @@ -156,16 +156,20 @@ public void AppendUploadToGradleFile_AllRequirementsMet_AppendsUploadTask(bool i "// Autogenerated Sentry symbol upload task [start]", "// Autogenerated Sentry symbol upload task [end]", "sentry.properties", + "tasks.register('sentryUploadDebugFiles', Exec)", "args = ['debug-files', 'upload', '--il2cpp-mapping', '--include-sources'", - "tasks.assembleDebug.finalizedBy sentryUploadSymbols", - "tasks.assembleRelease.finalizedBy sentryUploadSymbols", - "tasks.bundleDebug.finalizedBy sentryUploadSymbols", - "tasks.bundleRelease.finalizedBy sentryUploadSymbols" + "tasks.register('sentryUploadSymbols')", + "dependsOn 'sentryUploadDebugFiles'", + "tasks.named('assembleDebug').configure { finalizedBy 'sentryUploadSymbols' }", + "tasks.named('assembleRelease').configure { finalizedBy 'sentryUploadSymbols' }", + "tasks.named('bundleDebug').configure { finalizedBy 'sentryUploadSymbols' }", + "tasks.named('bundleRelease').configure { finalizedBy 'sentryUploadSymbols' }" }; if (!isExporting) { - keywords.Add("standardOutput outputStream"); + keywords.Add(DebugSymbolUpload.SymbolUploadLogName); + keywords.Add("standardOutput = new org.apache.tools.ant.util.TeeOutputStream(System.out, sentryLogFile)"); } if (ignoreCliErrors) @@ -175,10 +179,13 @@ public void AppendUploadToGradleFile_AllRequirementsMet_AppendsUploadTask(bool i if (addMapping) { + keywords.Add("tasks.register('sentryUploadProguardMapping', Exec)"); keywords.Add("args = ['upload-proguard'"); + keywords.Add("dependsOn 'sentryUploadProguardMapping'"); if (!isExporting) { - keywords.Add("standardOutput mappingOutputStream"); + keywords.Add(DebugSymbolUpload.MappingUploadLogName); + keywords.Add("standardOutput = new org.apache.tools.ant.util.TeeOutputStream(System.out, mappingLogFile)"); } } @@ -233,17 +240,17 @@ public void RemoveUploadTaskFromGradleFile_MultipleConsecutiveRemovals_HandlesCo for (var i = 0; i < 3; i++) { var gradleFile = File.ReadAllText(GetGradleFilePath()); - StringAssert.DoesNotContain("task sentryUploadSymbols", gradleFile); + StringAssert.DoesNotContain("sentryUploadSymbols", gradleFile); sut.AppendUploadToGradleFile(_fixture.SentryCliPath); gradleFile = File.ReadAllText(GetGradleFilePath()); - StringAssert.Contains("task sentryUploadSymbols", gradleFile); + StringAssert.Contains("sentryUploadSymbols", gradleFile); sut.RemoveUploadFromGradleFile(); gradleFile = File.ReadAllText(GetGradleFilePath()); - StringAssert.DoesNotContain("task sentryUploadSymbols", gradleFile); + StringAssert.DoesNotContain("sentryUploadSymbols", gradleFile); } } From 5c72463400882ce51f86fdc3626c46caf7013d2f Mon Sep 17 00:00:00 2001 From: bitsandfoxes Date: Mon, 18 May 2026 12:37:17 +0200 Subject: [PATCH 2/2] updated changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f8e3d3c11..343342161 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ ### Fixes +- The SDK now uses Gradle's built-in Exec task type when setting up the automated debug symbol upload. This resolves builds failing when targeting Android on Unity 6.4 ([#2686](https://github.com/getsentry/sentry-unity/pull/2686)) - When targeting iOS, the SDK no longer crashes in `urlSessionTask:setState:` when handling an `AVAssetDownloadTask` ([#2677](https://github.com/getsentry/sentry-unity/pull/2677)) ### Features