com.amanotes.gdk 0.2.87 → 0.2.89
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +41 -0
- package/Editor/AmaGDKEditor.cs +3 -1
- package/Editor/Extra/GDKCIBuildCommand.cs +528 -239
- package/Editor/Extra/GDKLocalBuild.cs +12 -1
- package/Editor/Extra/GDKPostBuildAsset.cs +21 -3
- package/Extra/AmaGDKInstaller.unitypackage +0 -0
- package/Extra/AutoEventQC.unitypackage +0 -0
- package/Extra/CheckDiskSpace.unitypackage +0 -0
- package/Extra/Consent.unitypackage +0 -0
- package/Extra/CrashlyticHook.unitypackage +0 -0
- package/Extra/ForceUpdate.unitypackage +0 -0
- package/Extra/LegacyGDKUpdateHelper.unitypackage +0 -0
- package/Extra/PostProcessor.unitypackage +0 -0
- package/Packages/AmaGDKConfig.unitypackage +0 -0
- package/Packages/AmaGDKExample.unitypackage +0 -0
- package/Packages/AmaGDKTest.unitypackage +0 -0
- package/Packages/AppsFlyerAdapter.PurchaseConnector.unitypackage +0 -0
- package/Packages/AppsFlyerAdapter.unitypackage +0 -0
- package/Packages/FirebaseAnalyticsAdapter.unitypackage +0 -0
- package/Packages/FirebaseRemoteConfigAdapter.unitypackage +0 -0
- package/Packages/IronSourceAdapter.unitypackage +0 -0
- package/Packages/MaxAdNetworkAdapter.unitypackage +0 -0
- package/Packages/RevenueCatAdapter.unitypackage +0 -0
- package/Packages/SqliteAnalyticsAdapter.unitypackage +0 -0
- package/Runtime/Ad/AdLogic.cs +5 -1
- package/Runtime/AmaGDK.cs +1 -1
- package/Runtime/Internal/AmaGDK.WebUtils.cs +17 -7
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,44 @@
|
|
|
1
|
+
## [0.2.89] - 2025-08-05
|
|
2
|
+
- [Fix] Null Exception when ad load failed
|
|
3
|
+
- [Fix] Don't cancel unity build jobs
|
|
4
|
+
- [Fix] Build Unity 2021
|
|
5
|
+
- [Dev] Remove Ad Quality
|
|
6
|
+
- [Dev] Fix build jobs
|
|
7
|
+
- [Dev] Upgrade unity version
|
|
8
|
+
- [Dev] Add retrier for unity license
|
|
9
|
+
- [Dev] Remove gradle path on CI
|
|
10
|
+
- [Dev] Update integration test
|
|
11
|
+
- [Dev] Improve build command
|
|
12
|
+
- [Dev] Update project settings
|
|
13
|
+
- [Dev] Return unity license
|
|
14
|
+
- [Dev] Upgrade Ironsource v8.10.0 & Max v13.3.1
|
|
15
|
+
- [Dev] Migrate CI to TartVM workflow
|
|
16
|
+
- [Dev] Upgrade unity versions
|
|
17
|
+
|
|
18
|
+
## [0.2.88] - 2025-07-05
|
|
19
|
+
- [Dev] Various fixes for Unity 6
|
|
20
|
+
- [Fix] Update marker block id for Notion change log
|
|
21
|
+
- [Dev] Add AI config
|
|
22
|
+
- [Dev] Improve crap score 2
|
|
23
|
+
- [Dev] Reduce complexity & crap score
|
|
24
|
+
- [Dev] Various warning fixes & Improve message verification in tests
|
|
25
|
+
- [Fix] Compiler error in Unity 2023+
|
|
26
|
+
- [Dev] Track max adapters
|
|
27
|
+
- [Fix] Do not override config when Adapter id is not available
|
|
28
|
+
- [Fix] Bypass file utils unit test
|
|
29
|
+
- [Dev] Improve verbose logging
|
|
30
|
+
- [BugFix]: Fix sentry issue : Null exception issue
|
|
31
|
+
- [Fix] Missing User Mapping in MaxAdapter
|
|
32
|
+
- [Fix] Manage ad activity killed routine
|
|
33
|
+
- [Fix] Attach JNI thread
|
|
34
|
+
- [Fix] Missing DoOnMainThread for ConsentInformation update
|
|
35
|
+
- [Fix] Send GDKVersionTracking only for Android/iOS
|
|
36
|
+
- [Dev] Rename Remote Config Data Source
|
|
37
|
+
- [Fix] Improve disk space checking with thead pool
|
|
38
|
+
- [Dev] Refactor DiskSpacePopup
|
|
39
|
+
- [Fix] Add missing scope registry for integration test
|
|
40
|
+
- [Dev] Add UniTask Dependency
|
|
41
|
+
|
|
1
42
|
## [0.2.87] - 2025-06-19
|
|
2
43
|
- [Dev] Add AI config
|
|
3
44
|
- [Dev] Improve crap score 2
|
package/Editor/AmaGDKEditor.cs
CHANGED
|
@@ -245,8 +245,10 @@ namespace Amanotes.Editor
|
|
|
245
245
|
bannerTitle ??= new GUIContent()
|
|
246
246
|
{
|
|
247
247
|
image = logo.Value,
|
|
248
|
-
text = $"<b>AmaGDK</b> <size=12><color
|
|
248
|
+
text = $"<b>AmaGDK</b> <size=12><color=\"grey\">v{AmaGDK.VERSION}</color></size>"
|
|
249
249
|
};
|
|
250
|
+
|
|
251
|
+
|
|
250
252
|
AmaGUI.SectionLabel(bannerTitle);
|
|
251
253
|
var rect = GUILayoutUtility.GetLastRect();
|
|
252
254
|
var btnRect = rect;
|
|
@@ -10,12 +10,18 @@ using Debug = UnityEngine.Debug;
|
|
|
10
10
|
|
|
11
11
|
namespace Amanotes.Core
|
|
12
12
|
{
|
|
13
|
+
/// <summary>
|
|
14
|
+
/// Unity CI Build Command for GitLab CI integration.
|
|
15
|
+
/// Supports Unity 2021+ with backward compatibility for current features.
|
|
16
|
+
/// </summary>
|
|
13
17
|
public static class GDKCIBuildCommand
|
|
14
18
|
{
|
|
19
|
+
#region Constants
|
|
20
|
+
|
|
21
|
+
// Environment variable keys
|
|
15
22
|
private const string KEYSTORE_PASS = "KEYSTORE_PASS";
|
|
16
23
|
private const string KEY_ALIAS_PASS = "KEY_ALIAS_PASS";
|
|
17
24
|
private const string KEY_ALIAS_NAME = "KEY_ALIAS_NAME";
|
|
18
|
-
private const string KEYSTORE = "keystore.keystore";
|
|
19
25
|
private const string BUILD_OPTIONS_ENV_VAR = "BuildOptions";
|
|
20
26
|
private const string ANDROID_APP_BUNDLE = "BUILD_APP_BUNDLE";
|
|
21
27
|
private const string SCRIPTING_BACKEND_ENV_VAR = "SCRIPTING_BACKEND";
|
|
@@ -23,418 +29,701 @@ namespace Amanotes.Core
|
|
|
23
29
|
private const string VERSION_NUMBER_VAR = "VERSION_NUMBER_VAR";
|
|
24
30
|
private const string VERSION_BUILD_VAR = "VERSION_BUILD_VAR";
|
|
25
31
|
|
|
32
|
+
// File paths
|
|
33
|
+
private const string KEYSTORE = "keystore.keystore";
|
|
34
|
+
|
|
35
|
+
// Other constants
|
|
36
|
+
private static readonly string Eol = Environment.NewLine;
|
|
37
|
+
|
|
38
|
+
#endregion
|
|
39
|
+
|
|
40
|
+
#region Pod Installation
|
|
41
|
+
|
|
42
|
+
/// <summary>
|
|
43
|
+
/// Installs CocoaPods for iOS builds.
|
|
44
|
+
/// </summary>
|
|
45
|
+
/// <param name="processExit">Event handler for process completion</param>
|
|
46
|
+
/// <param name="buildPath">Build path for pod installation</param>
|
|
26
47
|
public static void InstallPod(EventHandler processExit, string buildPath = null)
|
|
27
48
|
{
|
|
28
49
|
try
|
|
29
50
|
{
|
|
30
|
-
|
|
31
|
-
if (Application.isBatchMode && TryGetEnv("CI_SCRIPT_DIR", out string scriptDir))
|
|
32
|
-
{
|
|
33
|
-
arguments = $"{scriptDir}/utils.sh pod-install";
|
|
34
|
-
}
|
|
35
|
-
else if (!Application.isBatchMode)
|
|
36
|
-
{
|
|
37
|
-
string podPath = "/usr/local/bin/pod";
|
|
38
|
-
if (!File.Exists(podPath)) podPath = "/opt/homebrew/bin/pod";
|
|
39
|
-
arguments = $"-c \"{podPath} install --project-directory={buildPath}\"";
|
|
40
|
-
}
|
|
51
|
+
LogInfo("Starting CocoaPods installation...");
|
|
41
52
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
{
|
|
45
|
-
FileName = "/bin/zsh",
|
|
46
|
-
Arguments = arguments,
|
|
47
|
-
CreateNoWindow = false,
|
|
48
|
-
RedirectStandardOutput = true,
|
|
49
|
-
RedirectStandardError = true,
|
|
50
|
-
UseShellExecute = false
|
|
51
|
-
};
|
|
52
|
-
|
|
53
|
-
var proc = new Process
|
|
53
|
+
string arguments = GetPodInstallArguments(buildPath);
|
|
54
|
+
if (string.IsNullOrEmpty(arguments))
|
|
54
55
|
{
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
// Attach event handlers
|
|
60
|
-
proc.OutputDataReceived += (sender, args) =>
|
|
61
|
-
{
|
|
62
|
-
if (args.Data == null) return; // End of the stream
|
|
63
|
-
Debug.Log(args.Data);
|
|
64
|
-
};
|
|
65
|
-
|
|
66
|
-
proc.Exited += processExit;
|
|
56
|
+
LogWarning("No pod install arguments configured. Skipping pod installation.");
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
67
59
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
proc.BeginOutputReadLine();
|
|
71
|
-
proc.BeginErrorReadLine();
|
|
72
|
-
proc.WaitForExit();
|
|
60
|
+
var process = CreatePodInstallProcess(arguments, processExit);
|
|
61
|
+
ExecuteProcess(process);
|
|
73
62
|
}
|
|
74
63
|
catch (Exception e)
|
|
75
64
|
{
|
|
65
|
+
LogError($"Pod installation failed: {e.Message}");
|
|
76
66
|
Debug.LogError(e);
|
|
77
67
|
}
|
|
78
68
|
}
|
|
79
69
|
|
|
80
|
-
static string
|
|
70
|
+
private static string GetPodInstallArguments(string buildPath)
|
|
81
71
|
{
|
|
82
|
-
|
|
83
|
-
for (int i = 0; i < args.Length; i++)
|
|
72
|
+
if (Application.isBatchMode && TryGetEnv("CI_SCRIPT_DIR", out string scriptDir))
|
|
84
73
|
{
|
|
85
|
-
|
|
74
|
+
return $"{scriptDir}/utils.sh pod-install";
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (!Application.isBatchMode && !string.IsNullOrEmpty(buildPath))
|
|
78
|
+
{
|
|
79
|
+
string podPath = GetPodExecutablePath();
|
|
80
|
+
if (!string.IsNullOrEmpty(podPath))
|
|
86
81
|
{
|
|
87
|
-
return
|
|
82
|
+
return $"-c \"{podPath} install --project-directory={buildPath}\"";
|
|
88
83
|
}
|
|
89
84
|
}
|
|
85
|
+
|
|
90
86
|
return null;
|
|
91
87
|
}
|
|
92
88
|
|
|
93
|
-
static string
|
|
89
|
+
private static string GetPodExecutablePath()
|
|
94
90
|
{
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
where scene.enabled
|
|
98
|
-
where !string.IsNullOrEmpty(scene.path)
|
|
99
|
-
select scene.path
|
|
100
|
-
).ToArray();
|
|
91
|
+
string[] possiblePaths = { "/usr/local/bin/pod", "/opt/homebrew/bin/pod" };
|
|
92
|
+
return possiblePaths.FirstOrDefault(File.Exists);
|
|
101
93
|
}
|
|
102
94
|
|
|
103
|
-
static
|
|
95
|
+
private static Process CreatePodInstallProcess(string arguments, EventHandler processExit)
|
|
104
96
|
{
|
|
105
|
-
|
|
106
|
-
|
|
97
|
+
var startInfo = new ProcessStartInfo
|
|
98
|
+
{
|
|
99
|
+
FileName = "/bin/zsh",
|
|
100
|
+
Arguments = arguments,
|
|
101
|
+
CreateNoWindow = false,
|
|
102
|
+
RedirectStandardOutput = true,
|
|
103
|
+
RedirectStandardError = true,
|
|
104
|
+
UseShellExecute = false
|
|
105
|
+
};
|
|
107
106
|
|
|
108
|
-
|
|
107
|
+
var process = new Process
|
|
109
108
|
{
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
// side effect to fix android build system:
|
|
114
|
-
EditorUserBuildSettings.androidBuildSystem = AndroidBuildSystem.Internal;
|
|
115
|
-
#endif
|
|
116
|
-
}
|
|
109
|
+
StartInfo = startInfo,
|
|
110
|
+
EnableRaisingEvents = true
|
|
111
|
+
};
|
|
117
112
|
|
|
118
|
-
|
|
119
|
-
|
|
113
|
+
process.OutputDataReceived += (sender, args) =>
|
|
114
|
+
{
|
|
115
|
+
if (args.Data != null)
|
|
116
|
+
{
|
|
117
|
+
Debug.Log(args.Data);
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
120
|
|
|
121
|
-
|
|
121
|
+
process.Exited += processExit;
|
|
122
|
+
return process;
|
|
123
|
+
}
|
|
122
124
|
|
|
123
|
-
|
|
125
|
+
private static void ExecuteProcess(Process process)
|
|
126
|
+
{
|
|
127
|
+
process.Start();
|
|
128
|
+
process.BeginOutputReadLine();
|
|
129
|
+
process.BeginErrorReadLine();
|
|
130
|
+
process.WaitForExit();
|
|
124
131
|
}
|
|
132
|
+
|
|
133
|
+
#endregion
|
|
125
134
|
|
|
126
|
-
|
|
135
|
+
#region Argument Parsing
|
|
136
|
+
|
|
137
|
+
/// <summary>
|
|
138
|
+
/// Gets a command line argument value by name.
|
|
139
|
+
/// </summary>
|
|
140
|
+
/// <param name="name">Argument name to search for</param>
|
|
141
|
+
/// <returns>Argument value or null if not found</returns>
|
|
142
|
+
private static string GetArgument(string name)
|
|
143
|
+
{
|
|
144
|
+
string[] args = Environment.GetCommandLineArgs();
|
|
145
|
+
for (int i = 0; i < args.Length; i++)
|
|
146
|
+
{
|
|
147
|
+
if (args[i].Contains(name) && i + 1 < args.Length)
|
|
148
|
+
{
|
|
149
|
+
return args[i + 1];
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
return null;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
private static string GetBuildPath()
|
|
127
156
|
{
|
|
128
157
|
string buildPath = GetArgument("customBuildPath");
|
|
129
|
-
|
|
130
|
-
|
|
158
|
+
LogInfo($"Received customBuildPath: {buildPath}");
|
|
159
|
+
|
|
160
|
+
if (string.IsNullOrEmpty(buildPath))
|
|
131
161
|
{
|
|
132
|
-
throw new
|
|
162
|
+
throw new ArgumentException("customBuildPath argument is missing");
|
|
133
163
|
}
|
|
164
|
+
|
|
134
165
|
return buildPath;
|
|
135
166
|
}
|
|
136
167
|
|
|
137
|
-
static string GetBuildName()
|
|
168
|
+
private static string GetBuildName()
|
|
138
169
|
{
|
|
139
170
|
string buildName = GetArgument("customBuildName");
|
|
140
|
-
|
|
141
|
-
|
|
171
|
+
LogInfo($"Received customBuildName: {buildName}");
|
|
172
|
+
|
|
173
|
+
if (string.IsNullOrEmpty(buildName))
|
|
142
174
|
{
|
|
143
|
-
throw new
|
|
175
|
+
throw new ArgumentException("customBuildName argument is missing");
|
|
144
176
|
}
|
|
177
|
+
|
|
145
178
|
return buildName;
|
|
146
179
|
}
|
|
180
|
+
|
|
181
|
+
#endregion
|
|
182
|
+
|
|
183
|
+
#region Build Configuration
|
|
184
|
+
|
|
185
|
+
/// <summary>
|
|
186
|
+
/// Gets enabled scenes for build.
|
|
187
|
+
/// </summary>
|
|
188
|
+
/// <returns>Array of enabled scene paths</returns>
|
|
189
|
+
private static string[] GetEnabledScenes()
|
|
190
|
+
{
|
|
191
|
+
return EditorBuildSettings.scenes
|
|
192
|
+
.Where(scene => scene.enabled && !string.IsNullOrEmpty(scene.path))
|
|
193
|
+
.Select(scene => scene.path)
|
|
194
|
+
.ToArray();
|
|
195
|
+
}
|
|
147
196
|
|
|
148
|
-
|
|
197
|
+
/// <summary>
|
|
198
|
+
/// Determines build target from command line arguments.
|
|
199
|
+
/// </summary>
|
|
200
|
+
/// <returns>Build target enum value</returns>
|
|
201
|
+
private static BuildTarget GetBuildTarget()
|
|
149
202
|
{
|
|
150
|
-
|
|
203
|
+
string buildTargetName = GetArgument("customBuildTarget");
|
|
204
|
+
LogInfo($"Received customBuildTarget: {buildTargetName}");
|
|
205
|
+
|
|
206
|
+
if (string.IsNullOrEmpty(buildTargetName))
|
|
151
207
|
{
|
|
152
|
-
|
|
208
|
+
throw new ArgumentException("customBuildTarget argument is missing");
|
|
153
209
|
}
|
|
154
|
-
|
|
210
|
+
|
|
211
|
+
// Handle legacy Android build system for very old Unity versions
|
|
212
|
+
if (buildTargetName.ToLower() == "android")
|
|
155
213
|
{
|
|
156
|
-
#if
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
buildName += ".apk";
|
|
214
|
+
#if !UNITY_5_6_OR_NEWER
|
|
215
|
+
// Legacy compatibility for Unity < 5.6
|
|
216
|
+
EditorUserBuildSettings.androidBuildSystem = AndroidBuildSystem.Internal;
|
|
160
217
|
#endif
|
|
161
218
|
}
|
|
162
|
-
return buildPath + buildName;
|
|
163
|
-
}
|
|
164
219
|
|
|
165
|
-
|
|
166
|
-
{
|
|
167
|
-
if (TryGetEnv(BUILD_OPTIONS_ENV_VAR, out string envVar))
|
|
220
|
+
if (buildTargetName.TryConvertToEnum(out BuildTarget target))
|
|
168
221
|
{
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
BuildOptions option;
|
|
172
|
-
string optionVar;
|
|
173
|
-
int length = allOptionVars.Length;
|
|
222
|
+
return target;
|
|
223
|
+
}
|
|
174
224
|
|
|
175
|
-
|
|
225
|
+
LogWarning($"Build target '{buildTargetName}' not recognized. Available targets: {string.Join(", ", Enum.GetNames(typeof(BuildTarget)))}");
|
|
226
|
+
return BuildTarget.NoTarget;
|
|
227
|
+
}
|
|
176
228
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
else
|
|
186
|
-
{
|
|
187
|
-
Console.WriteLine($":: Cannot convert {optionVar} to {nameof(BuildOptions)} enum, skipping it.");
|
|
188
|
-
}
|
|
189
|
-
}
|
|
229
|
+
/// <summary>
|
|
230
|
+
/// Generates the final build path with appropriate file extension.
|
|
231
|
+
/// </summary>
|
|
232
|
+
private static string GetFixedBuildPath(BuildTarget buildTarget, string buildPath, string buildName)
|
|
233
|
+
{
|
|
234
|
+
string extension = GetBuildExtension(buildTarget);
|
|
235
|
+
return Path.Combine(buildPath, buildName + extension);
|
|
236
|
+
}
|
|
190
237
|
|
|
191
|
-
|
|
238
|
+
private static string GetBuildExtension(BuildTarget buildTarget)
|
|
239
|
+
{
|
|
240
|
+
switch (buildTarget)
|
|
241
|
+
{
|
|
242
|
+
case BuildTarget.StandaloneWindows:
|
|
243
|
+
case BuildTarget.StandaloneWindows64:
|
|
244
|
+
return ".exe";
|
|
245
|
+
|
|
246
|
+
case BuildTarget.Android:
|
|
247
|
+
#if UNITY_2018_3_OR_NEWER
|
|
248
|
+
return EditorUserBuildSettings.buildAppBundle ? ".aab" : ".apk";
|
|
249
|
+
#else
|
|
250
|
+
return ".apk";
|
|
251
|
+
#endif
|
|
252
|
+
|
|
253
|
+
default:
|
|
254
|
+
return string.Empty;
|
|
192
255
|
}
|
|
193
|
-
|
|
194
|
-
return BuildOptions.None;
|
|
195
256
|
}
|
|
196
257
|
|
|
197
|
-
|
|
198
|
-
|
|
258
|
+
/// <summary>
|
|
259
|
+
/// Parses build options from environment variables.
|
|
260
|
+
/// </summary>
|
|
261
|
+
/// <returns>Combined build options</returns>
|
|
262
|
+
private static BuildOptions GetBuildOptions()
|
|
199
263
|
{
|
|
200
|
-
if (!
|
|
264
|
+
if (!TryGetEnv(BUILD_OPTIONS_ENV_VAR, out string envVar))
|
|
201
265
|
{
|
|
202
|
-
|
|
203
|
-
return false;
|
|
266
|
+
return BuildOptions.None;
|
|
204
267
|
}
|
|
205
268
|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
}
|
|
269
|
+
string[] optionNames = envVar.Split(',');
|
|
270
|
+
BuildOptions combinedOptions = BuildOptions.None;
|
|
209
271
|
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
272
|
+
LogInfo($"Parsing {BUILD_OPTIONS_ENV_VAR} with {optionNames.Length} options: {envVar}");
|
|
273
|
+
|
|
274
|
+
foreach (string optionName in optionNames)
|
|
275
|
+
{
|
|
276
|
+
if (optionName.TryConvertToEnum(out BuildOptions option))
|
|
277
|
+
{
|
|
278
|
+
combinedOptions |= option;
|
|
279
|
+
}
|
|
280
|
+
else
|
|
281
|
+
{
|
|
282
|
+
LogWarning($"Unknown build option: '{optionName}'. Skipping.");
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
return combinedOptions;
|
|
214
287
|
}
|
|
288
|
+
|
|
289
|
+
#endregion
|
|
215
290
|
|
|
216
|
-
|
|
291
|
+
#region Unity Version Compatibility
|
|
292
|
+
|
|
293
|
+
/// <summary>
|
|
294
|
+
/// Sets scripting backend based on environment variable.
|
|
295
|
+
/// Handles Unity version differences for API compatibility.
|
|
296
|
+
/// </summary>
|
|
297
|
+
private static void SetScriptingBackendFromEnv(BuildTarget platform)
|
|
217
298
|
{
|
|
218
299
|
var targetGroup = BuildPipeline.GetBuildTargetGroup(platform);
|
|
300
|
+
|
|
219
301
|
if (TryGetEnv(SCRIPTING_BACKEND_ENV_VAR, out string scriptingBackend))
|
|
220
302
|
{
|
|
221
303
|
if (scriptingBackend.TryConvertToEnum(out ScriptingImplementation backend))
|
|
222
304
|
{
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
PlayerSettings.SetScriptingBackend(UnityEditor.Build.NamedBuildTarget.FromBuildTargetGroup(targetGroup), backend);
|
|
226
|
-
#else
|
|
227
|
-
PlayerSettings.SetScriptingBackend(targetGroup, backend);
|
|
228
|
-
#endif
|
|
305
|
+
LogInfo($"Setting ScriptingBackend to {backend}");
|
|
306
|
+
SetScriptingBackend(targetGroup, backend);
|
|
229
307
|
}
|
|
230
308
|
else
|
|
231
309
|
{
|
|
232
|
-
|
|
233
|
-
throw new
|
|
310
|
+
var availableBackends = string.Join(", ", Enum.GetValues(typeof(ScriptingImplementation)).Cast<ScriptingImplementation>());
|
|
311
|
+
throw new ArgumentException($"Invalid scripting backend '{scriptingBackend}'. Available options: {availableBackends}");
|
|
234
312
|
}
|
|
235
313
|
}
|
|
236
314
|
else
|
|
237
315
|
{
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
#else
|
|
241
|
-
var defaultBackend = PlayerSettings.GetDefaultScriptingBackend(targetGroup);
|
|
242
|
-
#endif
|
|
243
|
-
Console.WriteLine($":: Using project's configured ScriptingBackend (should be {defaultBackend} for targetGroup {targetGroup}");
|
|
316
|
+
var defaultBackend = GetDefaultScriptingBackend(targetGroup);
|
|
317
|
+
LogInfo($"Using project's default ScriptingBackend: {defaultBackend} for {targetGroup}");
|
|
244
318
|
}
|
|
245
319
|
}
|
|
246
320
|
|
|
247
|
-
|
|
321
|
+
private static void SetScriptingBackend(BuildTargetGroup targetGroup, ScriptingImplementation backend)
|
|
248
322
|
{
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
Console.WriteLine($":: Setting bundleVersionNumber to '{bundleVersionNumber}' (Length: {bundleVersionNumber.Length})");
|
|
255
|
-
PlayerSettings.bundleVersion = bundleVersionNumber;
|
|
256
|
-
}
|
|
257
|
-
HandleBuildNumber(buildTarget);
|
|
258
|
-
|
|
259
|
-
if (buildTarget == BuildTarget.Android)
|
|
260
|
-
{
|
|
261
|
-
HandleAndroidAppBundle();
|
|
262
|
-
HandleAndroidKeystore();
|
|
263
|
-
HandleDebugSymbols();
|
|
264
|
-
HandleExportAndroidProject();
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
var buildPath = GetBuildPath();
|
|
268
|
-
var buildName = GetBuildName();
|
|
269
|
-
var buildOptions = GetBuildOptions();
|
|
270
|
-
var fixedBuildPath = GetFixedBuildPath(buildTarget, buildPath, buildName);
|
|
271
|
-
|
|
272
|
-
SetScriptingBackendFromEnv(buildTarget);
|
|
273
|
-
|
|
274
|
-
var buildReport = BuildPipeline.BuildPlayer(GetEnabledScenes(), fixedBuildPath, buildTarget, buildOptions);
|
|
275
|
-
|
|
276
|
-
if (buildReport.summary.result != UnityEditor.Build.Reporting.BuildResult.Succeeded)
|
|
277
|
-
throw new Exception($"Build ended with {buildReport.summary.result} status");
|
|
278
|
-
|
|
279
|
-
BuildMetadata.Save(buildPath, buildTarget);
|
|
280
|
-
Console.WriteLine(":: Done with build");
|
|
323
|
+
#if UNITY_2023_2_OR_NEWER
|
|
324
|
+
PlayerSettings.SetScriptingBackend(UnityEditor.Build.NamedBuildTarget.FromBuildTargetGroup(targetGroup), backend);
|
|
325
|
+
#else
|
|
326
|
+
PlayerSettings.SetScriptingBackend(targetGroup, backend);
|
|
327
|
+
#endif
|
|
281
328
|
}
|
|
282
329
|
|
|
283
|
-
private static
|
|
330
|
+
private static ScriptingImplementation GetDefaultScriptingBackend(BuildTargetGroup targetGroup)
|
|
284
331
|
{
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
#if UNITY_2018_3_OR_NEWER
|
|
288
|
-
if (bool.TryParse(value, out bool buildAppBundle))
|
|
289
|
-
{
|
|
290
|
-
EditorUserBuildSettings.buildAppBundle = buildAppBundle;
|
|
291
|
-
Console.WriteLine($":: {ANDROID_APP_BUNDLE} env var detected, set buildAppBundle to {value}.");
|
|
292
|
-
}
|
|
293
|
-
else
|
|
294
|
-
{
|
|
295
|
-
Console.WriteLine($":: {ANDROID_APP_BUNDLE} env var detected but the value \"{value}\" is not a boolean.");
|
|
296
|
-
}
|
|
332
|
+
#if UNITY_2023_2_OR_NEWER
|
|
333
|
+
return PlayerSettings.GetDefaultScriptingBackend(UnityEditor.Build.NamedBuildTarget.FromBuildTargetGroup(targetGroup));
|
|
297
334
|
#else
|
|
298
|
-
|
|
335
|
+
return PlayerSettings.GetDefaultScriptingBackend(targetGroup);
|
|
299
336
|
#endif
|
|
300
|
-
}
|
|
301
337
|
}
|
|
338
|
+
|
|
339
|
+
#endregion
|
|
302
340
|
|
|
303
|
-
|
|
341
|
+
#region Android-Specific Handling
|
|
342
|
+
|
|
343
|
+
private static void HandleAndroidConfiguration(BuildTarget buildTarget)
|
|
304
344
|
{
|
|
305
|
-
if (
|
|
306
|
-
|
|
345
|
+
if (buildTarget != BuildTarget.Android) return;
|
|
346
|
+
|
|
347
|
+
LogInfo("Configuring Android-specific settings...");
|
|
348
|
+
HandleAndroidAppBundle();
|
|
349
|
+
HandleAndroidKeystore();
|
|
350
|
+
HandleDebugSymbols();
|
|
351
|
+
HandleExportAndroidProject();
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
private static void HandleAndroidAppBundle()
|
|
355
|
+
{
|
|
356
|
+
if (!TryGetEnv(ANDROID_APP_BUNDLE, out string value)) return;
|
|
357
|
+
|
|
358
|
+
#if UNITY_2018_3_OR_NEWER
|
|
359
|
+
if (bool.TryParse(value, out bool buildAppBundle))
|
|
307
360
|
{
|
|
308
|
-
|
|
309
|
-
{
|
|
310
|
-
PlayerSettings.Android.bundleVersionCode = version;
|
|
311
|
-
}
|
|
312
|
-
else if (buildTarget == BuildTarget.iOS)
|
|
313
|
-
{
|
|
314
|
-
PlayerSettings.iOS.buildNumber = version.ToString();
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
Console.WriteLine($":: {VERSION_BUILD_VAR} env var detected, set the bundle version code to {value}.");
|
|
361
|
+
EditorUserBuildSettings.buildAppBundle = buildAppBundle;
|
|
362
|
+
LogInfo($"Set buildAppBundle to {buildAppBundle}");
|
|
318
363
|
}
|
|
319
364
|
else
|
|
320
|
-
|
|
365
|
+
{
|
|
366
|
+
LogWarning($"Invalid {ANDROID_APP_BUNDLE} value: '{value}'. Expected boolean.");
|
|
367
|
+
}
|
|
368
|
+
#else
|
|
369
|
+
LogWarning($"{ANDROID_APP_BUNDLE} requires Unity 2018.3 or newer. Current version does not support this feature.");
|
|
370
|
+
#endif
|
|
321
371
|
}
|
|
322
372
|
|
|
323
373
|
private static void HandleExportAndroidProject()
|
|
324
374
|
{
|
|
325
375
|
EditorUserBuildSettings.exportAsGoogleAndroidProject = false;
|
|
376
|
+
|
|
326
377
|
if (!TryGetEnv(EXPORT_ANDROID_PROJECT, out string stringValue)) return;
|
|
378
|
+
|
|
327
379
|
if (bool.TryParse(stringValue, out bool exportAndroidProject))
|
|
328
380
|
{
|
|
329
381
|
EditorUserBuildSettings.exportAsGoogleAndroidProject = exportAndroidProject;
|
|
382
|
+
LogInfo($"Set exportAsGoogleAndroidProject to {exportAndroidProject}");
|
|
383
|
+
}
|
|
384
|
+
else
|
|
385
|
+
{
|
|
386
|
+
LogWarning($"Invalid {EXPORT_ANDROID_PROJECT} value: '{stringValue}'. Expected boolean.");
|
|
330
387
|
}
|
|
331
388
|
}
|
|
332
389
|
|
|
333
390
|
private static void HandleAndroidKeystore()
|
|
334
391
|
{
|
|
392
|
+
LogInfo("Configuring Android keystore...");
|
|
393
|
+
|
|
335
394
|
#if UNITY_2019_1_OR_NEWER
|
|
336
395
|
PlayerSettings.Android.useCustomKeystore = false;
|
|
337
396
|
#endif
|
|
338
397
|
|
|
339
398
|
if (!File.Exists(KEYSTORE))
|
|
340
399
|
{
|
|
341
|
-
|
|
400
|
+
LogInfo($"Keystore file '{KEYSTORE}' not found. Using Unity's default keystore.");
|
|
342
401
|
return;
|
|
343
402
|
}
|
|
344
403
|
|
|
345
404
|
PlayerSettings.Android.keystoreName = KEYSTORE;
|
|
405
|
+
LogInfo($"Using keystore: {KEYSTORE}");
|
|
346
406
|
|
|
347
|
-
|
|
348
|
-
|
|
407
|
+
ConfigureKeystoreAlias();
|
|
408
|
+
ConfigureKeystorePasswords();
|
|
409
|
+
}
|
|
349
410
|
|
|
411
|
+
private static void ConfigureKeystoreAlias()
|
|
412
|
+
{
|
|
350
413
|
if (TryGetEnv(KEY_ALIAS_NAME, out string keyaliasName))
|
|
351
414
|
{
|
|
352
415
|
PlayerSettings.Android.keyaliasName = keyaliasName;
|
|
353
|
-
|
|
416
|
+
LogInfo($"Set key alias name from environment variable");
|
|
354
417
|
}
|
|
355
418
|
else
|
|
356
419
|
{
|
|
357
|
-
|
|
420
|
+
LogInfo($"Using project's default key alias name");
|
|
358
421
|
}
|
|
422
|
+
}
|
|
359
423
|
|
|
360
|
-
|
|
424
|
+
private static void ConfigureKeystorePasswords()
|
|
425
|
+
{
|
|
426
|
+
if (!TryGetEnv(KEYSTORE_PASS, out string keystorePass))
|
|
361
427
|
{
|
|
362
|
-
|
|
428
|
+
LogWarning($"{KEYSTORE_PASS} not set. Using Unity's default keystore.");
|
|
363
429
|
return;
|
|
364
430
|
}
|
|
365
431
|
|
|
366
|
-
if (!TryGetEnv(KEY_ALIAS_PASS, out keystoreAliasPass))
|
|
432
|
+
if (!TryGetEnv(KEY_ALIAS_PASS, out string keystoreAliasPass))
|
|
367
433
|
{
|
|
368
|
-
|
|
434
|
+
LogWarning($"{KEY_ALIAS_PASS} not set. Using Unity's default keystore.");
|
|
369
435
|
return;
|
|
370
436
|
}
|
|
437
|
+
|
|
371
438
|
#if UNITY_2019_1_OR_NEWER
|
|
372
439
|
PlayerSettings.Android.useCustomKeystore = true;
|
|
373
440
|
#endif
|
|
374
|
-
|
|
375
|
-
|
|
441
|
+
|
|
442
|
+
#if UNITY_2023_2_OR_NEWER
|
|
376
443
|
PlayerSettings.Android.keystorePass = keystorePass;
|
|
377
|
-
|
|
444
|
+
#else
|
|
378
445
|
PlayerSettings.keystorePass = keystorePass;
|
|
379
|
-
|
|
446
|
+
#endif
|
|
380
447
|
|
|
381
448
|
PlayerSettings.Android.keyaliasPass = keystoreAliasPass;
|
|
449
|
+
LogInfo("Keystore passwords configured successfully");
|
|
382
450
|
}
|
|
383
451
|
|
|
384
452
|
private static void HandleDebugSymbols()
|
|
385
453
|
{
|
|
386
|
-
|
|
454
|
+
LogInfo("Configuring Android debug symbols...");
|
|
455
|
+
|
|
456
|
+
#if UNITY_6000_0_OR_NEWER
|
|
387
457
|
UnityEditor.Android.UserBuildSettings.DebugSymbols.level = Unity.Android.Types.DebugSymbolLevel.SymbolTable;
|
|
388
|
-
|
|
458
|
+
LogInfo("Set debug symbols level to SymbolTable (Unity 6+)");
|
|
459
|
+
#elif UNITY_2021_1_OR_NEWER
|
|
389
460
|
EditorUserBuildSettings.androidCreateSymbols = AndroidCreateSymbols.Debugging;
|
|
390
|
-
|
|
391
|
-
|
|
461
|
+
LogInfo("Set debug symbols to Debugging (Unity 2021.1+)");
|
|
462
|
+
#else
|
|
392
463
|
EditorUserBuildSettings.androidCreateSymbolsZip = true;
|
|
393
|
-
|
|
464
|
+
LogInfo("Enabled debug symbols zip (Unity 2020.3 and earlier)");
|
|
465
|
+
#endif
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
#endregion
|
|
469
|
+
|
|
470
|
+
#region Version Handling
|
|
471
|
+
|
|
472
|
+
private static void HandleVersionConfiguration(BuildTarget buildTarget)
|
|
473
|
+
{
|
|
474
|
+
HandleBundleVersion();
|
|
475
|
+
HandleBuildNumber(buildTarget);
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
private static void HandleBundleVersion()
|
|
479
|
+
{
|
|
480
|
+
if (TryGetEnv(VERSION_NUMBER_VAR, out string bundleVersionNumber))
|
|
481
|
+
{
|
|
482
|
+
LogInfo($"Setting bundle version to '{bundleVersionNumber}' (Length: {bundleVersionNumber.Length})");
|
|
483
|
+
PlayerSettings.bundleVersion = bundleVersionNumber;
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
private static void HandleBuildNumber(BuildTarget buildTarget)
|
|
488
|
+
{
|
|
489
|
+
if (!TryGetEnv(VERSION_BUILD_VAR, out string value)) return;
|
|
490
|
+
|
|
491
|
+
if (!int.TryParse(value, out int buildNumber))
|
|
492
|
+
{
|
|
493
|
+
LogWarning($"Invalid {VERSION_BUILD_VAR} value: '{value}'. Expected integer.");
|
|
494
|
+
return;
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
switch (buildTarget)
|
|
498
|
+
{
|
|
499
|
+
case BuildTarget.Android:
|
|
500
|
+
PlayerSettings.Android.bundleVersionCode = buildNumber;
|
|
501
|
+
LogInfo($"Set Android bundle version code to {buildNumber}");
|
|
502
|
+
break;
|
|
503
|
+
|
|
504
|
+
case BuildTarget.iOS:
|
|
505
|
+
PlayerSettings.iOS.buildNumber = buildNumber.ToString();
|
|
506
|
+
LogInfo($"Set iOS build number to {buildNumber}");
|
|
507
|
+
break;
|
|
508
|
+
|
|
509
|
+
default:
|
|
510
|
+
LogInfo($"Build number not applicable for platform: {buildTarget}");
|
|
511
|
+
break;
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
#endregion
|
|
516
|
+
|
|
517
|
+
#region Main Build Method
|
|
518
|
+
|
|
519
|
+
/// <summary>
|
|
520
|
+
/// Main entry point for performing Unity builds in CI environment.
|
|
521
|
+
/// </summary>
|
|
522
|
+
public static void PerformBuild()
|
|
523
|
+
{
|
|
524
|
+
try
|
|
525
|
+
{
|
|
526
|
+
LogInfo("=== Starting Unity Build Process ===");
|
|
527
|
+
|
|
528
|
+
var buildTarget = GetBuildTarget();
|
|
529
|
+
var buildPath = GetBuildPath();
|
|
530
|
+
var buildName = GetBuildName();
|
|
531
|
+
var buildOptions = GetBuildOptions();
|
|
532
|
+
var fixedBuildPath = GetFixedBuildPath(buildTarget, buildPath, buildName);
|
|
533
|
+
|
|
534
|
+
LogInfo($"Build configuration: Target={buildTarget}, Path={fixedBuildPath}, Options={buildOptions}");
|
|
535
|
+
|
|
536
|
+
// Configure build settings
|
|
537
|
+
HandleVersionConfiguration(buildTarget);
|
|
538
|
+
HandleAndroidConfiguration(buildTarget);
|
|
539
|
+
SetScriptingBackendFromEnv(buildTarget);
|
|
540
|
+
|
|
541
|
+
// Perform the build
|
|
542
|
+
var buildPlayerOptions = new BuildPlayerOptions
|
|
543
|
+
{
|
|
544
|
+
scenes = GetEnabledScenes(),
|
|
545
|
+
locationPathName = fixedBuildPath,
|
|
546
|
+
target = buildTarget,
|
|
547
|
+
targetGroup = BuildPipeline.GetBuildTargetGroup(buildTarget),
|
|
548
|
+
options = buildOptions
|
|
549
|
+
};
|
|
550
|
+
|
|
551
|
+
LogInfo($"Building to: {fixedBuildPath}");
|
|
552
|
+
var buildReport = BuildPipeline.BuildPlayer(buildPlayerOptions);
|
|
553
|
+
|
|
554
|
+
// Handle build results
|
|
555
|
+
ReportSummary(buildReport.summary);
|
|
556
|
+
|
|
557
|
+
if (buildReport.summary.result != UnityEditor.Build.Reporting.BuildResult.Succeeded)
|
|
558
|
+
{
|
|
559
|
+
throw new Exception($"Build failed with status: {buildReport.summary.result}");
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
// Save build metadata
|
|
563
|
+
BuildMetadata.Save(buildPath, buildTarget);
|
|
564
|
+
LogInfo("=== Build Process Completed Successfully ===");
|
|
565
|
+
}
|
|
566
|
+
catch (Exception ex)
|
|
567
|
+
{
|
|
568
|
+
LogError($"Build process failed: {ex.Message}");
|
|
569
|
+
throw;
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
#endregion
|
|
574
|
+
|
|
575
|
+
#region Build Reporting
|
|
576
|
+
|
|
577
|
+
private static void ReportSummary(BuildSummary summary)
|
|
578
|
+
{
|
|
579
|
+
var report = new System.Text.StringBuilder()
|
|
580
|
+
.AppendLine()
|
|
581
|
+
.AppendLine("###########################")
|
|
582
|
+
.AppendLine("# Build Results #")
|
|
583
|
+
.AppendLine("###########################")
|
|
584
|
+
.AppendLine()
|
|
585
|
+
.AppendLine($"Platform Group: {summary.platformGroup}")
|
|
586
|
+
.AppendLine($"Platform: {summary.platform}")
|
|
587
|
+
.AppendLine($"Result: {summary.result}")
|
|
588
|
+
.AppendLine($"Duration: {summary.totalTime}")
|
|
589
|
+
.AppendLine($"Warnings: {summary.totalWarnings}")
|
|
590
|
+
.AppendLine($"Errors: {summary.totalErrors}")
|
|
591
|
+
.AppendLine($"Size: {summary.totalSize:N0} bytes")
|
|
592
|
+
.AppendLine()
|
|
593
|
+
.ToString();
|
|
594
|
+
|
|
595
|
+
Console.WriteLine(report);
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
#endregion
|
|
599
|
+
|
|
600
|
+
#region Utility Methods
|
|
601
|
+
|
|
602
|
+
/// <summary>
|
|
603
|
+
/// Tries to get environment variable value.
|
|
604
|
+
/// </summary>
|
|
605
|
+
/// <param name="key">Environment variable key</param>
|
|
606
|
+
/// <param name="value">Retrieved value</param>
|
|
607
|
+
/// <returns>True if variable exists and is not empty</returns>
|
|
608
|
+
internal static bool TryGetEnv(string key, out string value)
|
|
609
|
+
{
|
|
610
|
+
value = Environment.GetEnvironmentVariable(key);
|
|
611
|
+
return !string.IsNullOrEmpty(value);
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
/// <summary>
|
|
615
|
+
/// Extension method to safely convert string to enum.
|
|
616
|
+
/// </summary>
|
|
617
|
+
private static bool TryConvertToEnum<TEnum>(this string strEnumValue, out TEnum value) where TEnum : struct
|
|
618
|
+
{
|
|
619
|
+
return Enum.TryParse(strEnumValue, out value) && Enum.IsDefined(typeof(TEnum), value);
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
private static void LogInfo(string message)
|
|
623
|
+
{
|
|
624
|
+
Console.WriteLine($":: {message}");
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
private static void LogWarning(string message)
|
|
628
|
+
{
|
|
629
|
+
Console.WriteLine($":: WARNING: {message}");
|
|
394
630
|
}
|
|
631
|
+
|
|
632
|
+
private static void LogError(string message)
|
|
633
|
+
{
|
|
634
|
+
Console.WriteLine($":: ERROR: {message}");
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
#endregion
|
|
395
638
|
}
|
|
396
639
|
|
|
640
|
+
#region Build Metadata
|
|
641
|
+
|
|
642
|
+
/// <summary>
|
|
643
|
+
/// Contains build metadata information for CI tracking.
|
|
644
|
+
/// </summary>
|
|
397
645
|
[Serializable]
|
|
398
646
|
public class BuildMetadata
|
|
399
647
|
{
|
|
400
648
|
public string appVersion;
|
|
401
649
|
public string buildNumber;
|
|
402
|
-
public string buildTarget;
|
|
650
|
+
public string buildTarget;
|
|
403
651
|
|
|
652
|
+
/// <summary>
|
|
653
|
+
/// Saves build metadata to a JSON file in the build directory.
|
|
654
|
+
/// </summary>
|
|
655
|
+
/// <param name="buildPath">Build output directory</param>
|
|
656
|
+
/// <param name="buildTarget">Target platform</param>
|
|
404
657
|
public static void Save(string buildPath, BuildTarget buildTarget)
|
|
405
658
|
{
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
var metadata = new BuildMetadata
|
|
659
|
+
try
|
|
409
660
|
{
|
|
410
|
-
|
|
411
|
-
buildNumber = buildTarget == BuildTarget.Android ? PlayerSettings.Android.bundleVersionCode.ToString() : PlayerSettings.iOS.buildNumber,
|
|
412
|
-
buildTarget = buildTarget.ToString()
|
|
413
|
-
};
|
|
661
|
+
string outputFile = Path.Combine(buildPath, "build_info.json");
|
|
414
662
|
|
|
415
|
-
|
|
416
|
-
|
|
663
|
+
var metadata = new BuildMetadata
|
|
664
|
+
{
|
|
665
|
+
appVersion = PlayerSettings.bundleVersion,
|
|
666
|
+
buildNumber = GetBuildNumberForPlatform(buildTarget),
|
|
667
|
+
buildTarget = buildTarget.ToString()
|
|
668
|
+
};
|
|
669
|
+
|
|
670
|
+
string json = JsonUtility.ToJson(metadata, prettyPrint: true);
|
|
671
|
+
File.WriteAllText(outputFile, json);
|
|
417
672
|
|
|
418
|
-
|
|
673
|
+
Console.WriteLine($":: Build metadata saved to: {outputFile}");
|
|
674
|
+
}
|
|
675
|
+
catch (Exception ex)
|
|
676
|
+
{
|
|
677
|
+
Console.WriteLine($":: WARNING: Failed to save build metadata: {ex.Message}");
|
|
678
|
+
}
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
private static string GetBuildNumberForPlatform(BuildTarget buildTarget)
|
|
682
|
+
{
|
|
683
|
+
switch (buildTarget)
|
|
684
|
+
{
|
|
685
|
+
case BuildTarget.Android:
|
|
686
|
+
return PlayerSettings.Android.bundleVersionCode.ToString();
|
|
687
|
+
case BuildTarget.iOS:
|
|
688
|
+
return PlayerSettings.iOS.buildNumber;
|
|
689
|
+
default:
|
|
690
|
+
return "0";
|
|
691
|
+
}
|
|
419
692
|
}
|
|
420
693
|
}
|
|
421
694
|
|
|
422
|
-
|
|
695
|
+
#endregion
|
|
696
|
+
|
|
697
|
+
#region Preprocessor
|
|
698
|
+
|
|
699
|
+
/// <summary>
|
|
700
|
+
/// Preprocessor for handling CI-specific build settings.
|
|
701
|
+
/// </summary>
|
|
702
|
+
public class GDKPreProcessBuild : IPreprocessBuildWithReport
|
|
423
703
|
{
|
|
424
|
-
public int callbackOrder
|
|
425
|
-
|
|
426
|
-
get { return 0; }
|
|
427
|
-
}
|
|
704
|
+
public int callbackOrder => 0;
|
|
705
|
+
|
|
428
706
|
public void OnPreprocessBuild(BuildReport report)
|
|
429
707
|
{
|
|
430
708
|
if (report.summary.platform != BuildTarget.Android) return;
|
|
431
|
-
|
|
709
|
+
|
|
710
|
+
// Configure Gradle path for CI builds
|
|
432
711
|
if (!Application.isBatchMode) return;
|
|
712
|
+
|
|
433
713
|
if (!GDKCIBuildCommand.TryGetEnv("GRADLE_PATH", out string envGradlePath)) return;
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
714
|
+
|
|
715
|
+
try
|
|
716
|
+
{
|
|
717
|
+
EditorPrefs.SetBool("GradleUseEmbedded", false);
|
|
718
|
+
EditorPrefs.SetString("GradlePath", envGradlePath);
|
|
719
|
+
Debug.Log($"Updated Gradle path to: {envGradlePath}");
|
|
720
|
+
}
|
|
721
|
+
catch (Exception ex)
|
|
722
|
+
{
|
|
723
|
+
Debug.LogError($"Failed to set Gradle path: {ex.Message}");
|
|
724
|
+
}
|
|
438
725
|
}
|
|
439
726
|
}
|
|
727
|
+
|
|
728
|
+
#endregion
|
|
440
729
|
}
|
|
@@ -211,7 +211,18 @@ namespace Amanotes.Editor
|
|
|
211
211
|
private void ExportBuild(BuildInfo info)
|
|
212
212
|
{
|
|
213
213
|
string fullBuildPath = info.fullBuildPath(buildFolder);
|
|
214
|
-
|
|
214
|
+
|
|
215
|
+
// Use BuildPlayerOptions instead of deprecated overload for Unity 6 compatibility
|
|
216
|
+
var buildPlayerOptions = new BuildPlayerOptions
|
|
217
|
+
{
|
|
218
|
+
scenes = GetScenes(),
|
|
219
|
+
locationPathName = fullBuildPath,
|
|
220
|
+
target = info.target,
|
|
221
|
+
targetGroup = BuildPipeline.GetBuildTargetGroup(info.target),
|
|
222
|
+
options = BuildOptions.None
|
|
223
|
+
};
|
|
224
|
+
|
|
225
|
+
BuildPipeline.BuildPlayer(buildPlayerOptions);
|
|
215
226
|
info.PostProcessBuild(buildFolder);
|
|
216
227
|
|
|
217
228
|
// if (buildRQ.willRunSHPostBuild)
|
|
@@ -201,6 +201,24 @@ namespace Amanotes.Editor
|
|
|
201
201
|
Debug.Log($"Set build property: {property.key} = {property.value}");
|
|
202
202
|
}
|
|
203
203
|
}
|
|
204
|
+
|
|
205
|
+
static PBXCapabilityType CapabilityFromString(string name)
|
|
206
|
+
{
|
|
207
|
+
return name switch
|
|
208
|
+
{
|
|
209
|
+
"iCloud" => PBXCapabilityType.iCloud,
|
|
210
|
+
"InAppPurchase" => PBXCapabilityType.InAppPurchase,
|
|
211
|
+
"GameCenter" => PBXCapabilityType.GameCenter,
|
|
212
|
+
"PushNotifications" => PBXCapabilityType.PushNotifications,
|
|
213
|
+
"Wallet" => PBXCapabilityType.Wallet,
|
|
214
|
+
"ApplePay" => PBXCapabilityType.ApplePay,
|
|
215
|
+
"PersonalVPN" => PBXCapabilityType.PersonalVPN,
|
|
216
|
+
"HealthKit" => PBXCapabilityType.HealthKit,
|
|
217
|
+
"HomeKit" => PBXCapabilityType.HomeKit,
|
|
218
|
+
// add any others you use…
|
|
219
|
+
_ => throw new ArgumentException($"Unknown capability: {name}")
|
|
220
|
+
};
|
|
221
|
+
}
|
|
204
222
|
|
|
205
223
|
// Enable Capabilities
|
|
206
224
|
private void AddCapabilities(PBXProject proj, string pathToBuildProject, string targetGuid)
|
|
@@ -209,7 +227,7 @@ namespace Amanotes.Editor
|
|
|
209
227
|
{
|
|
210
228
|
if (!capability.enable) continue;
|
|
211
229
|
|
|
212
|
-
var pbxCapabilityType =
|
|
230
|
+
var pbxCapabilityType = CapabilityFromString(capability.type);
|
|
213
231
|
if (pbxCapabilityType == null)
|
|
214
232
|
{
|
|
215
233
|
Debug.LogError($"Unknown capability type: {capability.type}");
|
|
@@ -225,12 +243,12 @@ namespace Amanotes.Editor
|
|
|
225
243
|
continue;
|
|
226
244
|
}
|
|
227
245
|
proj.AddCapability(targetGuid, pbxCapabilityType, entitlementsPath);
|
|
228
|
-
Debug.Log($"Added capability: {pbxCapabilityType
|
|
246
|
+
Debug.Log($"Added capability: {pbxCapabilityType} with entitlements: {entitlementsPath}");
|
|
229
247
|
}
|
|
230
248
|
else
|
|
231
249
|
{
|
|
232
250
|
proj.AddCapability(targetGuid, pbxCapabilityType);
|
|
233
|
-
Debug.Log($"Added capability: {pbxCapabilityType
|
|
251
|
+
Debug.Log($"Added capability: {pbxCapabilityType}");
|
|
234
252
|
}
|
|
235
253
|
}
|
|
236
254
|
}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/Runtime/Ad/AdLogic.cs
CHANGED
|
@@ -207,7 +207,11 @@ namespace Amanotes.Core.Internal
|
|
|
207
207
|
if (!isAdReady)
|
|
208
208
|
{
|
|
209
209
|
yield return HandleNotReadyAd();
|
|
210
|
-
if (_showState
|
|
210
|
+
if (_showState != ShowAdsState.WaitForAd || _loadState != LoadAdsState.Ready || !isAdReady)
|
|
211
|
+
{
|
|
212
|
+
Log($"[Ad] Terminate ShowAdRoutine _showState ${_showState.ToString()} _loadState: {_loadState.ToString()} || isAdReady: {isAdReady}");
|
|
213
|
+
yield break;
|
|
214
|
+
}
|
|
211
215
|
}
|
|
212
216
|
|
|
213
217
|
yield return ExecuteAdShow();
|
package/Runtime/AmaGDK.cs
CHANGED
|
@@ -27,7 +27,7 @@ namespace Amanotes.Core
|
|
|
27
27
|
{
|
|
28
28
|
public partial class AmaGDK : MonoBehaviour
|
|
29
29
|
{
|
|
30
|
-
public const string VERSION = "0.2.
|
|
30
|
+
public const string VERSION = "0.2.89";
|
|
31
31
|
|
|
32
32
|
internal static Status _status = Status.None;
|
|
33
33
|
internal static ConfigAsset _config = null;
|
|
@@ -136,22 +136,32 @@ namespace Amanotes.Core.Internal
|
|
|
136
136
|
|
|
137
137
|
public static IEnumerator CheckInternet(Action<bool> hasInternet)
|
|
138
138
|
{
|
|
139
|
-
|
|
140
|
-
|
|
139
|
+
try
|
|
140
|
+
{
|
|
141
|
+
UnityWebRequest www = UnityWebRequest.Get(AmaGDK.Config.common.internetCheckUrl);
|
|
142
|
+
www.timeout = 10; // Set a reasonable timeout
|
|
143
|
+
yield return www.SendWebRequest();
|
|
141
144
|
|
|
142
|
-
|
|
145
|
+
if (www.result != UnityWebRequest.Result.Success && www.responseCode != 429) //429 = Too many requests
|
|
146
|
+
{
|
|
147
|
+
hasInternet?.Invoke(false);
|
|
148
|
+
yield break;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
hasInternet?.Invoke(true);
|
|
152
|
+
}
|
|
153
|
+
catch (System.Exception ex)
|
|
143
154
|
{
|
|
155
|
+
// Log the exception but assume no internet connection
|
|
156
|
+
LogWarning($"Internet check failed with exception: {ex.Message}");
|
|
144
157
|
hasInternet?.Invoke(false);
|
|
145
|
-
yield break;
|
|
146
158
|
}
|
|
147
|
-
|
|
148
|
-
hasInternet?.Invoke(true);
|
|
149
159
|
}
|
|
150
160
|
}
|
|
151
161
|
|
|
152
162
|
public partial class SDKConfig
|
|
153
163
|
{
|
|
154
164
|
[Tooltip("The URL we would use to ping to verify if the app is actually connected to the internet")]
|
|
155
|
-
public string internetCheckUrl = "
|
|
165
|
+
public string internetCheckUrl = "https://clients3.google.com/generate_204";
|
|
156
166
|
}
|
|
157
167
|
}
|