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 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
@@ -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=gray>v{AmaGDK.VERSION}</color></size>"
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
- string arguments = "";
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
- // Configure process start info
43
- var startInfo = new ProcessStartInfo
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
- StartInfo = startInfo,
56
- EnableRaisingEvents = true
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
- // Start the process
69
- proc.Start();
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 GetArgument(string name)
70
+ private static string GetPodInstallArguments(string buildPath)
81
71
  {
82
- string[] args = Environment.GetCommandLineArgs();
83
- for (int i = 0; i < args.Length; i++)
72
+ if (Application.isBatchMode && TryGetEnv("CI_SCRIPT_DIR", out string scriptDir))
84
73
  {
85
- if (args[i].Contains(name))
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 args[i + 1];
82
+ return $"-c \"{podPath} install --project-directory={buildPath}\"";
88
83
  }
89
84
  }
85
+
90
86
  return null;
91
87
  }
92
88
 
93
- static string[] GetEnabledScenes()
89
+ private static string GetPodExecutablePath()
94
90
  {
95
- return (
96
- from scene in EditorBuildSettings.scenes
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 BuildTarget GetBuildTarget()
95
+ private static Process CreatePodInstallProcess(string arguments, EventHandler processExit)
104
96
  {
105
- string buildTargetName = GetArgument("customBuildTarget");
106
- Console.WriteLine(":: Received customBuildTarget " + buildTargetName);
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
- if (buildTargetName.ToLower() == "android")
107
+ var process = new Process
109
108
  {
110
- #if !UNITY_5_6_OR_NEWER
111
- // https://issuetracker.unity3d.com/issues/buildoptions-dot-acceptexternalmodificationstoplayer-causes-unityexception-unknown-project-type-0
112
- // Fixed in Unity 5.6.0
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
- if (buildTargetName.TryConvertToEnum(out BuildTarget target))
119
- return target;
113
+ process.OutputDataReceived += (sender, args) =>
114
+ {
115
+ if (args.Data != null)
116
+ {
117
+ Debug.Log(args.Data);
118
+ }
119
+ };
120
120
 
121
- Console.WriteLine($":: {nameof(buildTargetName)} \"{buildTargetName}\" not defined on enum {nameof(BuildTarget)}, using {nameof(BuildTarget.NoTarget)} enum to build");
121
+ process.Exited += processExit;
122
+ return process;
123
+ }
122
124
 
123
- return BuildTarget.NoTarget;
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
- static string GetBuildPath()
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
- Console.WriteLine(":: Received customBuildPath " + buildPath);
130
- if (buildPath == "")
158
+ LogInfo($"Received customBuildPath: {buildPath}");
159
+
160
+ if (string.IsNullOrEmpty(buildPath))
131
161
  {
132
- throw new Exception("customBuildPath argument is missing");
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
- Console.WriteLine(":: Received customBuildName " + buildName);
141
- if (buildName == "")
171
+ LogInfo($"Received customBuildName: {buildName}");
172
+
173
+ if (string.IsNullOrEmpty(buildName))
142
174
  {
143
- throw new Exception("customBuildName argument is missing");
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
- static string GetFixedBuildPath(BuildTarget buildTarget, string buildPath, string buildName)
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
- if (buildTarget.ToString().ToLower().Contains("windows"))
203
+ string buildTargetName = GetArgument("customBuildTarget");
204
+ LogInfo($"Received customBuildTarget: {buildTargetName}");
205
+
206
+ if (string.IsNullOrEmpty(buildTargetName))
151
207
  {
152
- buildName += ".exe";
208
+ throw new ArgumentException("customBuildTarget argument is missing");
153
209
  }
154
- else if (buildTarget == BuildTarget.Android)
210
+
211
+ // Handle legacy Android build system for very old Unity versions
212
+ if (buildTargetName.ToLower() == "android")
155
213
  {
156
- #if UNITY_2018_3_OR_NEWER
157
- buildName += EditorUserBuildSettings.buildAppBundle ? ".aab" : ".apk";
158
- #else
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
- static BuildOptions GetBuildOptions()
166
- {
167
- if (TryGetEnv(BUILD_OPTIONS_ENV_VAR, out string envVar))
220
+ if (buildTargetName.TryConvertToEnum(out BuildTarget target))
168
221
  {
169
- string[] allOptionVars = envVar.Split(',');
170
- BuildOptions allOptions = BuildOptions.None;
171
- BuildOptions option;
172
- string optionVar;
173
- int length = allOptionVars.Length;
222
+ return target;
223
+ }
174
224
 
175
- Console.WriteLine($":: Detecting {BUILD_OPTIONS_ENV_VAR} env var with {length} elements ({envVar})");
225
+ LogWarning($"Build target '{buildTargetName}' not recognized. Available targets: {string.Join(", ", Enum.GetNames(typeof(BuildTarget)))}");
226
+ return BuildTarget.NoTarget;
227
+ }
176
228
 
177
- for (int i = 0; i < length; i++)
178
- {
179
- optionVar = allOptionVars[i];
180
-
181
- if (optionVar.TryConvertToEnum(out option))
182
- {
183
- allOptions |= option;
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
- return allOptions;
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
- // https://stackoverflow.com/questions/1082532/how-to-tryparse-for-enum-value
198
- static bool TryConvertToEnum<TEnum>(this string strEnumValue, out TEnum value)
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 (!Enum.IsDefined(typeof(TEnum), strEnumValue))
264
+ if (!TryGetEnv(BUILD_OPTIONS_ENV_VAR, out string envVar))
201
265
  {
202
- value = default;
203
- return false;
266
+ return BuildOptions.None;
204
267
  }
205
268
 
206
- value = (TEnum)Enum.Parse(typeof(TEnum), strEnumValue);
207
- return true;
208
- }
269
+ string[] optionNames = envVar.Split(',');
270
+ BuildOptions combinedOptions = BuildOptions.None;
209
271
 
210
- internal static bool TryGetEnv(string key, out string value)
211
- {
212
- value = Environment.GetEnvironmentVariable(key);
213
- return !string.IsNullOrEmpty(value);
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
- static void SetScriptingBackendFromEnv(BuildTarget platform)
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
- Console.WriteLine($":: Setting ScriptingBackend to {backend}");
224
- #if UNITY_2023_2_OR_NEWER
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
- string possibleValues = string.Join(", ", Enum.GetValues(typeof(ScriptingImplementation)).Cast<ScriptingImplementation>());
233
- throw new Exception($"Could not find '{scriptingBackend}' in ScriptingImplementation enum. Possible values are: {possibleValues}");
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
- #if UNITY_2023_2_OR_NEWER
239
- var defaultBackend = PlayerSettings.GetDefaultScriptingBackend(UnityEditor.Build.NamedBuildTarget.FromBuildTargetGroup(targetGroup));
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
- public static void PerformBuild()
321
+ private static void SetScriptingBackend(BuildTargetGroup targetGroup, ScriptingImplementation backend)
248
322
  {
249
- var buildTarget = GetBuildTarget();
250
-
251
- Console.WriteLine(":: Performing build");
252
- if (TryGetEnv(VERSION_NUMBER_VAR, out string bundleVersionNumber))
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 void HandleAndroidAppBundle()
330
+ private static ScriptingImplementation GetDefaultScriptingBackend(BuildTargetGroup targetGroup)
284
331
  {
285
- if (TryGetEnv(ANDROID_APP_BUNDLE, out string value))
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
- Console.WriteLine($":: {ANDROID_APP_BUNDLE} env var detected but does not work with lower Unity version than 2018.3");
335
+ return PlayerSettings.GetDefaultScriptingBackend(targetGroup);
299
336
  #endif
300
- }
301
337
  }
338
+
339
+ #endregion
302
340
 
303
- private static void HandleBuildNumber(BuildTarget buildTarget)
341
+ #region Android-Specific Handling
342
+
343
+ private static void HandleAndroidConfiguration(BuildTarget buildTarget)
304
344
  {
305
- if (!TryGetEnv(VERSION_BUILD_VAR, out string value)) return;
306
- if (int.TryParse(value, out int version))
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
- if (buildTarget == BuildTarget.Android)
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
- Console.WriteLine($":: {VERSION_BUILD_VAR} env var detected but the version value \"{value}\" is not an integer.");
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
- Console.WriteLine($":: {KEYSTORE} not found, skipping setup, using Unity's default keystore");
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
- string keystorePass;
348
- string keystoreAliasPass;
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
- Console.WriteLine($":: using ${KEY_ALIAS_NAME} env var on PlayerSettings");
416
+ LogInfo($"Set key alias name from environment variable");
354
417
  }
355
418
  else
356
419
  {
357
- Console.WriteLine($":: ${KEY_ALIAS_NAME} env var not set, using Project's PlayerSettings");
420
+ LogInfo($"Using project's default key alias name");
358
421
  }
422
+ }
359
423
 
360
- if (!TryGetEnv(KEYSTORE_PASS, out keystorePass))
424
+ private static void ConfigureKeystorePasswords()
425
+ {
426
+ if (!TryGetEnv(KEYSTORE_PASS, out string keystorePass))
361
427
  {
362
- Console.WriteLine($":: ${KEYSTORE_PASS} env var not set, skipping setup, using Unity's default keystore");
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
- Console.WriteLine($":: ${KEY_ALIAS_PASS} env var not set, skipping setup, using Unity's default keystore");
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
- #if UNITY_2023_2_OR_NEWER
441
+
442
+ #if UNITY_2023_2_OR_NEWER
376
443
  PlayerSettings.Android.keystorePass = keystorePass;
377
- #else
444
+ #else
378
445
  PlayerSettings.keystorePass = keystorePass;
379
- #endif
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
- #if UNITY_6000_0_OR_NEWER
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
- #elif UNITY_2021_1_OR_NEWER
458
+ LogInfo("Set debug symbols level to SymbolTable (Unity 6+)");
459
+ #elif UNITY_2021_1_OR_NEWER
389
460
  EditorUserBuildSettings.androidCreateSymbols = AndroidCreateSymbols.Debugging;
390
- #else
391
- // For Unity 2020.3 and earlier, use the legacy boolean property
461
+ LogInfo("Set debug symbols to Debugging (Unity 2021.1+)");
462
+ #else
392
463
  EditorUserBuildSettings.androidCreateSymbolsZip = true;
393
- #endif
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
- string outputFile = Path.Combine(buildPath, "build_info.json");
407
-
408
- var metadata = new BuildMetadata
659
+ try
409
660
  {
410
- appVersion = PlayerSettings.bundleVersion,
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
- string json = JsonUtility.ToJson(metadata, prettyPrint: true);
416
- File.WriteAllText(outputFile, json);
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
- Console.WriteLine($":: Build information saved to {outputFile}");
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
- public class GDKPreProcessBuild: IPreprocessBuildWithReport
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
- // Change Gradle path when running in headless mode (CI Machine)
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
- EditorPrefs.SetBool("GradleUseEmbedded", false);
435
- EditorPrefs.SetString("GradlePath", envGradlePath);
436
- Debug.Log("Update gradle path to: " + envGradlePath);
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
- BuildPipeline.BuildPlayer(GetScenes(), fullBuildPath, info.target, BuildOptions.None);
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 = PBXCapabilityType.StringToPBXCapabilityType(capability.type);
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.id} with entitlements: {entitlementsPath}");
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.id}");
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
@@ -207,7 +207,11 @@ namespace Amanotes.Core.Internal
207
207
  if (!isAdReady)
208
208
  {
209
209
  yield return HandleNotReadyAd();
210
- if (_showState == ShowAdsState.ShowFail) yield break;
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.87";
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
- UnityWebRequest www = new UnityWebRequest(AmaGDK.Config.common.internetCheckUrl);
140
- yield return www.SendWebRequest();
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
- if (www.error != null && www.responseCode != 429) //429 = Too many requests
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 = "http://clients3.google.com/generate_204";
165
+ public string internetCheckUrl = "https://clients3.google.com/generate_204";
156
166
  }
157
167
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "com.amanotes.gdk",
3
- "version": "0.2.87",
3
+ "version": "0.2.89",
4
4
  "displayName": "AmaGDK",
5
5
  "description": "Amanotes Game Development Kit",
6
6
  "unity": "2020.3",