Skip to content

delete a bunch of code, use C# to setup samples in pack job. #5077

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Mar 11, 2021
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions .yamato/com.unity.ml-agents-pack.yml
Original file line number Diff line number Diff line change
@@ -5,8 +5,12 @@ pack:
image: package-ci/ubuntu:stable
flavor: b1.small
commands:
- npm install upm-ci-utils@stable -g --registry https://artifactory.prd.cds.internal.unity3d.com/artifactory/api/npm/upm-npm
- upm-ci project pack --project-path Project
- |
python3 -m pip install unity-downloader-cli --index-url https://artifactory.prd.it.unity3d.com/artifactory/api/pypi/pypi/simple --upgrade
unity-downloader-cli -u 2018.4 -c editor --wait --fast
./.Editor/Unity -projectPath Project -batchMode -executeMethod Unity.MLAgents.SampleExporter.ExportCuratedSamples -logFile -
npm install upm-ci-utils@stable -g --registry https://artifactory.prd.cds.internal.unity3d.com/artifactory/api/npm/upm-npm
upm-ci project pack --project-path Project
artifacts:
packages:
paths:
22 changes: 0 additions & 22 deletions .yamato/ml-agents-sample-export.yml

This file was deleted.

111 changes: 86 additions & 25 deletions Project/Assets/ML-Agents/Editor/Tests/SampleExporter.cs
Original file line number Diff line number Diff line change
@@ -1,52 +1,113 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Newtonsoft.Json;
using UnityEditor;
using UnityEngine;
using UnityEngine.iOS;

namespace Unity.MLAgents
{
public class SampleExporter
{
const string k_SceneFlag = "--mlagents-scene-path";
const string k_MLAgentsSampleFile = "mlagents-sample.json";
const string k_PackageSampleFile = ".sample.json";
const string k_MLAgentsDir = "ML-Agents";
const string k_MLAgentsExamplesDir = "Examples";
const string k_MLAgentsPackageName = "com.unity.ml-agents";
const string k_MLAgentsSamplesDirName = "Samples";
const string k_MLAgentsScriptsDirName = "Scripts";

struct MLAgentsSampleJson
{
public string displayName;
public string description;
public List<string> scenes;
}

struct PackageSampleJson
{
public string displayName;
public string description;
}

public static void ExportCuratedSamples()
{
var oldBurst = EditorPrefs.GetBool("BurstCompilation");
EditorPrefs.SetBool("BurstCompilation", false);
try
{
var args = Environment.GetCommandLineArgs();
var scenes = new List<string>();
for (var i = 0; i < args.Length - 1; i++)
// Path to Project/Assets
var assetsDir = Application.dataPath;
var repoRoot = Directory.GetParent(Directory.GetParent(assetsDir).FullName).FullName;

// Top level of where to store the samples
var samplesDir = Path.Combine(
repoRoot,
k_MLAgentsPackageName,
k_MLAgentsSamplesDirName);

if (!Directory.Exists(samplesDir))
{
if (args[i] == k_SceneFlag)
{
scenes.Add(args[i + 1]);
Debug.Log($"Exporting Scene {scenes.Last()}");
}
Directory.CreateDirectory(samplesDir);
}

foreach (var scene in scenes)
// Path to the examples dir in the project
var examplesDir = Path.Combine(Application.dataPath, k_MLAgentsDir, k_MLAgentsExamplesDir);
foreach (var exampleDirectory in Directory.GetDirectories(examplesDir))
{
var assets = new List<string> { scene };
var exampleFolderToAdd = Directory.GetParent(Directory.GetParent(scene).FullName).FullName;
Debug.Log($"Parent of Scene: {exampleFolderToAdd}");
if (Directory.Exists(Path.Combine(exampleFolderToAdd, "Scripts")))
var mlAgentsSamplePath = Path.Combine(exampleDirectory, k_MLAgentsSampleFile);
if (File.Exists(mlAgentsSamplePath))
{
exampleFolderToAdd = Path.Combine(exampleFolderToAdd, "Scripts");
}
var sampleJson = JsonConvert.DeserializeObject<MLAgentsSampleJson>(File.ReadAllText(mlAgentsSamplePath));
Debug.Log(JsonConvert.SerializeObject(sampleJson));
foreach (var scene in sampleJson.scenes)
{
var scenePath = Path.Combine(exampleDirectory, scene);
if (File.Exists(scenePath))
{
// Create a Sample Directory
var currentSampleDir = Directory.CreateDirectory(Path.Combine(samplesDir,
Path.GetFileNameWithoutExtension(scenePath)));

exampleFolderToAdd = exampleFolderToAdd.Substring(exampleFolderToAdd.IndexOf("Assets"));
foreach (var guid in AssetDatabase.FindAssets("t:Script", new[] { exampleFolderToAdd }))
{
var path = AssetDatabase.GUIDToAssetPath(guid);
assets.Add(path);
Debug.Log($"Adding Asset: {path}");

var scriptsPath = Path.Combine(exampleDirectory, k_MLAgentsScriptsDirName);
Debug.Log($"Scene Path: {scenePath}");
var assets = new List<string> { scenePath.Substring(scenePath.IndexOf("Assets")) };
if (!Directory.Exists(Path.Combine(scriptsPath)))
{
scriptsPath = exampleDirectory;
}

scriptsPath = scriptsPath.Substring(scriptsPath.IndexOf("Assets"));
foreach (var guid in AssetDatabase.FindAssets("t:Script", new[] { scriptsPath }))
{
var path = AssetDatabase.GUIDToAssetPath(guid);
assets.Add(path);
Debug.Log($"Adding Asset: {path}");
}

var packageFilePath = Path.GetFileNameWithoutExtension(scenePath) + ".unitypackage";
AssetDatabase.ExportPackage(assets.ToArray(),
Path.Combine(Application.dataPath, packageFilePath),
ExportPackageOptions.IncludeDependencies | ExportPackageOptions.Recurse);

// Move the .unitypackage into the samples folder.
var packageFileFullPath = Path.Combine(Application.dataPath, packageFilePath);

var packageInSamplePath = Path.Combine(currentSampleDir.FullName, packageFilePath);
Debug.Log($"Moving {packageFileFullPath} to {packageInSamplePath}");
File.Move(packageFileFullPath, packageInSamplePath);

// write the .sample.json file to the sample directory
File.WriteAllText(Path.Combine(currentSampleDir.FullName, k_PackageSampleFile),
JsonConvert.SerializeObject(new PackageSampleJson
{
description = sampleJson.description,
displayName = sampleJson.displayName
}));
}
}
}
AssetDatabase.ExportPackage(assets.ToArray(), Path.GetFileNameWithoutExtension(scene) + ".unitypackage", ExportPackageOptions.IncludeDependencies | ExportPackageOptions.Recurse);
}
}
catch (Exception e)
7 changes: 7 additions & 0 deletions Project/Assets/ML-Agents/Examples/3DBall/mlagents-sample.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"displayName": "3D Ball",
"description": "The 3D Ball sample is a simple environment that is a great for jumping into Ml-Agents to see how things work.",
"scenes": [
"Scenes/3DBall.unity"
]
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion Project/Packages/manifest.json
Original file line number Diff line number Diff line change
@@ -37,7 +37,8 @@
"com.unity.modules.video": "1.0.0",
"com.unity.modules.vr": "1.0.0",
"com.unity.modules.wind": "1.0.0",
"com.unity.modules.xr": "1.0.0"
"com.unity.modules.xr": "1.0.0",
"com.unity.nuget.newtonsoft-json": "2.0.0"
},
"testables": [
"com.unity.ml-agents",
1 change: 1 addition & 0 deletions Project/Project.sln.DotSettings
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=ML/@EntryIndexedValue">ML</s:String>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Dont/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
4 changes: 3 additions & 1 deletion com.unity.ml-agents/.gitignore
Original file line number Diff line number Diff line change
@@ -21,9 +21,11 @@ build.bat.meta
/Assets/Plugins*
/Assets/Demonstrations*
/csharp_timers.json
/Samples/
/Samples.meta

# Visual Studio 2015 cache directory
/.vs/

*.api
*.api.meta
*.api.meta
29 changes: 0 additions & 29 deletions ml-agents/tests/yamato/sample_curation.py

This file was deleted.

50 changes: 0 additions & 50 deletions ml-agents/tests/yamato/yamato_utils.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import glob
import os
import shutil
import subprocess
@@ -230,52 +229,3 @@ def override_legacy_config_file(python_version, src_path, dest_path, **kwargs):

with open(dest_path, "w") as f:
yaml.dump(configs, f)


def create_samples(
scenes: List[str],
base_path: str,
log_output_path: Optional[str] = f"{get_base_output_path()}/sample_export.txt",
) -> int:
unity_exe = get_unity_executable_path()
test_args = [
unity_exe,
"-projectPath",
f"{base_path}/Project",
"-batchmode",
"-executeMethod",
"Unity.MLAgents.SampleExporter.ExportCuratedSamples",
]

if log_output_path:
os.makedirs(os.path.dirname(log_output_path), exist_ok=True)
subprocess.run(["touch", log_output_path])
test_args += ["-logfile", log_output_path]
else:
# Log to stdout
test_args += ["-logfile", "-"]

os.makedirs(os.path.join(get_base_output_path(), "Samples"), exist_ok=True)

for scene in scenes:
test_args += ["--mlagents-scene-path", scene]

timeout = 5 * 60 # 5 minutes for now
res: subprocess.CompletedProcess = subprocess.run(test_args, timeout=timeout)

if res.returncode == 0:
for file in glob.glob(os.path.join(base_path, "Project/*.unitypackage")):
print(
f"moving {file} to {os.path.join(get_base_output_path(), 'Samples', os.path.basename(file))}"
)
shutil.move(
file,
os.path.join(get_base_output_path(), "Samples", os.path.basename(file)),
)

# Print if we fail or want verbosity.
if res.returncode != 0:
if log_output_path:
subprocess.run(["cat", log_output_path])

return res.returncode