Skip to content

Commit edcf2df

Browse files
authored
Enable the exporting of unitypackage files from a list of curated scenes. (#5052)
1 parent d37a2af commit edcf2df

File tree

5 files changed

+165
-0
lines changed

5 files changed

+165
-0
lines changed
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
sample_export:
2+
name: Samples Export 2021.2
3+
agent:
4+
type: Unity::VM
5+
image: package-ci/ubuntu:stable
6+
flavor: b1.large
7+
variables:
8+
UNITY_VERSION: 2021.2
9+
commands:
10+
- python3 -m pip install pyyaml --index-url https://artifactory.prd.it.unity3d.com/artifactory/api/pypi/pypi/simple
11+
- python3 -m pip install unity-downloader-cli --index-url https://artifactory.prd.it.unity3d.com/artifactory/api/pypi/pypi/simple --upgrade
12+
- unity-downloader-cli -u 2021.2 -c editor --wait --fast
13+
- python3 -u -m ml-agents.tests.yamato.sample_curation --scene "Assets/ML-Agents/Examples/Basic/Scenes/Basic.unity" "Assets/ML-Agents/Examples/Match3/Scenes/Match3.unity" "Assets/ML-Agents/Examples/WallJump/Scenes/WallJump.unity" "Assets/ML-Agents/TestScenes/TestCompressedGrid/TestGridCompressed.unity" "Assets/ML-Agents/TestScenes/TestCompressedTexture/TestTextureCompressed.unity"
14+
triggers:
15+
cancel_old_ci: true
16+
artifacts:
17+
logs:
18+
paths:
19+
- "artifacts/sample_export.txt"
20+
samples:
21+
paths:
22+
- "artifacts/Samples/**"
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.IO;
4+
using System.Linq;
5+
using UnityEditor;
6+
using UnityEngine;
7+
using UnityEngine.iOS;
8+
9+
namespace Unity.MLAgents
10+
{
11+
public class SampleExporter
12+
{
13+
const string k_SceneFlag = "--mlagents-scene-path";
14+
15+
public static void ExportCuratedSamples()
16+
{
17+
var oldBurst = EditorPrefs.GetBool("BurstCompilation");
18+
EditorPrefs.SetBool("BurstCompilation", false);
19+
try
20+
{
21+
var args = Environment.GetCommandLineArgs();
22+
var scenes = new List<string>();
23+
for (var i = 0; i < args.Length - 1; i++)
24+
{
25+
if (args[i] == k_SceneFlag)
26+
{
27+
scenes.Add(args[i + 1]);
28+
Debug.Log($"Exporting Scene {scenes.Last()}");
29+
}
30+
}
31+
32+
foreach (var scene in scenes)
33+
{
34+
var assets = new List<string> { scene };
35+
var exampleFolderToAdd = Directory.GetParent(Directory.GetParent(scene).FullName).FullName;
36+
Debug.Log($"Parent of Scene: {exampleFolderToAdd}");
37+
if (Directory.Exists(Path.Combine(exampleFolderToAdd, "Scripts")))
38+
{
39+
exampleFolderToAdd = Path.Combine(exampleFolderToAdd, "Scripts");
40+
}
41+
42+
exampleFolderToAdd = exampleFolderToAdd.Substring(exampleFolderToAdd.IndexOf("Assets"));
43+
foreach (var guid in AssetDatabase.FindAssets("t:Script", new[] { exampleFolderToAdd }))
44+
{
45+
var path = AssetDatabase.GUIDToAssetPath(guid);
46+
assets.Add(path);
47+
Debug.Log($"Adding Asset: {path}");
48+
}
49+
AssetDatabase.ExportPackage(assets.ToArray(), Path.GetFileNameWithoutExtension(scene) + ".unitypackage", ExportPackageOptions.IncludeDependencies | ExportPackageOptions.Recurse);
50+
}
51+
}
52+
catch (Exception e)
53+
{
54+
Debug.Log(e);
55+
EditorApplication.Exit(1);
56+
}
57+
EditorPrefs.SetBool("BurstCompilation", oldBurst);
58+
EditorApplication.Exit(0);
59+
}
60+
}
61+
}

Project/Assets/ML-Agents/Editor/Tests/SampleExporter.cs.meta

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import sys
2+
import argparse
3+
4+
from .yamato_utils import get_base_path, create_samples
5+
6+
7+
def main(scenes):
8+
base_path = get_base_path()
9+
print(f"Running in base path {base_path}")
10+
11+
returncode = create_samples(
12+
scenes,
13+
base_path,
14+
log_output_path=None, # Log to stdout so we get timestamps on the logs
15+
)
16+
17+
if returncode == 0:
18+
print("Test run SUCCEEDED!")
19+
else:
20+
print("Test run FAILED!")
21+
22+
sys.exit(returncode)
23+
24+
25+
if __name__ == "__main__":
26+
parser = argparse.ArgumentParser()
27+
parser.add_argument("--scene", nargs="+", default=None, required=True)
28+
args = parser.parse_args()
29+
main(args.scene)

ml-agents/tests/yamato/yamato_utils.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import glob
12
import os
23
import shutil
34
import subprocess
@@ -229,3 +230,52 @@ def override_legacy_config_file(python_version, src_path, dest_path, **kwargs):
229230

230231
with open(dest_path, "w") as f:
231232
yaml.dump(configs, f)
233+
234+
235+
def create_samples(
236+
scenes: List[str],
237+
base_path: str,
238+
log_output_path: Optional[str] = f"{get_base_output_path()}/sample_export.txt",
239+
) -> int:
240+
unity_exe = get_unity_executable_path()
241+
test_args = [
242+
unity_exe,
243+
"-projectPath",
244+
f"{base_path}/Project",
245+
"-batchmode",
246+
"-executeMethod",
247+
"Unity.MLAgents.SampleExporter.ExportCuratedSamples",
248+
]
249+
250+
if log_output_path:
251+
os.makedirs(os.path.dirname(log_output_path), exist_ok=True)
252+
subprocess.run(["touch", log_output_path])
253+
test_args += ["-logfile", log_output_path]
254+
else:
255+
# Log to stdout
256+
test_args += ["-logfile", "-"]
257+
258+
os.makedirs(os.path.join(get_base_output_path(), "Samples"), exist_ok=True)
259+
260+
for scene in scenes:
261+
test_args += ["--mlagents-scene-path", scene]
262+
263+
timeout = 5 * 60 # 5 minutes for now
264+
res: subprocess.CompletedProcess = subprocess.run(test_args, timeout=timeout)
265+
266+
if res.returncode == 0:
267+
for file in glob.glob(os.path.join(base_path, "Project/*.unitypackage")):
268+
print(
269+
f"moving {file} to {os.path.join(get_base_output_path(), 'Samples', os.path.basename(file))}"
270+
)
271+
shutil.move(
272+
file,
273+
os.path.join(get_base_output_path(), "Samples", os.path.basename(file)),
274+
)
275+
276+
# Print if we fail or want verbosity.
277+
if res.returncode != 0:
278+
if log_output_path:
279+
subprocess.run(["cat", log_output_path])
280+
281+
return res.returncode

0 commit comments

Comments
 (0)