diff --git a/.github/workflows/create-unitypackage.yml b/.github/workflows/create-unitypackage.yml
index 04d5ac1e2..87a2f7a68 100644
--- a/.github/workflows/create-unitypackage.yml
+++ b/.github/workflows/create-unitypackage.yml
@@ -2,9 +2,9 @@ name: Create UnityPackage
on:
workflow_dispatch:
- push:
- branches:
- - workflow-wip
+ # push:
+ # branches:
+ # - workflow-wip-2
env:
UNITY_PROJECT_PATH: .
@@ -16,6 +16,7 @@ defaults:
jobs:
checkout:
runs-on: [self-hosted, Windows, X64, Unity]
+ timeout-minutes: 10
steps:
- id: checkout
uses: actions/checkout@v4
@@ -26,13 +27,14 @@ jobs:
detect-unity-version:
needs: checkout
runs-on: [self-hosted, Windows, X64, Unity]
+ timeout-minutes: 10
outputs:
unity-editor-executable: ${{ steps.detect-unity-version.outputs.unity-editor-executable }}
steps:
- name: Detect Unity Version
id: detect-unity-version
run: |
- PROJECT_VERSION_PATH="${UNITY_PROJECT_PATH}/ProjectSettings/ProjectVersion.txt"
+ PROJECT_VERSION_PATH="${{ env.UNITY_PROJECT_PATH }}/ProjectSettings/ProjectVersion.txt"
UNITY_HUB="C:\Program Files\Unity Hub\Unity Hub.exe"
UNITY_VERSION=`cat ${PROJECT_VERSION_PATH} | sed -n -E "s/^m_EditorVersion:\s+//p" | head -n 1`
@@ -53,11 +55,13 @@ jobs:
--childModules"
fi
+ echo "${UNITY_EDITOR_EXECUTABLE} is installed."
echo "unity-editor-executable=${UNITY_EDITOR_EXECUTABLE}" >> "${GITHUB_OUTPUT}"
run-edit-mode-tests:
needs: detect-unity-version
runs-on: [self-hosted, Windows, X64, Unity]
+ timeout-minutes: 10
steps:
- name: Run EditMode Tests
id: run-edit-mode-tests
@@ -68,14 +72,17 @@ jobs:
"${{ needs.detect-unity-version.outputs.unity-editor-executable }}" \
-batchmode \
-silent-crashes \
- -projectPath "${UNITY_PROJECT_PATH}" \
+ -projectPath "${{ env.UNITY_PROJECT_PATH }}" \
-executeMethod "UniGLTF.TestRunner.RunEditModeTests" \
- -logFile output.log
+ -logFile run-edit-mode-tests.log \
+ -testRunnerNUnitXmlFile run-edit-mode-tests.xml
RET=$?
set -e
echo "Output Log..."
- cat output.log | egrep "^\[\[TestRunnerLog\]\]"
+ cat run-edit-mode-tests.log | egrep "^\[\[TestRunnerLog\]\]"
+
+ # TODO: テスト結果を NUnit3 形式の run-edit-mode-tests.xml から読み込んで表示する
if [ ${RET:-1} -eq 0 ]; then
echo "Test succeeded."
@@ -85,6 +92,29 @@ jobs:
exit 1
fi
+ create-unitypackage:
+ needs: [detect-unity-version, run-edit-mode-tests]
+ runs-on: [self-hosted, Windows, X64, Unity]
+ timeout-minutes: 20
+ steps:
+ - name: Create UnityPackage
+ id: create-unitypackage
+ run: |
+ "${{ needs.detect-unity-version.outputs.unity-editor-executable }}" \
+ -batchmode \
+ -silent-crashes \
+ -projectPath "${{ env.UNITY_PROJECT_PATH }}" \
+ -executeMethod "VRM.DevOnly.PackageExporter.VRMExportUnityPackage.CreateUnityPackageWithBuild" \
+ -logFile create-unitypackage.log
+
+ echo "Success to create UnityPackage."
+
+ - name: Upload UnityPackage
+ uses: actions/upload-artifact@v4
+ with:
+ name: unitypackage
+ path: ${{ env.UNITY_PROJECT_PATH }}/*.unitypackage
+
diff --git a/Assets/UniGLTF/Editor/TestRunner/TestRunner.cs b/Assets/UniGLTF/Editor/TestRunner/TestRunner.cs
index 1885bf5c9..39e371477 100644
--- a/Assets/UniGLTF/Editor/TestRunner/TestRunner.cs
+++ b/Assets/UniGLTF/Editor/TestRunner/TestRunner.cs
@@ -1,7 +1,13 @@
+using System.Globalization;
+using System.IO;
+using System.Text;
+using System.Xml;
+using NUnit.Framework.Interfaces;
using UnityEditor;
using UnityEditor.TestTools.TestRunner.Api;
using UnityEngine;
+using TestStatus = UnityEditor.TestTools.TestRunner.Api.TestStatus;
namespace UniGLTF
{
@@ -21,8 +27,28 @@ namespace UniGLTF
{
private static readonly string LogPrefix = $"[[TestRunnerLog]] ";
private static readonly string ResultLogPrefix = $"[[TestRunnerResult]] ";
+
+ private readonly string _xmlFilePath;
private StackTraceLogType _tmpStackTraceLogType;
+ public TestCallback()
+ {
+ if (!Application.isBatchMode) return;
+
+ var arguments = System.Environment.GetCommandLineArgs();
+ for (var idx = 0; idx < arguments.Length; idx++)
+ {
+ if (arguments[idx] == "-testRunnerNUnitXmlFile" && idx + 1 < arguments.Length)
+ {
+ if (!arguments[idx + 1].StartsWith("-"))
+ {
+ _xmlFilePath = arguments[idx + 1];
+ break;
+ }
+ }
+ }
+ }
+
public void RunStarted(ITestAdaptor testsToRun)
{
_tmpStackTraceLogType = Application.GetStackTraceLogType(LogType.Log);
@@ -33,6 +59,7 @@ namespace UniGLTF
public void RunFinished(ITestResultAdaptor result)
{
+ Debug.Log($"{LogPrefix}Edit Mode Tests Finished.");
Debug.Log($"{LogPrefix}Passed: {result.PassCount}, Skipped: {result.SkipCount}, Failed: {result.FailCount}");
Debug.Log($"{ResultLogPrefix}{result.FailCount}");
@@ -40,6 +67,17 @@ namespace UniGLTF
if (Application.isBatchMode)
{
+ if (!string.IsNullOrEmpty(_xmlFilePath))
+ {
+ Debug.Log($"{LogPrefix}Write NUnit XML to {_xmlFilePath}");
+ var xmlNode = CreateNUnitXmlTree(result);
+
+ using var xmlWriter = new XmlTextWriter(_xmlFilePath, Encoding.UTF8);
+ xmlWriter.Formatting = Formatting.Indented;
+ xmlWriter.WriteStartDocument();
+ xmlNode.WriteTo(xmlWriter);
+ xmlWriter.WriteEndDocument();
+ }
EditorApplication.Exit(result.FailCount > 0 ? 1 : 0);
}
}
@@ -58,6 +96,32 @@ namespace UniGLTF
Debug.Log($"{LogPrefix}{result.StackTrace}");
}
}
+
+ ///
+ /// https://forum.unity.com/threads/generating-nunit-compatible-xml-output.769757/
+ ///
+ private static TNode CreateNUnitXmlTree(ITestResultAdaptor result)
+ {
+ var testRunNode = new TNode("test-run");
+ testRunNode.AddAttribute("id", "2");
+ testRunNode.AddAttribute("testcasecount", (result.PassCount + result.FailCount + result.SkipCount + result.InconclusiveCount).ToString());
+ testRunNode.AddAttribute("result", result.ResultState);
+ testRunNode.AddAttribute("total", (result.PassCount + result.FailCount + result.SkipCount + result.InconclusiveCount).ToString());
+ testRunNode.AddAttribute("passed", result.PassCount.ToString());
+ testRunNode.AddAttribute("failed", result.FailCount.ToString());
+ testRunNode.AddAttribute("inconclusive", result.InconclusiveCount.ToString());
+ testRunNode.AddAttribute("skipped", result.SkipCount.ToString());
+ testRunNode.AddAttribute("asserts", result.AssertCount.ToString());
+ testRunNode.AddAttribute("engine-version", "3.5.0.0");
+ testRunNode.AddAttribute("clr-version", System.Environment.Version.ToString());
+ testRunNode.AddAttribute("start-time", result.StartTime.ToString("u"));
+ testRunNode.AddAttribute("end-time", result.EndTime.ToString("u"));
+ testRunNode.AddAttribute("duration", result.Duration.ToString(CultureInfo.InvariantCulture));
+
+ testRunNode.ChildNodes.Add(result.ToXml());
+
+ return testRunNode;
+ }
}
}
}
\ No newline at end of file
diff --git a/Assets/VRM/Editor/VRMExportUnityPackage.cs b/Assets/VRM/Editor/VRMExportUnityPackage.cs
index 35be05607..1ad482342 100644
--- a/Assets/VRM/Editor/VRMExportUnityPackage.cs
+++ b/Assets/VRM/Editor/VRMExportUnityPackage.cs
@@ -22,6 +22,9 @@ namespace VRM.DevOnly.PackageExporter
}
}
+ ///
+ /// TODO: 本来このクラスは「パッケージとしての UniVRM」のスコープのクラスであるが、「UPM Package VRM」のスコープにコードがあるので変
+ ///
public static class VRMExportUnityPackage
{
static string GetProjectRoot()
@@ -136,21 +139,39 @@ namespace VRM.DevOnly.PackageExporter
///
/// This is call from Jenkins build
///
- /// -quit -batchMode -executeMethod VRM.DevOnly.PackageExporter.VRMExportUnityPackage.CreateUnityPackageWithBuild
+ /// -batchMode -silent-crashes -projectPath . -executeMethod VRM.DevOnly.PackageExporter.VRMExportUnityPackage.CreateUnityPackageWithBuild
///
public static void CreateUnityPackageWithBuild()
{
- var folder = GetProjectRoot();
- if (!Directory.Exists(folder))
+ try
{
- Directory.CreateDirectory(folder);
- }
+ Debug.Log($"[{nameof(VRMExportUnityPackage)}] Start CreateUnityPackageWithBuild...");
+ var folder = GetProjectRoot();
+ if (!Directory.Exists(folder))
+ {
+ Directory.CreateDirectory(folder);
+ }
- if (!BuildTestScene())
- {
- Debug.LogError("Failed to build test scenes");
+ Debug.Log($"[{nameof(VRMExportUnityPackage)}] Try to build test scenes...");
+ BuildTestScene();
+
+ Debug.Log($"[{nameof(VRMExportUnityPackage)}] Create UnityPackages...");
+ CreateUnityPackages(folder);
+
+ Debug.Log($"[{nameof(VRMExportUnityPackage)}] Finish CreateUnityPackageWithBuild");
+ if (Application.isBatchMode)
+ {
+ EditorApplication.Exit(0);
+ }
+ }
+ catch (Exception e)
+ {
+ Debug.LogException(e);
+ if (Application.isBatchMode)
+ {
+ EditorApplication.Exit(1);
+ }
}
- CreateUnityPackages(folder);
}
public class GlobList
@@ -185,7 +206,7 @@ namespace VRM.DevOnly.PackageExporter
}
}
- public static void CreateUnityPackages(string outputDir)
+ private static void CreateUnityPackages(string outputDir)
{
if (!VRMSampleCopy.Validate())
{
@@ -234,7 +255,7 @@ namespace VRM.DevOnly.PackageExporter
}
}
- public static void CreateUnityPackage(
+ private static void CreateUnityPackage(
string outputDir,
PackageInfo package
)
@@ -248,13 +269,18 @@ namespace VRM.DevOnly.PackageExporter
AssetDatabase.ExportPackage(targetFileNames, path, ExportPackageOptions.Default);
}
- public static bool BuildTestScene()
+ private static void BuildTestScene()
{
- var levels = new string[] { "Assets/VRM.Samples/Scenes/VRMRuntimeLoaderSample.unity" };
- return Build(levels);
+ var levels = new string[]
+ {
+ "Assets/UniGLTF_Samples/GltfViewer/GltfViewer.unity",
+ "Assets/VRM_Samples/SimpleViewer/SimpleViewer.unity",
+ "Assets/VRM10_Samples/VRM10Viewer/VRM10Viewer.unity",
+ };
+ Build(levels);
}
- public static bool Build(string[] levels)
+ private static void Build(string[] levels)
{
var buildPath = Path.GetFullPath(Application.dataPath + "/../build/build.exe");
Debug.LogFormat("BuildPath: {0}", buildPath);
@@ -263,12 +289,10 @@ namespace VRM.DevOnly.PackageExporter
BuildTarget.StandaloneWindows,
BuildOptions.None
);
-#if UNITY_2018_1_OR_NEWER
- var isSuccess = build.summary.result == BuildResult.Succeeded;
-#else
- var isSuccess = !string.IsNullOrEmpty(build);
-#endif
- return isSuccess;
+ if (build.summary.result != BuildResult.Succeeded)
+ {
+ throw new Exception("Failed to build scenes");
+ }
}
}
}