1+ using System ;
2+ using System . Collections . Generic ;
3+ using System . IO ;
4+ using System . Linq ;
5+ using System . Numerics ;
6+ using NUnit . Framework ;
7+ using Sequence . Config ;
8+ using UnityEditor ;
9+ using UnityEditor . Build ;
10+ using UnityEditor . Build . Reporting ;
11+ using UnityEngine ;
12+
13+ namespace Sequence . Editor
14+ {
15+ /// <summary>
16+ /// This test will build the project for all platforms and check if the build is compiled successfully
17+ /// </summary>
18+ public static class SequencePlatformCompileTest
19+ {
20+ private const string BuildDirectory = "Builds" ;
21+ private static List < string > _failedBuilds ;
22+
23+ [ MenuItem ( "Sequence Dev/Platform Compile Test" ) ]
24+ public static void RunBuildTest ( )
25+ {
26+ BigInteger startEpochTime = new BigInteger ( DateTimeOffset . Now . ToUnixTimeSeconds ( ) ) ;
27+ ClearPreviousErrors ( ) ;
28+
29+ string [ ] scenes = GetEnabledScenes ( ) ;
30+
31+ #if UNITY_EDITOR_WIN
32+ BuildPlatform ( BuildTarget . StandaloneWindows64 , $ "{ BuildDirectory } /WindowsBuild", scenes ) ;
33+ #endif
34+ #if UNITY_EDITOR_OSX
35+ BuildPlatform ( BuildTarget . StandaloneOSX , $ "{ BuildDirectory } /MacOSBuild", scenes ) ;
36+ BuildPlatform ( BuildTarget . iOS , $ "{ BuildDirectory } /iOSBuild", scenes ) ;
37+ #endif
38+ BuildPlatform ( BuildTarget . WebGL , $ "{ BuildDirectory } /WebGLBuild", scenes ) ;
39+ AndroidBuildTest ( $ "{ BuildDirectory } /AndroidBuild", scenes ) ;
40+
41+ Debug . Log ( "Platform Compile Test Completed. Check the console for errors." ) ;
42+ foreach ( var failedBuild in _failedBuilds )
43+ {
44+ Debug . LogError ( failedBuild ) ;
45+ }
46+
47+ BigInteger endEpochTime = new BigInteger ( DateTimeOffset . Now . ToUnixTimeSeconds ( ) ) ;
48+ Debug . Log ( $ "Total Test Time: { endEpochTime - startEpochTime } seconds") ;
49+ }
50+
51+ private static void ClearPreviousErrors ( )
52+ {
53+ _failedBuilds = new List < string > ( ) ;
54+
55+ string errorDirectory = "PlatformCompileTestErrors" ;
56+ if ( Directory . Exists ( errorDirectory ) )
57+ {
58+ var txtFiles = Directory . GetFiles ( errorDirectory , "*.txt" ) ;
59+ foreach ( var file in txtFiles )
60+ {
61+ File . Delete ( file ) ;
62+ }
63+ }
64+ else
65+ {
66+ Directory . CreateDirectory ( errorDirectory ) ;
67+ }
68+ }
69+
70+ private static string [ ] GetEnabledScenes ( )
71+ {
72+ return EditorBuildSettings . scenes
73+ . Where ( scene => scene . enabled )
74+ . Select ( scene => scene . path )
75+ . ToArray ( ) ;
76+ }
77+
78+ private static void BuildPlatform ( BuildTarget target , string path , string [ ] scenes )
79+ {
80+ try
81+ {
82+ BuildToPlatformAndCheckForSuccess ( target , path , scenes ) ;
83+ }
84+ finally
85+ {
86+ CleanupBuildDirectory ( ) ;
87+ }
88+ }
89+
90+ private static void BuildToPlatformAndCheckForSuccess ( BuildTarget target , string path , string [ ] scenes )
91+ {
92+ BuildReport report = BuildPipeline . BuildPlayer ( scenes , path , target , BuildOptions . None ) ;
93+
94+ if ( report . summary . result != BuildResult . Succeeded )
95+ {
96+ _failedBuilds . Add ( $ "{ target } build failed with { report . summary . totalErrors } errors. Please see { BuildDirectory } /{ target } .txt for details.") ;
97+ LogErrorsToFile ( report , target ) ;
98+ }
99+ }
100+
101+ private static void CleanupBuildDirectory ( )
102+ {
103+ if ( Directory . Exists ( BuildDirectory ) )
104+ {
105+ Directory . Delete ( BuildDirectory , true ) ;
106+ }
107+ }
108+
109+ private static void LogErrorsToFile ( BuildReport report , BuildTarget target )
110+ {
111+ string errorDirectory = "PlatformCompileTestErrors" ;
112+ if ( ! Directory . Exists ( errorDirectory ) )
113+ {
114+ Directory . CreateDirectory ( errorDirectory ) ;
115+ }
116+
117+ string errorFilePath = Path . Combine ( errorDirectory , $ "{ target } .txt") ;
118+
119+ using ( StreamWriter writer = new StreamWriter ( errorFilePath , false ) )
120+ {
121+ writer . WriteLine ( $ "Build Time: { DateTime . Now : yyyy-MM-dd HH:mm:ss} ") ;
122+ writer . WriteLine ( $ "Platform: { target } ") ;
123+ writer . WriteLine ( $ "Build Errors Summary:") ;
124+ writer . WriteLine ( $ "Total Errors: { report . summary . totalErrors } ") ;
125+ writer . WriteLine ( ) ;
126+ writer . WriteLine ( "Detailed Errors:" ) ;
127+
128+ foreach ( var step in report . steps )
129+ {
130+ foreach ( var message in step . messages )
131+ {
132+ if ( message . type == LogType . Error )
133+ {
134+ writer . WriteLine ( $ "[{ message . type } ] { message . content } ") ;
135+ }
136+ }
137+ }
138+ }
139+ }
140+
141+ private static void AndroidBuildTest ( string path , string [ ] scenes )
142+ {
143+ SequenceConfig config = SequenceConfig . GetConfig ( ) ;
144+ bool isSecureStorageEnabled = config . StoreSessionPrivateKeyInSecureStorage ;
145+ BuildTarget target = BuildTarget . Android ;
146+
147+ try
148+ {
149+ BuildToPlatformAndCheckForSuccess ( target , path , scenes ) ;
150+
151+ AssertPluginCompatibility ( config , target ) ;
152+ AssertAppropriateScriptingDefines ( config , target ) ;
153+
154+ config . StoreSessionPrivateKeyInSecureStorage = ! config . StoreSessionPrivateKeyInSecureStorage ;
155+
156+ BuildToPlatformAndCheckForSuccess ( target , path , scenes ) ;
157+
158+ AssertPluginCompatibility ( config , target ) ;
159+ AssertAppropriateScriptingDefines ( config , target ) ;
160+ }
161+ finally
162+ {
163+ config . StoreSessionPrivateKeyInSecureStorage = isSecureStorageEnabled ;
164+
165+ CleanupBuildDirectory ( ) ;
166+ }
167+ }
168+
169+ private static void AssertPluginCompatibility ( SequenceConfig config , BuildTarget target )
170+ {
171+ PluginImporter pluginImporter = AssetImporter . GetAtPath ( AndroidDependencyManager . SecureStoragePluginPath ) as PluginImporter ;
172+ Assert . IsNotNull ( pluginImporter , "Plugin not found at path: " + AndroidDependencyManager . SecureStoragePluginPath ) ;
173+ Assert . AreEqual ( config . StoreSessionPrivateKeyInSecureStorage , pluginImporter . GetCompatibleWithPlatform ( target ) ) ;
174+ }
175+
176+ private static void AssertAppropriateScriptingDefines ( SequenceConfig config , BuildTarget target )
177+ {
178+ string defines = PlayerSettings . GetScriptingDefineSymbols ( NamedBuildTarget . FromBuildTargetGroup ( BuildPipeline . GetBuildTargetGroup ( target ) ) ) ;
179+ Assert . AreEqual ( config . StoreSessionPrivateKeyInSecureStorage , defines . Contains ( AndroidScriptDefineSetup . EnableAndroidSecureStorage ) ) ;
180+ }
181+ }
182+ }
0 commit comments