Skip to content

Integration-test building without sentry SDK only on main branch #785

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jun 8, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,8 @@ jobs:
run: sudo pwsh ./test/Scripts.Integration.Test/integration-create-project.ps1 -UnityPath "${{ env.UNITY_PATH }}"

- name: Build without Sentry SDK
# This hasn't broken for many months, so disabling on PRs to speed up CI. And also to test a clean build with Sentry SDK included.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A surprise but a welcome one!

if: ${{ github.ref_name == 'main' }}
run: sudo pwsh ./test/Scripts.Integration.Test/integration-build-project.ps1 -UnityPath "${{ env.UNITY_PATH }}" -Platform "${{ matrix.platform }}"

- name: Download UPM package
Expand Down Expand Up @@ -331,6 +333,8 @@ jobs:
run: ./test/Scripts.Integration.Test/integration-create-project.ps1 -UnityPath "${{ env.UNITY_PATH }}"

- name: Build without Sentry SDK
# This hasn't broken for many months, so disabling on PRs to speed up CI. And also to test a clean build with Sentry SDK included.
if: ${{ github.ref_name == 'main' }}
run: ./test/Scripts.Integration.Test/integration-build-project.ps1 -UnityPath "${{ env.UNITY_PATH }}"

- name: Download UPM package
Expand Down
2 changes: 1 addition & 1 deletion Directory.Build.targets
Original file line number Diff line number Diff line change
Expand Up @@ -350,7 +350,7 @@ Related: https://forum.unity.com/threads/6572-debugger-agent-unable-to-listen-on
<UnityTestResults Path="$(UnityTestPlayModeResultFilePath)" />
</Target>

<!-- Run EditMode tests with dotnet msbuild /t:UnityEditModeTest test/Sentry.Unity.Tests -->
<!-- Run EditMode tests with dotnet msbuild /t:UnityEditModeTest test/Sentry.Unity.Editor.Tests -->
<Target Name="UnityEditModeTest" DependsOnTargets="Build" Condition="'$(MSBuildProjectName)' == 'Sentry.Unity.Editor.Tests'">
<Error Condition="$(UnityExec) == ''" Text="Couldn't find Unity." />

Expand Down
1 change: 1 addition & 0 deletions samples/unity-of-bugs/Assets/Editor/Builder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ public static void BuildIl2CPPPlayer(BuildTarget target, BuildTargetGroup group)
ValidateArguments(args);

// Make sure the configuration is right.
EditorUserBuildSettings.selectedBuildTargetGroup = group;
PlayerSettings.SetScriptingBackend(group, ScriptingImplementation.IL2CPP);

if (args.ContainsKey("sentryOptions.configure"))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ internal void SetupSymbolsUpload(string unityProjectPath, string gradleProjectPa
var disableSymbolsUpload = false;
var logger = _options?.DiagnosticLogger ?? new UnityLogger(new SentryUnityOptions());
var symbolsUpload = new DebugSymbolUpload(logger, _sentryCliOptions, unityProjectPath, gradleProjectPath,
EditorUserBuildSettings.exportAsGoogleAndroidProject);
PlayerSettings.GetScriptingBackend(BuildTargetGroup.Android), EditorUserBuildSettings.exportAsGoogleAndroidProject);

if (_options is null || !_options.Enabled || !_options.AndroidNativeSupportEnabled)
{
Expand Down
35 changes: 20 additions & 15 deletions src/Sentry.Unity.Editor/Android/DebugSymbolUpload.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,19 +20,26 @@ internal class DebugSymbolUpload

private readonly string _unityProjectPath;
private readonly string _gradleProjectPath;
private readonly ScriptingImplementation _scriptingBackend;

private readonly SentryCliOptions? _cliOptions;
internal string[] _symbolUploadPaths;

private const string SymbolUploadTaskStartComment = "// Autogenerated Sentry symbol upload task [start]";
private const string SymbolUploadTaskEndComment = "// Autogenerated Sentry symbol upload task [end]";

private string _symbolUploadTask = @"
// Credentials and project settings information are stored in the sentry.properties file
gradle.taskGraph.whenReady {{
gradle.taskGraph.allTasks[-1].doLast {{
println 'Uploading symbols to Sentry'
println 'Uploading symbols to Sentry. You can find the full log in ./Logs/sentry-symbols-upload.log (the file content may not be strictly sequential because it\'s a merge of two streams).'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❤️

def sentryLogFile = new FileOutputStream('{2}/Logs/sentry-symbols-upload.log')
exec {{
environment ""SENTRY_PROPERTIES"", ""./sentry.properties""
executable ""{0}""
args = [""upload-dif"", {1}]
environment 'SENTRY_PROPERTIES', './sentry.properties'
executable '{0}'
args = ['upload-dif', {1}]
standardOutput sentryLogFile
errorOutput sentryLogFile
}}
}}
}}";
Expand All @@ -41,13 +48,15 @@ public DebugSymbolUpload(IDiagnosticLogger logger,
SentryCliOptions? cliOptions,
string unityProjectPath,
string gradleProjectPath,
ScriptingImplementation scriptingBackend,
bool isExporting = false,
IApplication? application = null)
{
_logger = logger;

_unityProjectPath = unityProjectPath;
_gradleProjectPath = gradleProjectPath;
_scriptingBackend = scriptingBackend;

_cliOptions = cliOptions;
_symbolUploadPaths = GetSymbolUploadPaths(isExporting, application);
Expand Down Expand Up @@ -94,7 +103,9 @@ public void AppendUploadToGradleFile(string sentryCliPath)
}

using var streamWriter = File.AppendText(gradleFilePath);
streamWriter.Write(_symbolUploadTask, sentryCliPath, uploadDifArguments);
streamWriter.WriteLine(SymbolUploadTaskStartComment);
streamWriter.WriteLine(_symbolUploadTask.Trim(), sentryCliPath, uploadDifArguments, ConvertSlashes(_unityProjectPath));
streamWriter.WriteLine(SymbolUploadTaskEndComment);
}

public void RemoveUploadFromGradleFile()
Expand All @@ -114,12 +125,8 @@ public void RemoveUploadFromGradleFile()
return;
}

// Replacing the paths with '.*' and escaping the task
var uploadTaskFilter = string.Format(_symbolUploadTask, ".*", ".*");
uploadTaskFilter = Regex.Replace(uploadTaskFilter, "\"", "\\\"");
uploadTaskFilter = Regex.Replace(uploadTaskFilter, @"\[", "\\[");

gradleBuildFile = Regex.Replace(gradleBuildFile, uploadTaskFilter, "");
var regex = new Regex(Regex.Escape(SymbolUploadTaskStartComment) + ".*" + Regex.Escape(SymbolUploadTaskEndComment), RegexOptions.Singleline);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for fixing that!

gradleBuildFile = regex.Replace(gradleBuildFile, "");

using var streamWriter = File.CreateText(gradleFilePath);
streamWriter.Write(gradleBuildFile);
Expand Down Expand Up @@ -161,7 +168,7 @@ internal string[] GetSymbolUploadPaths(bool isExporting, IApplication? applicati
if (IsNewBuildingBackend(application))
{
_logger.LogInfo("Unity version 2021.2 or newer detected. Root for symbols upload: 'Library'.");
if (!IsMono)
if (_scriptingBackend == ScriptingImplementation.IL2CPP)
{
paths.Add(Path.Combine(_unityProjectPath, RelativeBuildOutputPathNew));
}
Expand All @@ -170,7 +177,7 @@ internal string[] GetSymbolUploadPaths(bool isExporting, IApplication? applicati
else
{
_logger.LogInfo("Unity version 2021.1 or older detected. Root for symbols upload: 'Temp'.");
if (!IsMono)
if (_scriptingBackend == ScriptingImplementation.IL2CPP)
{
paths.Add(Path.Combine(_unityProjectPath, RelativeBuildOutputPathOld));
}
Expand All @@ -195,7 +202,5 @@ internal static bool IsNewBuildingBackend(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 static bool IsMono => PlayerSettings.GetScriptingBackend(EditorUserBuildSettings.selectedBuildTargetGroup) == ScriptingImplementation.Mono2x;
}
}
14 changes: 7 additions & 7 deletions src/Sentry.Unity.Editor/Native/BuildPostProcess.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ public static class BuildPostProcess
[PostProcessBuild(1)]
public static void OnPostProcessBuild(BuildTarget target, string executablePath)
{
if (EditorUserBuildSettings.selectedBuildTargetGroup is not BuildTargetGroup.Standalone)
var targetGroup = BuildPipeline.GetBuildTargetGroup(target);
if (targetGroup is not BuildTargetGroup.Standalone)
{
return;
}
Expand All @@ -22,6 +23,7 @@ public static void OnPostProcessBuild(BuildTarget target, string executablePath)
.Load<ScriptableSentryUnityOptions>(ScriptableSentryUnityOptions.GetConfigPath())
?.ToSentryUnityOptions(BuildPipeline.isBuildingPlayer);
var logger = options?.DiagnosticLogger ?? new UnityLogger(options ?? new SentryUnityOptions());
var isMono = PlayerSettings.GetScriptingBackend(targetGroup) == ScriptingImplementation.Mono2x;

try
{
Expand Down Expand Up @@ -49,7 +51,7 @@ public static void OnPostProcessBuild(BuildTarget target, string executablePath)
var projectDir = Path.GetDirectoryName(executablePath);
var executableName = Path.GetFileName(executablePath);
AddCrashHandler(logger, target, projectDir, executableName);
UploadDebugSymbols(logger, target, projectDir, executableName, options);
UploadDebugSymbols(logger, target, projectDir, executableName, options, isMono);
}
catch (Exception e)
{
Expand Down Expand Up @@ -94,9 +96,7 @@ private static void AddCrashHandler(IDiagnosticLogger logger, BuildTarget target
File.Copy(crashpadPath, targetPath, true);
}

private static bool IsMono => PlayerSettings.GetScriptingBackend(EditorUserBuildSettings.selectedBuildTargetGroup) == ScriptingImplementation.Mono2x;

private static void UploadDebugSymbols(IDiagnosticLogger logger, BuildTarget target, string projectDir, string executableName, SentryUnityOptions options)
private static void UploadDebugSymbols(IDiagnosticLogger logger, BuildTarget target, string projectDir, string executableName, SentryUnityOptions options, bool isMono)
{
var cliOptions = SentryScriptableObject.CreateOrLoad<SentryCliOptions>(SentryCliOptions.GetConfigPath());
if (!cliOptions.IsValid(logger))
Expand Down Expand Up @@ -131,7 +131,7 @@ private static void UploadDebugSymbols(IDiagnosticLogger logger, BuildTarget tar
addPath("UnityPlayer.dll");
addPath(Path.GetFileNameWithoutExtension(executableName) + "_Data/Plugins/x86_64/sentry.dll");
addPath(Path.GetFullPath($"Packages/{SentryPackageInfo.GetName()}/Plugins/Windows/Sentry/sentry.pdb"));
if (IsMono)
if (isMono)
{
addPath("MonoBleedingEdge/EmbedRuntime");
}
Expand All @@ -141,7 +141,7 @@ private static void UploadDebugSymbols(IDiagnosticLogger logger, BuildTarget tar
addPath("GameAssembly.so");
addPath("UnityPlayer.so");
addPath(Path.GetFullPath($"Packages/{SentryPackageInfo.GetName()}/Plugins/Linux/Sentry/libsentry.dbg.so"));
if (IsMono)
if (isMono)
{
addPath(Path.GetFileNameWithoutExtension(executableName) + "_Data/MonoBleedingEdge/x86_64");
}
Expand Down
2 changes: 2 additions & 0 deletions src/Sentry.Unity.Editor/SentryCli.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ public static string CreateSentryProperties(string propertiesPath, SentryCliOpti
properties.WriteLine($"defaults.org={cliOptions.Organization}");
properties.WriteLine($"defaults.project={cliOptions.Project}");
properties.WriteLine($"auth.token={cliOptions.Auth}");
properties.WriteLine($"log.level=info");

return propertiesFile;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -280,93 +280,87 @@ public void ModifyManifest_RepeatedRunRemovesConfigs()
[Test]
public void SetupSymbolsUpload_SentryCliOptionsNull_LogsWarningAndReturns()
{
var fakeProjectPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
DebugSymbolUploadTests.SetupFakeProject(fakeProjectPath);
var gradleProjectPath = Path.Combine(fakeProjectPath, "GradleProject");
var dsuFixture = new DebugSymbolUploadTests.Fixture();
DebugSymbolUploadTests.SetupFakeProject(dsuFixture.FakeProjectPath);

_fixture.SentryCliOptions = null;
var sut = _fixture.GetSut();

sut.SetupSymbolsUpload("unity_project_path", gradleProjectPath);
sut.SetupSymbolsUpload(dsuFixture.UnityProjectPath, dsuFixture.GradleProjectPath);

_fixture.LoggerInterceptor.AssertLogContains(SentryLevel.Warning, "Failed to load sentry-cli options.");

Directory.Delete(Path.GetFullPath(fakeProjectPath), true);
Directory.Delete(Path.GetFullPath(dsuFixture.FakeProjectPath), true);
}

[Test]
public void SetupSymbolsUpload_SymbolsUploadDisabled_LogsAndReturns()
{
var fakeProjectPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
DebugSymbolUploadTests.SetupFakeProject(fakeProjectPath);
var gradleProjectPath = Path.Combine(fakeProjectPath, "GradleProject");
var dsuFixture = new DebugSymbolUploadTests.Fixture();
DebugSymbolUploadTests.SetupFakeProject(dsuFixture.FakeProjectPath);

_fixture.SentryCliOptions!.UploadSymbols = false;
var sut = _fixture.GetSut();

sut.SetupSymbolsUpload("unity_project_path", gradleProjectPath);
sut.SetupSymbolsUpload(dsuFixture.UnityProjectPath, dsuFixture.GradleProjectPath);

_fixture.LoggerInterceptor.AssertLogContains(SentryLevel.Debug, "Automated symbols upload has been disabled.");

Directory.Delete(Path.GetFullPath(fakeProjectPath), true);
Directory.Delete(Path.GetFullPath(dsuFixture.FakeProjectPath), true);
}

[Test]
public void SetupSymbolsUpload_DevelopmentBuildDevUploadDisabled_LogsAndReturns()
{
var fakeProjectPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
DebugSymbolUploadTests.SetupFakeProject(fakeProjectPath);
var gradleProjectPath = Path.Combine(fakeProjectPath, "GradleProject");
var dsuFixture = new DebugSymbolUploadTests.Fixture();
DebugSymbolUploadTests.SetupFakeProject(dsuFixture.FakeProjectPath);

_fixture.IsDevelopmentBuild = true;
var sut = _fixture.GetSut();

sut.SetupSymbolsUpload("unity_project_path", gradleProjectPath);
sut.SetupSymbolsUpload(dsuFixture.UnityProjectPath, dsuFixture.GradleProjectPath);

_fixture.LoggerInterceptor.AssertLogContains(SentryLevel.Debug, "Automated symbols upload for development builds has been disabled.");

Directory.Delete(Path.GetFullPath(fakeProjectPath), true);
Directory.Delete(Path.GetFullPath(dsuFixture.FakeProjectPath), true);
}

[Test]
public void SetupSymbolsUpload_SentryCliOptionsInvalid_LogsAndReturns()
{
var fakeProjectPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
DebugSymbolUploadTests.SetupFakeProject(fakeProjectPath);
var gradleProjectPath = Path.Combine(fakeProjectPath, "GradleProject");
var dsuFixture = new DebugSymbolUploadTests.Fixture();
DebugSymbolUploadTests.SetupFakeProject(dsuFixture.FakeProjectPath);

_fixture.SentryCliOptions!.Auth = string.Empty;
var sut = _fixture.GetSut();

sut.SetupSymbolsUpload("unity_project_path", gradleProjectPath);
sut.SetupSymbolsUpload(dsuFixture.UnityProjectPath, dsuFixture.GradleProjectPath);

_fixture.LoggerInterceptor.AssertLogContains(SentryLevel.Warning, "sentry-cli validation failed. Symbols will not be uploaded." +
"\nYou can disable this warning by disabling the automated symbols upload under " +
SentryCliOptions.EditorMenuPath);

Directory.Delete(Path.GetFullPath(fakeProjectPath), true);
Directory.Delete(Path.GetFullPath(dsuFixture.FakeProjectPath), true);
}

[Test]
[TestCase(ScriptingImplementation.IL2CPP)]
[TestCase(ScriptingImplementation.Mono2x)]
public void SetupSymbolsUpload_ValidConfiguration_AppendsUploadTaskToGradleAndCreatesSentryProperties(ScriptingImplementation scriptingImplementation)
{
var fakeProjectPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
DebugSymbolUploadTests.SetupFakeProject(fakeProjectPath);
var dsuFixture = new DebugSymbolUploadTests.Fixture();
DebugSymbolUploadTests.SetupFakeProject(dsuFixture.FakeProjectPath);

_fixture.ScriptingImplementation = scriptingImplementation;
var sut = _fixture.GetSut();
var unityProjectPath = Path.Combine(fakeProjectPath, "UnityProject");
var gradleProjectPath = Path.Combine(fakeProjectPath, "GradleProject");

sut.SetupSymbolsUpload(unityProjectPath, gradleProjectPath);
sut.SetupSymbolsUpload(dsuFixture.UnityProjectPath, dsuFixture.GradleProjectPath);

StringAssert.Contains("println 'Uploading symbols to Sentry'",
File.ReadAllText(Path.Combine(gradleProjectPath, "build.gradle")));
Assert.True(File.Exists(Path.Combine(gradleProjectPath, "sentry.properties")));
StringAssert.Contains("println 'Uploading symbols to Sentry",
File.ReadAllText(Path.Combine(dsuFixture.GradleProjectPath, "build.gradle")));
Assert.True(File.Exists(Path.Combine(dsuFixture.GradleProjectPath, "sentry.properties")));

Directory.Delete(Path.GetFullPath(fakeProjectPath), true);
Directory.Delete(Path.GetFullPath(dsuFixture.FakeProjectPath), true);
}

private string WithAndroidManifest(Action<string> callback)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@
using NUnit.Framework;
using Sentry.Unity.Editor.Android;
using Sentry.Unity.Tests.Stubs;
using UnityEditor;

namespace Sentry.Unity.Editor.Tests.Android
{
public class DebugSymbolUploadTests
{
private class Fixture
public class Fixture
{
public TestUnityLoggerInterceptor LoggerInterceptor { get; set; }
internal TestUnityLoggerInterceptor LoggerInterceptor { get; set; }
public string FakeProjectPath { get; set; }
public string UnityProjectPath { get; set; }
public string GradleProjectPath { get; set; }
Expand All @@ -34,8 +35,8 @@ public Fixture()
Application = new TestApplication(unityVersion: "2019.4");
}

public DebugSymbolUpload GetSut() => new(new UnityLogger(new SentryOptions(), LoggerInterceptor),
null, UnityProjectPath, GradleProjectPath, IsExporting, Application);
internal DebugSymbolUpload GetSut() => new(new UnityLogger(new SentryOptions(), LoggerInterceptor),
null, UnityProjectPath, GradleProjectPath, ScriptingImplementation.IL2CPP, IsExporting, Application);
}

[SetUp]
Expand Down