diff --git a/.github/UnityPack.csx b/.github/UnityPack.csx index d7cd1a680..603c9fd61 100644 --- a/.github/UnityPack.csx +++ b/.github/UnityPack.csx @@ -1,10 +1,13 @@ /* - MIT License: The code in this script is mostly from https://github.com/MirageNet/unity-packer + MIT License: The code in this script is mostly from https://github.com/MirageNet/unity-packer + which is the source for the nuget unity-packer from https://www.nuget.org/packages/unity-packer Specifically the Pack method of the Packer class, related methods, plus the Utils.GreateGUID and Archive.AddFilesRecursive methods, adjusted for use in a .csx script called from a GitHub Action. + Environment Variables are used instead of command line arguments to pass the output file name, assets, and dependencies. + The AddDependenciesFile method is added to create a packagemanagermanifest asset file with - Newtonsoft.Json Unity Test Framework dependencies. + Newtonsoft.Json and Unity Test Framework dependencies. */ #r "nuget: SharpZipLib, 1.4.2" @@ -13,57 +16,90 @@ using System; using System.Collections.Generic; using System.IO; +using System.Linq; using System.Security.Cryptography; +using System.Text.Json; using ICSharpCode.SharpZipLib.GZip; using ICSharpCode.SharpZipLib.Tar; using YamlDotNet.RepresentationModel; -var args = Environment.GetCommandLineArgs(); +static StringSplitOptions stringSplitOptions = StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries; -for (int i = 0; i < args.Length; i++) - Console.WriteLine($"UnityPack: args[{i}]: {args[i]}"); +enum CmdLineArgs : int { DotNetScriptDll, ScriptFullName, Version } +static string[] args = Environment.GetCommandLineArgs(); -if (args.Length < 6) +//for (int i = 0; i < args.Length; i++) +// Console.WriteLine($"UnityPack: args[{i}]: {args[i]}"); + +// Output from GitHub Action logging for reference +// UnityPack: args[0]: C:\Users\runneradmin\.dotnet\tools\.store\dotnet-script\1.5.0\dotnet-script\1.5.0\tools\net8.0\any\dotnet-script.dll +// UnityPack: args[1]: .github/UnityPack.csx +// UnityPack: args[2]: 1.1.0 + +if (args.Length < 3) { - Console.WriteLine("Usage: UnityPack.csx [ ...]"); + Console.WriteLine("Usage: UnityPack.csx "); return; } -string outputFile = args[2]; -string versionArg = args[3]; +// Get version argument +static string version = args[(int)CmdLineArgs.Version]; + +// Get output file name +static string outputFile = Environment.GetEnvironmentVariable("UNITYPACK_OUTPUT") ?? "output.unitypackage"; if (!Path.IsPathRooted(outputFile)) outputFile = Path.GetFullPath(outputFile); -Console.WriteLine($"UnityPack: outputFile: {outputFile}"); +Console.WriteLine($"UnityPack: outputFile:{outputFile} version:{version}"); -var fileMap = new Dictionary(); +// Create assets dictionary +static Dictionary assets = new Dictionary(); +var assetVars = Environment.GetEnvironmentVariables() + .Cast() + .Where(e => e.Key.ToString().StartsWith("UNITYPACK_ASSET")) + .ToDictionary(e => e.Key.ToString(), e => e.Value.ToString()); -for (int i = 4; i < args.Length; i += 2) +foreach (var kvp in assetVars) { - string fromPath = args[i]; - - if (!Path.IsPathRooted(args[i])) - fromPath = Path.GetFullPath(fromPath); - - string toPath = args[i + 1]; - - fileMap.Add(fromPath, toPath); + string[] parts = kvp.Value.Split(' ', stringSplitOptions); + string source = parts[0]; + string destination = parts.Length > 1 ? parts[1] : ""; + assets[source] = destination; } -Pack(fileMap, outputFile, versionArg); +// Create dependencies dictionary +static Dictionary dependencies = new Dictionary(); +var envVars = Environment.GetEnvironmentVariables() + .Cast() + .Where(e => e.Key.ToString().StartsWith("UNITYPACK_DEPENDENCY")) + .ToDictionary(e => e.Key.ToString(), e => e.Value.ToString()); -static void Pack(IDictionary files, string outputFile, string version) +foreach (var kvp in envVars) { - //string randomFile = Path.GetRandomFileName(); + string[] parts = kvp.Value.Split(' ', stringSplitOptions); + string name = parts[0]; + string value = parts.Length > 1 ? parts[1] : ""; + dependencies[name] = value; +} +// Create testables list +static List testables = Environment.GetEnvironmentVariable("UNITYPACK_TESTABLES") + ?.Split(' ', stringSplitOptions) + .Where(t => !string.IsNullOrWhiteSpace(t)) + .ToList() ?? new List(); + +Pack(); + +static void Pack() +{ string tempPath = Path.Combine(Path.GetTempPath(), $"Mirror-{version}"); Directory.CreateDirectory(tempPath); Console.WriteLine($"UnityPack: tempPath: {tempPath}"); - AddAssets(files, tempPath); + AddAssets(tempPath); - AddDependeciesFile(tempPath); + AddDependenciesFile(tempPath); if (File.Exists(outputFile)) File.Delete(outputFile); @@ -74,9 +110,9 @@ static void Pack(IDictionary files, string outputFile, string ve Directory.Delete(tempPath, true); } -static void AddAssets(IDictionary files, string tempPath) +static void AddAssets(string tempPath) { - foreach (KeyValuePair fileEntry in files) + foreach (KeyValuePair fileEntry in assets) { if (File.Exists(fileEntry.Key)) AddAsset(tempPath, fileEntry.Key, fileEntry.Value); @@ -156,29 +192,27 @@ static YamlDocument GenerateMeta(string fromFile, string toFile) { // this is a folder return new YamlDocument(new YamlMappingNode - { - {"guid", guid}, - {"fileFormatVersion", "2"}, - {"folderAsset", "yes"} - }); + { + {"guid", guid}, + {"fileFormatVersion", "2"}, + {"folderAsset", "yes"} + }); } else { // this is a file return new YamlDocument(new YamlMappingNode - { - {"guid", guid}, - {"fileFormatVersion", "2"} - }); + { + {"guid", guid}, + {"fileFormatVersion", "2"} + }); } } static string GetGuid(YamlDocument meta) { var mapping = (YamlMappingNode)meta.RootNode; - var key = new YamlScalarNode("guid"); - var value = (YamlScalarNode)mapping[key]; return value.Value; } @@ -193,9 +227,7 @@ static string CreateGuid(string input) StringBuilder stringBuilder = new StringBuilder(); foreach (byte b in hashBytes) - { stringBuilder.Append(b.ToString("X2")); - } return stringBuilder.ToString(); } @@ -214,9 +246,18 @@ static void SaveMeta(string metaPath, YamlDocument meta) metaFileStream.SetLength(metaFile.Length - 3 - Environment.NewLine.Length); } -static void AddDependeciesFile(string tempPath) +static void AddDependenciesFile(string tempPath) { - string depenciesJson = "{\"dependencies\":{\"com.unity.nuget.newtonsoft-json\":\"3.0.0\"},\"testables\":[\"com.unity.test-framework.performance\"]}"; + //string depenciesJson = "{\"dependencies\":{\"com.unity.nuget.newtonsoft-json\":\"3.0.0\"},\"testables\":[\"com.unity.test-framework.performance\"]}"; + + // Serialize the JSON object + var jsonObject = new + { + dependencies, + testables + }; + + string depenciesJson = JsonSerializer.Serialize(jsonObject, new JsonSerializerOptions { WriteIndented = true }); string depenciesPath = Path.Combine(tempPath, "packagemanagermanifest"); Directory.CreateDirectory(depenciesPath); Console.WriteLine($"UnityPack: Creating dependency file at {Path.Combine(depenciesPath, "asset")}"); diff --git a/.github/workflows/RunUnityTests.yml b/.github/workflows/RunUnityTests.yml index c8cb08b8c..5c1bc5470 100644 --- a/.github/workflows/RunUnityTests.yml +++ b/.github/workflows/RunUnityTests.yml @@ -16,7 +16,7 @@ jobs: - 2021.3.38f1 - 2022.3.33f1 - 2023.2.20f1 - - 6000.0.5f1 + - 6000.0.7f1 steps: - name: Checkout repository diff --git a/.github/workflows/Semantic.yml b/.github/workflows/Semantic.yml index 830b494dc..b6028278b 100644 --- a/.github/workflows/Semantic.yml +++ b/.github/workflows/Semantic.yml @@ -43,3 +43,13 @@ jobs: --debug env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + UNITYPACK_OUTPUT: "Mirror.unitypackage" + # source and destination separated by space + # add more assets as separate env vars using the naming pattern + UNITYPACK_ASSET1: "Assets/Mirror Assets/Mirror" + UNITYPACK_ASSET2: "LICENSE Assets/Mirror/LICENSE" + # name and version separated by space + # add more dependencies as separate env vars using the naming pattern + UNITYPACK_DEPENDENCY1: "com.unity.nuget.newtonsoft-json 3.0.0" + # package names separated by space (only one for now) + UNITYPACK_TESTABLES: "com.unity.test-framework.performance" diff --git a/.releaserc.yml b/.releaserc.yml index eb57c0daf..3a05fab76 100644 --- a/.releaserc.yml +++ b/.releaserc.yml @@ -1,3 +1,6 @@ +branches: + - name: master + verifyConditions: - "@semantic-release/github" @@ -59,7 +62,7 @@ plugins: # Create Unity package with Mirror, ScriptTemplates, and LICENSE - - '@semantic-release/exec' - - prepareCmd: "dotnet script .github/UnityPack.csx Mirror.unitypackage ${nextRelease.version} Assets/Mirror Assets/Mirror LICENSE Assets/Mirror/LICENSE" + - prepareCmd: "dotnet script .github/UnityPack.csx ${nextRelease.version}" # Create a new release on GitHub - - '@semantic-release/github'