From be10037b59f74134aa647bf90de824a8222a3871 Mon Sep 17 00:00:00 2001 From: Aaron Robinson Date: Tue, 28 Feb 2023 21:00:28 -0600 Subject: [PATCH 01/34] Fix modpack installs --- ThunderstoreCLI/Commands/InstallCommand.cs | 33 +++++----- ThunderstoreCLI/Commands/UninstallCommand.cs | 2 +- ThunderstoreCLI/Game/ModProfile.cs | 4 +- ThunderstoreCLI/Models/PackageListingV1.cs | 7 ++ ThunderstoreCLI/Utils/ModDependencyTree.cs | 67 +++++++++----------- 5 files changed, 57 insertions(+), 56 deletions(-) diff --git a/ThunderstoreCLI/Commands/InstallCommand.cs b/ThunderstoreCLI/Commands/InstallCommand.cs index 7d688d2..1d7bb28 100644 --- a/ThunderstoreCLI/Commands/InstallCommand.cs +++ b/ThunderstoreCLI/Commands/InstallCommand.cs @@ -37,7 +37,7 @@ public static async Task Run(Config config) Match packageMatch = FullPackageNameRegex.Match(package); if (File.Exists(package)) { - returnCode = await InstallZip(config, http, def, profile, package, null, null); + returnCode = await InstallZip(config, http, def, profile, package, null, null, false); } else if (packageMatch.Success) { @@ -77,11 +77,11 @@ private static async Task InstallFromRepository(Config config, HttpClient h versionData ??= packageData!.LatestVersion!; var zipPath = await config.Cache.GetFileOrDownload($"{versionData.FullName}.zip", versionData.DownloadUrl!); - var returnCode = await InstallZip(config, http, game, profile, zipPath, versionData.Namespace!, packageData!.CommunityListings!.First().Community); + var returnCode = await InstallZip(config, http, game, profile, zipPath, versionData.Namespace!, packageData!.CommunityListings!.First().Community, packageData.CommunityListings!.First().Categories!.Contains("Modpacks")); return returnCode; } - private static async Task InstallZip(Config config, HttpClient http, GameDefinition game, ModProfile profile, string zipPath, string? backupNamespace, string? sourceCommunity) + private static async Task InstallZip(Config config, HttpClient http, GameDefinition game, ModProfile profile, string zipPath, string? backupNamespace, string? sourceCommunity, bool isModpack) { using var zip = ZipFile.OpenRead(zipPath); var manifestFile = zip.GetEntry("manifest.json") ?? throw new CommandFatalException("Package zip needs a manifest.json!"); @@ -90,15 +90,15 @@ private static async Task InstallZip(Config config, HttpClient http, GameDe manifest.Namespace ??= backupNamespace; - var dependenciesToInstall = ModDependencyTree.Generate(config, http, manifest, sourceCommunity) - .Where(dependency => !profile.InstalledModVersions.ContainsKey(dependency.Fullname!)) + var dependenciesToInstall = ModDependencyTree.Generate(config, http, manifest, sourceCommunity, isModpack) + .Where(dependency => !profile.InstalledModVersions.ContainsKey(dependency.FullNameParts["fullname"].Value)) .ToArray(); if (dependenciesToInstall.Length > 0) { var totalSize = dependenciesToInstall - .Where(d => !config.Cache.ContainsFile($"{d.Fullname}-{d.Versions![0].VersionNumber}.zip")) - .Select(d => d.Versions![0].FileSize) + .Where(d => !config.Cache.ContainsFile($"{d.FullName}-{d.VersionNumber}.zip")) + .Select(d => d.FileSize) .Sum(); if (totalSize != 0) { @@ -106,35 +106,32 @@ private static async Task InstallZip(Config config, HttpClient http, GameDe } var downloadTasks = dependenciesToInstall.Select(mod => - { - var version = mod.Versions![0]; - return config.Cache.GetFileOrDownload($"{mod.Fullname}-{version.VersionNumber}.zip", version.DownloadUrl!); - }).ToArray(); + config.Cache.GetFileOrDownload($"{mod.FullName}-{mod.VersionNumber}.zip", mod.DownloadUrl!) + ).ToArray(); var spinner = new ProgressSpinner("dependencies downloaded", downloadTasks); await spinner.Spin(); - foreach (var (tempZipPath, package) in downloadTasks.Select(x => x.Result).Zip(dependenciesToInstall)) + foreach (var (tempZipPath, pVersion) in downloadTasks.Select(x => x.Result).Zip(dependenciesToInstall)) { - var packageVersion = package.Versions![0]; - int returnCode = RunInstaller(game, profile, tempZipPath, package.Owner); + int returnCode = RunInstaller(game, profile, tempZipPath, pVersion.FullNameParts["namespace"].Value); if (returnCode == 0) { - Write.Success($"Installed mod: {package.Fullname}-{packageVersion.VersionNumber}"); + Write.Success($"Installed mod: {pVersion.FullName}"); } else { - Write.Error($"Failed to install mod: {package.Fullname}-{packageVersion.VersionNumber}"); + Write.Error($"Failed to install mod: {pVersion.FullName}"); return returnCode; } - profile.InstalledModVersions[package.Fullname!] = new PackageManifestV1(package, packageVersion); + profile.InstalledModVersions[pVersion.FullNameParts["fullname"].Value] = new InstalledModVersion(pVersion.FullNameParts["fullname"].Value, pVersion.VersionNumber!, pVersion.Dependencies!); } } var exitCode = RunInstaller(game, profile, zipPath, backupNamespace); if (exitCode == 0) { - profile.InstalledModVersions[manifest.FullName] = manifest; + profile.InstalledModVersions[manifest.FullName] = new InstalledModVersion(manifest.FullName, manifest.VersionNumber!, manifest.Dependencies!); Write.Success($"Installed mod: {manifest.FullName}-{manifest.VersionNumber}"); } else diff --git a/ThunderstoreCLI/Commands/UninstallCommand.cs b/ThunderstoreCLI/Commands/UninstallCommand.cs index ed57c79..c510fc5 100644 --- a/ThunderstoreCLI/Commands/UninstallCommand.cs +++ b/ThunderstoreCLI/Commands/UninstallCommand.cs @@ -35,7 +35,7 @@ public static int Run(Config config) var searchWithDash = search + '-'; foreach (var mod in profile.InstalledModVersions.Values) { - if (mod.Dependencies!.Any(s => s.StartsWith(searchWithDash))) + if (mod.Dependencies.Any(s => s.StartsWith(searchWithDash))) { if (modsToRemove.Add(mod.FullName)) { diff --git a/ThunderstoreCLI/Game/ModProfile.cs b/ThunderstoreCLI/Game/ModProfile.cs index 89f5869..e842c10 100644 --- a/ThunderstoreCLI/Game/ModProfile.cs +++ b/ThunderstoreCLI/Game/ModProfile.cs @@ -4,11 +4,13 @@ namespace ThunderstoreCLI.Game; +public record InstalledModVersion(string FullName, string VersionNumber, string[] Dependencies); + public class ModProfile : BaseJson { public string Name { get; set; } public string ProfileDirectory { get; set; } - public Dictionary InstalledModVersions { get; } = new(); + public Dictionary InstalledModVersions { get; } = new(); #pragma warning disable CS8618 private ModProfile() { } diff --git a/ThunderstoreCLI/Models/PackageListingV1.cs b/ThunderstoreCLI/Models/PackageListingV1.cs index 4a6743d..0f07ac4 100644 --- a/ThunderstoreCLI/Models/PackageListingV1.cs +++ b/ThunderstoreCLI/Models/PackageListingV1.cs @@ -1,4 +1,6 @@ +using System.Text.RegularExpressions; using Newtonsoft.Json; +using ThunderstoreCLI.Commands; namespace ThunderstoreCLI.Models; @@ -104,6 +106,11 @@ public class PackageVersionV1 [JsonProperty("file_size")] public int FileSize { get; set; } + [JsonIgnore] + private GroupCollection? _fullNameParts; + [JsonIgnore] + public GroupCollection FullNameParts => _fullNameParts ??= InstallCommand.FullPackageNameRegex.Match(FullName!).Groups; + public PackageVersionV1() { } public PackageVersionV1(PackageVersionData version) diff --git a/ThunderstoreCLI/Utils/ModDependencyTree.cs b/ThunderstoreCLI/Utils/ModDependencyTree.cs index 8d421f8..3ecde32 100644 --- a/ThunderstoreCLI/Utils/ModDependencyTree.cs +++ b/ThunderstoreCLI/Utils/ModDependencyTree.cs @@ -8,7 +8,7 @@ namespace ThunderstoreCLI.Utils; public static class ModDependencyTree { - public static IEnumerable Generate(Config config, HttpClient http, PackageManifestV1 root, string? sourceCommunity) + public static IEnumerable Generate(Config config, HttpClient http, PackageManifestV1 root, string? sourceCommunity, bool useExactVersions) { List? packages = null; @@ -32,67 +32,62 @@ public static IEnumerable Generate(Config config, HttpClient h packages = PackageListingV1.DeserializeList(packagesJson)!; } - HashSet visited = new(); - foreach (var originalDep in root.Dependencies!) + Queue toVisit = new(); + Dictionary dict = new(); + int currentId = 0; + foreach (var dep in root.Dependencies!) { - var match = InstallCommand.FullPackageNameRegex.Match(originalDep); + toVisit.Enqueue(dep); + } + while (toVisit.TryDequeue(out var packageString)) + { + var match = InstallCommand.FullPackageNameRegex.Match(packageString); var fullname = match.Groups["fullname"].Value; - var depPackage = packages?.Find(p => p.Fullname == fullname) ?? AttemptResolveExperimental(config, http, match, root.FullName); - if (depPackage == null) + if (dict.TryGetValue(fullname, out var current)) { + dict[fullname] = (currentId++, current.version); continue; } - foreach (var dependency in GenerateInner(packages, config, http, depPackage, p => visited.Contains(p.Fullname!))) + var package = packages?.Find(p => p.Fullname == fullname) ?? AttemptResolveExperimental(config, http, match); + if (package is null) + continue; + PackageVersionV1? version; + if (useExactVersions) { - // can happen on cycles, oh well - if (visited.Contains(dependency.Fullname!)) + string requiredVersion = match.Groups["version"].Value; + version = package.Versions!.FirstOrDefault(v => v.VersionNumber == requiredVersion); + if (version is null) { - continue; + Write.Warn($"Version {requiredVersion} could not be found for mod {fullname}, using latest instead"); + version = package.Versions!.First(); } - visited.Add(dependency.Fullname!); - yield return dependency; } - } - } - - private static IEnumerable GenerateInner(List? packages, Config config, HttpClient http, PackageListingV1 root, Predicate visited) - { - if (visited(root)) - { - yield break; - } - - foreach (var dependency in root.Versions!.First().Dependencies!) - { - var match = InstallCommand.FullPackageNameRegex.Match(dependency); - var fullname = match.Groups["fullname"].Value; - var package = packages?.Find(p => p.Fullname == fullname) ?? AttemptResolveExperimental(config, http, match, root.Fullname!); - if (package == null) + else { - continue; + version = package.Versions!.First(); } - foreach (var innerPackage in GenerateInner(packages, config, http, package, visited)) + dict[fullname] = (currentId++, version); + foreach (var dep in version.Dependencies!) { - yield return innerPackage; + toVisit.Enqueue(dep); } } - - yield return root; + return dict.Values.OrderByDescending(x => x.id).Select(x => x.version); } - private static PackageListingV1? AttemptResolveExperimental(Config config, HttpClient http, Match nameMatch, string neededBy) + private static PackageListingV1? AttemptResolveExperimental(Config config, HttpClient http, Match nameMatch) { var response = http.Send(config.Api.GetPackageMetadata(nameMatch.Groups["namespace"].Value, nameMatch.Groups["name"].Value)); if (response.StatusCode == HttpStatusCode.NotFound) { - Write.Warn($"Failed to resolve dependency {nameMatch.Groups["fullname"].Value} for {neededBy}, continuing without it."); + Write.Warn($"Failed to resolve dependency {nameMatch.Groups["fullname"].Value}, continuing without it."); return null; } response.EnsureSuccessStatusCode(); using var reader = new StreamReader(response.Content.ReadAsStream()); var data = PackageData.Deserialize(reader.ReadToEnd()); - Write.Warn($"Package {data!.Fullname} (needed by {neededBy}) exists in different community, ignoring"); + Write.Warn($"Package {data!.Fullname} exists in different community, ignoring"); return null; } } From 863912d63a6558202d0fe425543c2b53e14f3dfe Mon Sep 17 00:00:00 2001 From: Aaron Robinson Date: Tue, 11 Apr 2023 16:05:07 -0500 Subject: [PATCH 02/34] Fix TCLI directory switch and LD_PRELOAD shenanigans --- ThunderstoreCLI/Game/ModProfile.cs | 2 +- ThunderstoreCLI/Options.cs | 5 ----- tcli-bepinex-installer/src/main.rs | 11 +++++++---- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/ThunderstoreCLI/Game/ModProfile.cs b/ThunderstoreCLI/Game/ModProfile.cs index e842c10..5a43fb0 100644 --- a/ThunderstoreCLI/Game/ModProfile.cs +++ b/ThunderstoreCLI/Game/ModProfile.cs @@ -20,7 +20,7 @@ internal ModProfile(GameDefinition gameDef, string name, string tcliDirectory) { Name = name; - var directory = Path.Combine(tcliDirectory, "Profiles", gameDef.Identifier, name); + var directory = Path.GetFullPath(Path.Combine(tcliDirectory, "Profiles", gameDef.Identifier, name)); if (!Directory.Exists(directory)) { Directory.CreateDirectory(directory); diff --git a/ThunderstoreCLI/Options.cs b/ThunderstoreCLI/Options.cs index b442cf1..9a3a14f 100644 --- a/ThunderstoreCLI/Options.cs +++ b/ThunderstoreCLI/Options.cs @@ -75,11 +75,6 @@ public override bool Validate() return false; } - if (!Directory.Exists(TcliDirectory)) - { - Directory.CreateDirectory(TcliDirectory!); - } - return true; } } diff --git a/tcli-bepinex-installer/src/main.rs b/tcli-bepinex-installer/src/main.rs index 546de59..70b2618 100644 --- a/tcli-bepinex-installer/src/main.rs +++ b/tcli-bepinex-installer/src/main.rs @@ -345,21 +345,24 @@ fn output_instructions(game_dir: PathBuf, bep_dir: PathBuf, platform: GamePlatfo ); let mut ld_library = OsString::from(game_dir.join("doorstop_libs")); - if let Some(orig) = env::var_os("LD_LIBRARY") { + if let Some(orig) = env::var_os("LD_LIBRARY_PATH") { ld_library.push(":"); ld_library.push(orig); } - println!("ENVIRONMENT:LD_LIBRARY={}", ld_library.to_string_lossy()); + println!( + "ENVIRONMENT:LD_LIBRARY_PATH={}", + ld_library.to_string_lossy() + ); - let mut ld_preload = OsString::from(game_dir.join("doorstop_libs").join({ + let mut ld_preload = OsString::from({ // FIXME: properly determine arch of the game exe, instead of assuming its the same as this exe if cfg!(target_arch = "x86_64") { "libdoorstop_x64.so" } else { "libdoorstop_x86.so" } - })); + }); if let Some(orig) = env::var_os("LD_PRELOAD") { ld_preload.push(":"); ld_preload.push(orig); From 9de949ba975a55505fc4f7a81716ae9c1b75c814 Mon Sep 17 00:00:00 2001 From: Aaron Robinson Date: Mon, 24 Apr 2023 23:31:54 -0500 Subject: [PATCH 03/34] Add support for community-specific categories --- ThunderstoreCLI/Commands/BuildCommand.cs | 2 +- .../CommandValidator.cs} | 6 ++-- ThunderstoreCLI/Commands/InitCommand.cs | 2 +- ThunderstoreCLI/Commands/PublishCommand.cs | 2 +- ThunderstoreCLI/Configuration/Config.cs | 9 +++-- .../{BaseConfig.cs => DefaultConfig.cs} | 2 +- .../Configuration/ProjectFileConfig.cs | 2 +- ThunderstoreCLI/Models/PublishModels.cs | 2 ++ ThunderstoreCLI/Models/ThunderstoreProject.cs | 34 +++++++++++++++++-- ThunderstoreCLI/Utils/DictionaryExtensions.cs | 9 +++++ 10 files changed, 56 insertions(+), 14 deletions(-) rename ThunderstoreCLI/{Configuration/Validator.cs => Commands/CommandValidator.cs} (93%) rename ThunderstoreCLI/Configuration/{BaseConfig.cs => DefaultConfig.cs} (97%) create mode 100644 ThunderstoreCLI/Utils/DictionaryExtensions.cs diff --git a/ThunderstoreCLI/Commands/BuildCommand.cs b/ThunderstoreCLI/Commands/BuildCommand.cs index b37abb1..3cdbeac 100644 --- a/ThunderstoreCLI/Commands/BuildCommand.cs +++ b/ThunderstoreCLI/Commands/BuildCommand.cs @@ -309,7 +309,7 @@ public static string SerializeManifest(Config config) public static List ValidateConfig(Config config, bool throwIfErrors = true) { - var v = new Validator("build"); + var v = new CommandValidator("build"); v.AddIfEmpty(config.PackageConfig.Namespace, "Package Namespace"); v.AddIfEmpty(config.PackageConfig.Name, "Package Name"); v.AddIfNotSemver(config.PackageConfig.VersionNumber, "Package VersionNumber"); diff --git a/ThunderstoreCLI/Configuration/Validator.cs b/ThunderstoreCLI/Commands/CommandValidator.cs similarity index 93% rename from ThunderstoreCLI/Configuration/Validator.cs rename to ThunderstoreCLI/Commands/CommandValidator.cs index f39b696..fbd7ac6 100644 --- a/ThunderstoreCLI/Configuration/Validator.cs +++ b/ThunderstoreCLI/Commands/CommandValidator.cs @@ -1,14 +1,14 @@ using ThunderstoreCLI.Utils; -namespace ThunderstoreCLI.Configuration; +namespace ThunderstoreCLI.Commands; /// Helper for validating command-specific configurations -public class Validator +public class CommandValidator { private List _errors; private string _name; - public Validator(string commandName, List? errors = null) + public CommandValidator(string commandName, List? errors = null) { _name = commandName; _errors = errors ?? new List(); diff --git a/ThunderstoreCLI/Commands/InitCommand.cs b/ThunderstoreCLI/Commands/InitCommand.cs index 6aaa02f..a63bb57 100644 --- a/ThunderstoreCLI/Commands/InitCommand.cs +++ b/ThunderstoreCLI/Commands/InitCommand.cs @@ -76,7 +76,7 @@ public static string BuildReadme(Config config) private static void ValidateConfig(Config config) { - var v = new Validator("init"); + var v = new CommandValidator("init"); v.AddIfEmpty(config.PackageConfig.Namespace, "Package Namespace"); v.AddIfEmpty(config.PackageConfig.Name, "Package Name"); v.AddIfNotSemver(config.PackageConfig.VersionNumber, "Package VersionNumber"); diff --git a/ThunderstoreCLI/Commands/PublishCommand.cs b/ThunderstoreCLI/Commands/PublishCommand.cs index 4658229..de07e9b 100644 --- a/ThunderstoreCLI/Commands/PublishCommand.cs +++ b/ThunderstoreCLI/Commands/PublishCommand.cs @@ -290,7 +290,7 @@ private static void HandleRequestError( private static void ValidateConfig(Config config, bool justReturnErrors = false) { var buildConfigErrors = BuildCommand.ValidateConfig(config, false); - var v = new Validator("publish", buildConfigErrors); + var v = new CommandValidator("publish", buildConfigErrors); v.AddIfEmpty(config.AuthConfig.AuthToken, "Auth AuthToken"); v.ThrowIfErrors(); } diff --git a/ThunderstoreCLI/Configuration/Config.cs b/ThunderstoreCLI/Configuration/Config.cs index af7ba0d..ff35a83 100644 --- a/ThunderstoreCLI/Configuration/Config.cs +++ b/ThunderstoreCLI/Configuration/Config.cs @@ -37,7 +37,7 @@ public static Config FromCLI(IConfigProvider cliConfig) providers.Add(new EnvironmentConfig()); if (cliConfig is CLIConfig) providers.Add(new ProjectFileConfig()); - providers.Add(new BaseConfig()); + providers.Add(new DefaultConfig()); return Parse(providers.ToArray()); } @@ -102,7 +102,10 @@ public PackageUploadMetadata GetUploadMetadata(string fileUuid) return new PackageUploadMetadata() { AuthorName = PackageConfig.Namespace, - Categories = PublishConfig.Categories, + Categories = PublishConfig.Categories!.GetOrDefault("") ?? Array.Empty(), + CommunityCategories = PublishConfig.Categories! + .Where(kvp => kvp.Key != "") + .ToDictionary(kvp => kvp.Key, kvp => kvp.Value), Communities = PublishConfig.Communities, HasNsfwContent = PackageConfig.ContainsNsfwContent ?? false, UploadUUID = fileUuid @@ -212,7 +215,7 @@ public class PublishConfig { public string? File { get; set; } public string[]? Communities { get; set; } - public string[]? Categories { get; set; } + public Dictionary? Categories { get; set; } } public class AuthConfig diff --git a/ThunderstoreCLI/Configuration/BaseConfig.cs b/ThunderstoreCLI/Configuration/DefaultConfig.cs similarity index 97% rename from ThunderstoreCLI/Configuration/BaseConfig.cs rename to ThunderstoreCLI/Configuration/DefaultConfig.cs index 16f32a1..c78cef7 100644 --- a/ThunderstoreCLI/Configuration/BaseConfig.cs +++ b/ThunderstoreCLI/Configuration/DefaultConfig.cs @@ -1,6 +1,6 @@ namespace ThunderstoreCLI.Configuration; -class BaseConfig : EmptyConfig +class DefaultConfig : EmptyConfig { public override GeneralConfig? GetGeneralConfig() { diff --git a/ThunderstoreCLI/Configuration/ProjectFileConfig.cs b/ThunderstoreCLI/Configuration/ProjectFileConfig.cs index 2afec61..33323a3 100644 --- a/ThunderstoreCLI/Configuration/ProjectFileConfig.cs +++ b/ThunderstoreCLI/Configuration/ProjectFileConfig.cs @@ -62,7 +62,7 @@ public override void Parse(Config currentConfig) { return new PublishConfig() { - Categories = Project.Publish?.Categories, + Categories = Project.Publish?.Categories.Categories, Communities = Project.Publish?.Communities }; } diff --git a/ThunderstoreCLI/Models/PublishModels.cs b/ThunderstoreCLI/Models/PublishModels.cs index f4aa90d..cb2e0af 100644 --- a/ThunderstoreCLI/Models/PublishModels.cs +++ b/ThunderstoreCLI/Models/PublishModels.cs @@ -10,6 +10,8 @@ public class PackageUploadMetadata : BaseJson [JsonProperty("communities")] public string[]? Communities { get; set; } + [JsonProperty("community_categories")] public Dictionary? CommunityCategories { get; set; } + [JsonProperty("has_nsfw_content")] public bool HasNsfwContent { get; set; } [JsonProperty("upload_uuid")] public string? UploadUUID { get; set; } diff --git a/ThunderstoreCLI/Models/ThunderstoreProject.cs b/ThunderstoreCLI/Models/ThunderstoreProject.cs index 2b7bbba..6b09b7a 100644 --- a/ThunderstoreCLI/Models/ThunderstoreProject.cs +++ b/ThunderstoreCLI/Models/ThunderstoreProject.cs @@ -8,6 +8,29 @@ namespace ThunderstoreCLI.Models; [TomlDoNotInlineObject] public class ThunderstoreProject : BaseToml { + public struct CategoryDictionary + { + public Dictionary Categories; + } + + static ThunderstoreProject() + { + TomletMain.RegisterMapper( + dict => TomletMain.ValueFrom(dict.Categories), + toml => toml switch + { + TomlArray arr => new CategoryDictionary + { + Categories = new Dictionary + { + { "", arr.ArrayValues.Select(v => v.StringValue).ToArray() } + } + }, + TomlTable table => new CategoryDictionary { Categories = TomletMain.To>(table) }, + _ => throw new NotSupportedException() + }); + } + [TomlDoNotInlineObject] public class ConfigData { @@ -75,10 +98,15 @@ public class PublishData { "riskofrain2" }; + [TomlProperty("categories")] - public string[] Categories { get; set; } = + [TomlDoNotInlineObject] + public CategoryDictionary Categories { get; set; } = new() { - "items", "skills" + Categories = new Dictionary + { + { "riskofrain2", new[] { "items", "skills" } } + } }; } [TomlProperty("publish")] @@ -112,7 +140,7 @@ public ThunderstoreProject(Config config) }; Publish = new PublishData() { - Categories = config.PublishConfig.Categories!, + Categories = new CategoryDictionary { Categories = config.PublishConfig.Categories! }, Communities = config.PublishConfig.Communities!, Repository = config.GeneralConfig.Repository }; diff --git a/ThunderstoreCLI/Utils/DictionaryExtensions.cs b/ThunderstoreCLI/Utils/DictionaryExtensions.cs new file mode 100644 index 0000000..6257624 --- /dev/null +++ b/ThunderstoreCLI/Utils/DictionaryExtensions.cs @@ -0,0 +1,9 @@ +namespace ThunderstoreCLI.Utils; + +public static class DictionaryExtensions +{ + public static TValue? GetOrDefault(this Dictionary dict, TKey key) where TKey : notnull + { + return dict.TryGetValue(key, out var value) ? value : default; + } +} From ede40973919344d0c1ffb7ad5e26426625d7dfa8 Mon Sep 17 00:00:00 2001 From: Lordfirespeed <28568841+Lordfirespeed@users.noreply.github.com> Date: Mon, 4 Dec 2023 19:46:18 +0000 Subject: [PATCH 04/34] add setup-rust step --- .github/workflows/test.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index cf6a83b..77f1bf8 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -34,6 +34,8 @@ jobs: - uses: actions/setup-dotnet@v3 with: dotnet-version: '7' + - name: Setup Rust/Cargo + uses: moonrepo/setup-rust@v1 - name: Install dependencies run: dotnet restore - name: Build From 646ea48112e03be1e6fff44a34255ab7d766d2aa Mon Sep 17 00:00:00 2001 From: Lordfirespeed <28568841+Lordfirespeed@users.noreply.github.com> Date: Mon, 4 Dec 2023 19:47:33 +0000 Subject: [PATCH 05/34] update actions/checkout from v2 to v4 --- .github/workflows/publish.yml | 2 +- .github/workflows/release.yml | 6 +++--- .github/workflows/test.yml | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 38aefe1..812261a 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -8,7 +8,7 @@ jobs: nuget: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - uses: actions/setup-dotnet@v3 with: dotnet-version: '7' diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e141a4d..6423ce6 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -10,7 +10,7 @@ jobs: validate-tag: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - id: tag uses: dawidd6/action-get-tag@v1 - id: regex-match @@ -43,7 +43,7 @@ jobs: target: osx-x64 os: macos-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - uses: actions/setup-dotnet@v3 with: dotnet-version: '7' @@ -81,7 +81,7 @@ jobs: name: Create .nupkg runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - uses: actions/setup-dotnet@v3 with: dotnet-version: '7' diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 77f1bf8..78124e4 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -7,7 +7,7 @@ jobs: name: Code style check runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - uses: actions/setup-dotnet@v3 with: dotnet-version: '7' @@ -30,7 +30,7 @@ jobs: env: OS: ${{ matrix.os }} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - uses: actions/setup-dotnet@v3 with: dotnet-version: '7' From 31d0053b4897e550a5332b5212448c34a2fc198b Mon Sep 17 00:00:00 2001 From: Lordfirespeed <28568841+Lordfirespeed@users.noreply.github.com> Date: Mon, 4 Dec 2023 19:48:12 +0000 Subject: [PATCH 06/34] update actions/setup-dotnet from v3 to v4 --- .github/workflows/publish.yml | 2 +- .github/workflows/release.yml | 4 ++-- .github/workflows/test.yml | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 812261a..e3ff8fd 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -9,7 +9,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: actions/setup-dotnet@v3 + - uses: actions/setup-dotnet@v4 with: dotnet-version: '7' diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 6423ce6..7f953d4 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -44,7 +44,7 @@ jobs: os: macos-latest steps: - uses: actions/checkout@v4 - - uses: actions/setup-dotnet@v3 + - uses: actions/setup-dotnet@v4 with: dotnet-version: '7' - id: tag @@ -82,7 +82,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: actions/setup-dotnet@v3 + - uses: actions/setup-dotnet@v4 with: dotnet-version: '7' - id: tag diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 78124e4..9ecae3c 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -8,7 +8,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: actions/setup-dotnet@v3 + - uses: actions/setup-dotnet@v4 with: dotnet-version: '7' - uses: actions/setup-python@v2 @@ -31,7 +31,7 @@ jobs: OS: ${{ matrix.os }} steps: - uses: actions/checkout@v4 - - uses: actions/setup-dotnet@v3 + - uses: actions/setup-dotnet@v4 with: dotnet-version: '7' - name: Setup Rust/Cargo From d40bcf74e6989452b89af496f617f26225cb27f2 Mon Sep 17 00:00:00 2001 From: Lordfirespeed <28568841+Lordfirespeed@users.noreply.github.com> Date: Mon, 4 Dec 2023 20:31:17 +0000 Subject: [PATCH 07/34] reduce complexity of pure SemVer regex https://semver.org/#is-there-a-suggested-regular-expression-regex-to-check-a-semver-string --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 7f953d4..da63e5b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -17,7 +17,7 @@ jobs: uses: actions-ecosystem/action-regex-match@v2 with: text: ${{ steps.tag.outputs.tag }} - regex: '^([1-9][0-9]*|[0-9])\.([1-9][0-9]*|[0-9])\.([1-9][0-9]*|[0-9])$' + regex: '^([1-9][0-9]*|0)\.([1-9][0-9]*|0)\.([1-9][0-9]*|0)$' - id: fail-fast if: ${{ steps.regex-match.outputs.match == '' }} uses: actions/github-script@v3 From 5b4dccd92e9da6e31bcfadc02c47534f4c414b7b Mon Sep 17 00:00:00 2001 From: Lordfirespeed <28568841+Lordfirespeed@users.noreply.github.com> Date: Mon, 4 Dec 2023 20:32:01 +0000 Subject: [PATCH 08/34] remove 'get tag' step from jobs that depend on `validate-tag` --- .github/workflows/release.yml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index da63e5b..7e3c7b2 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -47,8 +47,7 @@ jobs: - uses: actions/setup-dotnet@v4 with: dotnet-version: '7' - - id: tag - uses: dawidd6/action-get-tag@v1 + - name: Install dependencies run: dotnet restore @@ -85,8 +84,7 @@ jobs: - uses: actions/setup-dotnet@v4 with: dotnet-version: '7' - - id: tag - uses: dawidd6/action-get-tag@v1 + - name: Install dependencies run: dotnet restore From 5c4c5b4ac4663123e984e8858aa714472113d935 Mon Sep 17 00:00:00 2001 From: Lordfirespeed <28568841+Lordfirespeed@users.noreply.github.com> Date: Mon, 4 Dec 2023 20:33:47 +0000 Subject: [PATCH 09/34] add `.yml` entry to editorconfig --- .editorconfig | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.editorconfig b/.editorconfig index fd10fe0..72bd5fd 100644 --- a/.editorconfig +++ b/.editorconfig @@ -8,6 +8,9 @@ charset = utf-8 indent_style = space indent_size = 4 +[*.yml] +indent_size = 2 + [*.{cs,vb}] # https://docs.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/formatting-rules csharp_new_line_before_open_brace = all From bc5ef4b3b7160e8ff06ff45ef8415cc1523808c1 Mon Sep 17 00:00:00 2001 From: Lordfirespeed <28568841+Lordfirespeed@users.noreply.github.com> Date: Mon, 4 Dec 2023 20:35:22 +0000 Subject: [PATCH 10/34] add `tag` step output to `validate-tag` job outputs --- .github/workflows/release.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 7e3c7b2..e79b2dd 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -9,6 +9,8 @@ jobs: # Validate tag with proper regex since the check above is very limited. validate-tag: runs-on: ubuntu-latest + outputs: + tag: ${{ steps.tag.outputs.tag }} steps: - uses: actions/checkout@v4 - id: tag From 83e673cc0e69042d34c24180d3aab97882b142c9 Mon Sep 17 00:00:00 2001 From: Lordfirespeed <28568841+Lordfirespeed@users.noreply.github.com> Date: Mon, 4 Dec 2023 20:36:22 +0000 Subject: [PATCH 11/34] replace references to `steps.tag.outputs.tag` with `needs.validate-tag.outputs.tag` --- .github/workflows/release.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e79b2dd..95fa16c 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -56,7 +56,7 @@ jobs: - name: Build shell: bash run: | - release_name="tcli-${{ steps.tag.outputs.tag }}-${{ matrix.target }}" + release_name="tcli-${{ needs.validate-tag.outputs.tag }}-${{ matrix.target }}" dotnet publish ThunderstoreCLI/ThunderstoreCLI.csproj -c Release -r "${{ matrix.target }}" --self-contained true -f net7.0 -o "${release_name}" if [ "${{ matrix.target }}" == "win-x64" ]; then @@ -71,7 +71,7 @@ jobs: uses: softprops/action-gh-release@v1 with: files: "tcli*" - name: "Thunderstore CLI ${{ steps.tag.outputs.tag }}" + name: "Thunderstore CLI ${{ needs.validate-tag.outputs.tag }}" body_path: ${{ github.workspace }}/.github/RELEASE_TEMPLATE.md draft: true prerelease: ${{ startsWith(steps.tag.outputs.tag, '0.') }} @@ -98,7 +98,7 @@ jobs: uses: softprops/action-gh-release@v1 with: files: "tcli*" - name: "Thunderstore CLI ${{ steps.tag.outputs.tag }}" + name: "Thunderstore CLI ${{ needs.validate-tag.outputs.tag }}" body_path: ${{ github.workspace }}/.github/RELEASE_TEMPLATE.md draft: true prerelease: ${{ startsWith(steps.tag.outputs.tag, '0.') }} From 6c8077b03f9f4d21ee7b786c5b43659b5f53f7c6 Mon Sep 17 00:00:00 2001 From: Lordfirespeed <28568841+Lordfirespeed@users.noreply.github.com> Date: Mon, 4 Dec 2023 20:58:44 +0000 Subject: [PATCH 12/34] hoist job names to top, add step names for `release` workflow --- .github/workflows/release.yml | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 95fa16c..63a7837 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -8,12 +8,15 @@ on: jobs: # Validate tag with proper regex since the check above is very limited. validate-tag: + name: Validate tag's semantic version runs-on: ubuntu-latest outputs: tag: ${{ steps.tag.outputs.tag }} steps: - - uses: actions/checkout@v4 - - id: tag + - name: Checkout ref that triggered workflow + uses: actions/checkout@v4 + - name: Ensure triggering ref is a tag + id: tag uses: dawidd6/action-get-tag@v1 - id: regex-match uses: actions-ecosystem/action-regex-match@v2 @@ -27,9 +30,9 @@ jobs: script: core.setFailed('Tag is invalid') platform-binary: + name: Create binary ${{ matrix.target }} needs: validate-tag if: github.event.base_ref == 'refs/heads/master' - name: Create binary ${{ matrix.target }} runs-on: ${{ matrix.os }} strategy: matrix: @@ -45,8 +48,10 @@ jobs: target: osx-x64 os: macos-latest steps: - - uses: actions/checkout@v4 - - uses: actions/setup-dotnet@v4 + - name: Checkout ref that triggered workflow + uses: actions/checkout@v4 + - name: Setup .NET + uses: actions/setup-dotnet@v4 with: dotnet-version: '7' @@ -67,7 +72,7 @@ jobs: rm -r ${release_name} - - name: Publish to GitHub + - name: Add build artifacts to draft GitHub release uses: softprops/action-gh-release@v1 with: files: "tcli*" @@ -77,13 +82,15 @@ jobs: prerelease: ${{ startsWith(steps.tag.outputs.tag, '0.') }} nupkg: + name: Create .nupkg needs: validate-tag if: github.event.base_ref == 'refs/heads/master' - name: Create .nupkg runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - - uses: actions/setup-dotnet@v4 + - name: Checkout ref that triggered workflow + uses: actions/checkout@v4 + - name: Setup .NET + uses: actions/setup-dotnet@v4 with: dotnet-version: '7' @@ -94,7 +101,7 @@ jobs: shell: bash run: dotnet pack ThunderstoreCLI/ThunderstoreCLI.csproj -c Release -o "." -p:EnableInstallers=false -p:PublishSelfContained=false -p:PublishSingleFile=false -p:PublishTrimmed=false -p:PublishReadyToRun=false - - name: Publish to GitHub + - name: Add build artifacts to draft GitHub release uses: softprops/action-gh-release@v1 with: files: "tcli*" From cce90fee34d8fbd9abd5f37b124726a19e6205d0 Mon Sep 17 00:00:00 2001 From: Lordfirespeed <28568841+Lordfirespeed@users.noreply.github.com> Date: Mon, 4 Dec 2023 20:59:15 +0000 Subject: [PATCH 13/34] standardise whitespace between job steps for `release` workflow --- .github/workflows/release.yml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 63a7837..546d0b0 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -15,14 +15,17 @@ jobs: steps: - name: Checkout ref that triggered workflow uses: actions/checkout@v4 + - name: Ensure triggering ref is a tag id: tag uses: dawidd6/action-get-tag@v1 + - id: regex-match uses: actions-ecosystem/action-regex-match@v2 with: text: ${{ steps.tag.outputs.tag }} regex: '^([1-9][0-9]*|0)\.([1-9][0-9]*|0)\.([1-9][0-9]*|0)$' + - id: fail-fast if: ${{ steps.regex-match.outputs.match == '' }} uses: actions/github-script@v3 @@ -50,11 +53,12 @@ jobs: steps: - name: Checkout ref that triggered workflow uses: actions/checkout@v4 + - name: Setup .NET uses: actions/setup-dotnet@v4 with: dotnet-version: '7' - + - name: Install dependencies run: dotnet restore @@ -89,11 +93,12 @@ jobs: steps: - name: Checkout ref that triggered workflow uses: actions/checkout@v4 + - name: Setup .NET uses: actions/setup-dotnet@v4 with: dotnet-version: '7' - + - name: Install dependencies run: dotnet restore From b0bc3ba3b98a66c1a72e247f6aee88fbff6779d5 Mon Sep 17 00:00:00 2001 From: Lordfirespeed <28568841+Lordfirespeed@users.noreply.github.com> Date: Mon, 4 Dec 2023 20:59:41 +0000 Subject: [PATCH 14/34] add steps to setup Cargo before running build command --- .github/workflows/release.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 546d0b0..5a5a759 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -62,6 +62,9 @@ jobs: - name: Install dependencies run: dotnet restore + - name: Setup Cargo/Rust + uses: moonrepo/setup-rust@v1 + - name: Build shell: bash run: | @@ -102,6 +105,9 @@ jobs: - name: Install dependencies run: dotnet restore + - name: Setup Cargo/Rust + uses: moonrepo/setup-rust@v1 + - name: Build shell: bash run: dotnet pack ThunderstoreCLI/ThunderstoreCLI.csproj -c Release -o "." -p:EnableInstallers=false -p:PublishSelfContained=false -p:PublishSingleFile=false -p:PublishTrimmed=false -p:PublishReadyToRun=false From 25b059bae1488217bd0a4718a8bd71b7595874cc Mon Sep 17 00:00:00 2001 From: Lordfirespeed <28568841+Lordfirespeed@users.noreply.github.com> Date: Mon, 4 Dec 2023 21:07:06 +0000 Subject: [PATCH 15/34] add step names for `test` workflow --- .github/workflows/test.yml | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 9ecae3c..604269d 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -7,14 +7,17 @@ jobs: name: Code style check runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - - uses: actions/setup-dotnet@v4 + - name: Checkout ref that triggered workflow + uses: actions/checkout@v4 + - name: Setup .NET + uses: actions/setup-dotnet@v4 with: dotnet-version: '7' - - uses: actions/setup-python@v2 + - name: Setup Python + uses: actions/setup-python@v2 with: python-version: '3.8' - - name: Install pre-commit + - name: Install pre-commit framework run: curl https://pre-commit.com/install-local.py | python - - name: Install dotnet-format run: dotnet tool install -g dotnet-format @@ -30,11 +33,13 @@ jobs: env: OS: ${{ matrix.os }} steps: - - uses: actions/checkout@v4 - - uses: actions/setup-dotnet@v4 + - name: Checkout ref that triggered workflow + uses: actions/checkout@v4 + - name: setup .NET + uses: actions/setup-dotnet@v4 with: dotnet-version: '7' - - name: Setup Rust/Cargo + - name: Setup Cargo/Rust uses: moonrepo/setup-rust@v1 - name: Install dependencies run: dotnet restore From 3fbe8df98673ed9a55082dc406d5b5e04d04f2cc Mon Sep 17 00:00:00 2001 From: Lordfirespeed <28568841+Lordfirespeed@users.noreply.github.com> Date: Mon, 4 Dec 2023 21:14:42 +0000 Subject: [PATCH 16/34] standardise whitespace between job steps for `test` workflow --- .github/workflows/test.yml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 604269d..211da03 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -9,18 +9,23 @@ jobs: steps: - name: Checkout ref that triggered workflow uses: actions/checkout@v4 + - name: Setup .NET uses: actions/setup-dotnet@v4 with: dotnet-version: '7' + - name: Setup Python uses: actions/setup-python@v2 with: python-version: '3.8' + - name: Install pre-commit framework run: curl https://pre-commit.com/install-local.py | python - + - name: Install dotnet-format run: dotnet tool install -g dotnet-format + - name: Run pre-commit run: ~/bin/pre-commit run --show-diff-on-failure --color=always --all-files @@ -35,18 +40,24 @@ jobs: steps: - name: Checkout ref that triggered workflow uses: actions/checkout@v4 + - name: setup .NET uses: actions/setup-dotnet@v4 with: dotnet-version: '7' + - name: Setup Cargo/Rust uses: moonrepo/setup-rust@v1 + - name: Install dependencies run: dotnet restore + - name: Build run: dotnet build --configuration Release --no-restore + - name: Run xUnit tests run: dotnet test -p:EnableInstallers=false --collect:"XPlat Code Coverage" + - name: Upload coverage to Codecov uses: codecov/codecov-action@v2 with: From 5c795468071cdcaebdaf1d2bb43bf80b8d60065c Mon Sep 17 00:00:00 2001 From: Lordfirespeed <28568841+Lordfirespeed@users.noreply.github.com> Date: Mon, 4 Dec 2023 21:19:27 +0000 Subject: [PATCH 17/34] use more appropriate job names in `release` workflow --- .github/workflows/release.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 5a5a759..57f5ec5 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -8,7 +8,7 @@ on: jobs: # Validate tag with proper regex since the check above is very limited. validate-tag: - name: Validate tag's semantic version + name: Validate tag semantic version runs-on: ubuntu-latest outputs: tag: ${{ steps.tag.outputs.tag }} @@ -33,7 +33,7 @@ jobs: script: core.setFailed('Tag is invalid') platform-binary: - name: Create binary ${{ matrix.target }} + name: Build binaries for ${{ matrix.target }} needs: validate-tag if: github.event.base_ref == 'refs/heads/master' runs-on: ${{ matrix.os }} @@ -89,7 +89,7 @@ jobs: prerelease: ${{ startsWith(steps.tag.outputs.tag, '0.') }} nupkg: - name: Create .nupkg + name: Build NuGet Package needs: validate-tag if: github.event.base_ref == 'refs/heads/master' runs-on: ubuntu-latest From a2c0591d5506f4c76d912967879f739a84528163 Mon Sep 17 00:00:00 2001 From: Lordfirespeed <28568841+Lordfirespeed@users.noreply.github.com> Date: Mon, 4 Dec 2023 21:19:44 +0000 Subject: [PATCH 18/34] add job name and step names to `publish` workflow --- .github/workflows/publish.yml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index e3ff8fd..362f640 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -6,10 +6,13 @@ on: jobs: nuget: + name: Publish NuGet Package runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - - uses: actions/setup-dotnet@v4 + - name: Checkout ref that triggered workflow + uses: actions/checkout@v4 + - name: Setup .NET + uses: actions/setup-dotnet@v4 with: dotnet-version: '7' From 61cc94e765c1a5a04cebcd9d11e0a434459206ef Mon Sep 17 00:00:00 2001 From: Lordfirespeed <28568841+Lordfirespeed@users.noreply.github.com> Date: Mon, 4 Dec 2023 21:20:26 +0000 Subject: [PATCH 19/34] standardise whitespace in `publish` workflow --- .github/workflows/publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 362f640..f6eb4b2 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -11,6 +11,7 @@ jobs: steps: - name: Checkout ref that triggered workflow uses: actions/checkout@v4 + - name: Setup .NET uses: actions/setup-dotnet@v4 with: @@ -24,7 +25,6 @@ jobs: file: "tcli.${{ github.ref_name }}.nupkg" target: "tcli.nupkg" - - name: Publish to NuGet shell: bash run: dotnet nuget push tcli.nupkg -s https://api.nuget.org/v3/index.json -k ${{ secrets.NUGET_API_KEY }} --skip-duplicate From db4fffd8cd4acaea48995057f9ce1bb5961c1c4f Mon Sep 17 00:00:00 2001 From: Lordfirespeed <28568841+Lordfirespeed@users.noreply.github.com> Date: Mon, 4 Dec 2023 21:32:03 +0000 Subject: [PATCH 20/34] update fetch-gh-release-asset action and remove redundant default argument --- .github/workflows/publish.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index f6eb4b2..b545897 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -18,9 +18,8 @@ jobs: dotnet-version: '7' - name: Fetch Latest .nupkg - uses: dsaltares/fetch-gh-release-asset@0efe227dedb360b09ea0e533795d584b61c461a9 + uses: dsaltares/fetch-gh-release-asset@1.1.1 with: - token: "${{ secrets.GITHUB_TOKEN }}" version: "tags/${{ github.ref_name }}" file: "tcli.${{ github.ref_name }}.nupkg" target: "tcli.nupkg" From 0945b9a090ef69b725e500e40586ed265aa2aba1 Mon Sep 17 00:00:00 2001 From: Lordfirespeed <28568841+Lordfirespeed@users.noreply.github.com> Date: Mon, 4 Dec 2023 21:37:26 +0000 Subject: [PATCH 21/34] update to codecov v3 --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 211da03..a73f6a4 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -59,7 +59,7 @@ jobs: run: dotnet test -p:EnableInstallers=false --collect:"XPlat Code Coverage" - name: Upload coverage to Codecov - uses: codecov/codecov-action@v2 + uses: codecov/codecov-action@v3 with: directory: ./ThunderstoreCLI.Tests/TestResults/ env_vars: OS From f2e35566432a802c9bdaccb04eb90e314d04d376 Mon Sep 17 00:00:00 2001 From: Lordfirespeed <28568841+Lordfirespeed@users.noreply.github.com> Date: Mon, 4 Dec 2023 21:39:45 +0000 Subject: [PATCH 22/34] update triggers for the 'test' task --- .github/workflows/test.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index a73f6a4..b1149aa 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,6 +1,11 @@ name: Build & Test -on: [push] +on: + # Trigger on pushes to the main branch + push: + branches: [ main ] + # Trigger on any pull request + pull_request: jobs: pre-commit: From 264f219720899675c6b973ba2e6cd27654fc82c7 Mon Sep 17 00:00:00 2001 From: Lordfirespeed <28568841+Lordfirespeed@users.noreply.github.com> Date: Mon, 4 Dec 2023 21:43:50 +0000 Subject: [PATCH 23/34] replace dawid66/action-get-tag with updated + verified fork devops-actions/action-get-tag --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 57f5ec5..eddaf2f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -18,7 +18,7 @@ jobs: - name: Ensure triggering ref is a tag id: tag - uses: dawidd6/action-get-tag@v1 + uses: devops-actions/action-get-tag@v1.0.2 - id: regex-match uses: actions-ecosystem/action-regex-match@v2 From 14b4887a34b34c6fe95e7b08016093eb23befd1d Mon Sep 17 00:00:00 2001 From: Lordfirespeed <28568841+Lordfirespeed@users.noreply.github.com> Date: Mon, 4 Dec 2023 21:48:59 +0000 Subject: [PATCH 24/34] add 'Build and Test' status badge --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 8cd8eeb..41478b2 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ # thunderstore-cli +[![Build & Test](https://github.com/thunderstore-io/thunderstore-cli/actions/workflows/test.yml/badge.svg)](https://github.com/thunderstore-io/thunderstore-cli/actions/workflows/test.yml) [![codecov](https://codecov.io/gh/thunderstore-io/thunderstore-cli/branch/master/graph/badge.svg)](https://codecov.io/gh/thunderstore-io/thunderstore-cli) Thunderstore CLI (just "TCLI" from here on) is a command line tool for building and uploading mod packages to From 3f4e91567b973ed61dda1b92ec3dfdc030196c6e Mon Sep 17 00:00:00 2001 From: Lordfirespeed <28568841+Lordfirespeed@users.noreply.github.com> Date: Mon, 4 Dec 2023 21:49:11 +0000 Subject: [PATCH 25/34] add NuGet package version badge --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 41478b2..1fbb6e4 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,7 @@ [![Build & Test](https://github.com/thunderstore-io/thunderstore-cli/actions/workflows/test.yml/badge.svg)](https://github.com/thunderstore-io/thunderstore-cli/actions/workflows/test.yml) [![codecov](https://codecov.io/gh/thunderstore-io/thunderstore-cli/branch/master/graph/badge.svg)](https://codecov.io/gh/thunderstore-io/thunderstore-cli) +[![NuGet Package](https://img.shields.io/nuget/v/tcli)](https://www.nuget.org/packages/tcli) Thunderstore CLI (just "TCLI" from here on) is a command line tool for building and uploading mod packages to [Thunderstore](https://thunderstore.io/) mod database, and installing mods via the command line. From 9dda3dcd0140fa511c63d521f848420de754c202 Mon Sep 17 00:00:00 2001 From: Lordfirespeed <28568841+Lordfirespeed@users.noreply.github.com> Date: Mon, 4 Dec 2023 21:49:21 +0000 Subject: [PATCH 26/34] add NuGet Downloads badge --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 1fbb6e4..4101faa 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,7 @@ [![Build & Test](https://github.com/thunderstore-io/thunderstore-cli/actions/workflows/test.yml/badge.svg)](https://github.com/thunderstore-io/thunderstore-cli/actions/workflows/test.yml) [![codecov](https://codecov.io/gh/thunderstore-io/thunderstore-cli/branch/master/graph/badge.svg)](https://codecov.io/gh/thunderstore-io/thunderstore-cli) [![NuGet Package](https://img.shields.io/nuget/v/tcli)](https://www.nuget.org/packages/tcli) +[![downloads](https://img.shields.io/nuget/dt/tcli)](https://www.nuget.org/packages/tcli) Thunderstore CLI (just "TCLI" from here on) is a command line tool for building and uploading mod packages to [Thunderstore](https://thunderstore.io/) mod database, and installing mods via the command line. From 5a503a9b99aa2cabf05ea24afbec7448f89f14a9 Mon Sep 17 00:00:00 2001 From: Lordfirespeed <28568841+Lordfirespeed@users.noreply.github.com> Date: Wed, 6 Dec 2023 05:47:50 +0000 Subject: [PATCH 27/34] update github-script action --- .github/workflows/release.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index eddaf2f..6afd7cc 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -16,7 +16,7 @@ jobs: - name: Checkout ref that triggered workflow uses: actions/checkout@v4 - - name: Ensure triggering ref is a tag + - name: Ensure triggering ref is a tag id: tag uses: devops-actions/action-get-tag@v1.0.2 @@ -28,7 +28,7 @@ jobs: - id: fail-fast if: ${{ steps.regex-match.outputs.match == '' }} - uses: actions/github-script@v3 + uses: actions/github-script@v7 with: script: core.setFailed('Tag is invalid') From ed7de60e12bf5c04eac22830b6397499a1f25ebd Mon Sep 17 00:00:00 2001 From: Mythic Date: Wed, 6 Dec 2023 18:53:57 +0200 Subject: [PATCH 28/34] Update test workflow branch name --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index b1149aa..a02ea0a 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -3,7 +3,7 @@ name: Build & Test on: # Trigger on pushes to the main branch push: - branches: [ main ] + branches: [ master ] # Trigger on any pull request pull_request: From 1aa408421bdbb82afe8d24c61cb2f4beaf9c74c0 Mon Sep 17 00:00:00 2001 From: Mythic Date: Wed, 6 Dec 2023 19:00:59 +0200 Subject: [PATCH 29/34] Run pre-commit --- .github/workflows/test.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index a02ea0a..06c9fb2 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,11 +1,11 @@ name: Build & Test -on: +on: # Trigger on pushes to the main branch push: branches: [ master ] # Trigger on any pull request - pull_request: + pull_request: jobs: pre-commit: @@ -62,7 +62,7 @@ jobs: - name: Run xUnit tests run: dotnet test -p:EnableInstallers=false --collect:"XPlat Code Coverage" - + - name: Upload coverage to Codecov uses: codecov/codecov-action@v3 with: From c18cd03a60d55fc80bf8e4598fcb7af949e8c42f Mon Sep 17 00:00:00 2001 From: Mythic Date: Wed, 6 Dec 2023 19:12:14 +0200 Subject: [PATCH 30/34] Add codecov token to test workflow --- .github/workflows/test.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 06c9fb2..9c234ee 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -69,3 +69,4 @@ jobs: directory: ./ThunderstoreCLI.Tests/TestResults/ env_vars: OS fail_ci_if_error: true + token: ${{ secrets.CODECOV_TOKEN }} From bf7f268b63884f0a43d4d8097e84c66b1a45925e Mon Sep 17 00:00:00 2001 From: Joe Clack <28568841+Lordfirespeed@users.noreply.github.com> Date: Wed, 6 Dec 2023 19:49:09 +0000 Subject: [PATCH 31/34] Subscribe to 'published' instead --- .github/workflows/publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index b545897..3229fc7 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -2,7 +2,7 @@ name: Publish on: release: - types: [released, prereleased] + types: [ published ] jobs: nuget: From f16512b3476a784635034ea320088e016bc1e35d Mon Sep 17 00:00:00 2001 From: Lordfirespeed <28568841+Lordfirespeed@users.noreply.github.com> Date: Fri, 8 Dec 2023 05:35:35 +0000 Subject: [PATCH 32/34] fix incorrect references to 'tag' job output --- .github/workflows/release.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 6afd7cc..dfc09ea 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -86,7 +86,7 @@ jobs: name: "Thunderstore CLI ${{ needs.validate-tag.outputs.tag }}" body_path: ${{ github.workspace }}/.github/RELEASE_TEMPLATE.md draft: true - prerelease: ${{ startsWith(steps.tag.outputs.tag, '0.') }} + prerelease: ${{ startsWith(needs.validate-tag.outputs.tag, '0.') }} nupkg: name: Build NuGet Package @@ -119,4 +119,4 @@ jobs: name: "Thunderstore CLI ${{ needs.validate-tag.outputs.tag }}" body_path: ${{ github.workspace }}/.github/RELEASE_TEMPLATE.md draft: true - prerelease: ${{ startsWith(steps.tag.outputs.tag, '0.') }} + prerelease: ${{ startsWith(needs.validate-tag.outputs.tag, '0.') }} From dad1673c0792ebc745aaab4212500fc8ba32e323 Mon Sep 17 00:00:00 2001 From: Lordfirespeed <28568841+Lordfirespeed@users.noreply.github.com> Date: Fri, 8 Dec 2023 05:43:33 +0000 Subject: [PATCH 33/34] strip build metadata from the application version as per SemVer spec https://semver.org/#spec-item-10 --- ThunderstoreCLI/Utils/MiscUtils.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ThunderstoreCLI/Utils/MiscUtils.cs b/ThunderstoreCLI/Utils/MiscUtils.cs index 3e93f21..627863e 100644 --- a/ThunderstoreCLI/Utils/MiscUtils.cs +++ b/ThunderstoreCLI/Utils/MiscUtils.cs @@ -23,8 +23,8 @@ public static int[] GetCurrentVersion() throw new Exception("Reading app version from assembly failed"); } - // Drop possible pre-release cruft ("-alpha.0.1") from the end. - var versionParts = version.Split('-')[0].Split('.'); + // Drop possible pre-release or build metadata cruft ("-alpha.0.1", "+abcde") from the end. + var versionParts = version.Split('-', '+')[0].Split('.'); if (versionParts is null || versionParts.Length != 3) { From 8b2e1dba1541466e4070024eb6616b5367e7704f Mon Sep 17 00:00:00 2001 From: Digitalroot Date: Mon, 10 Jun 2024 00:30:24 -0700 Subject: [PATCH 34/34] Update PackageListingV1.cs to fix #103 This might be all that is needed to fix #103 --- ThunderstoreCLI/Models/PackageListingV1.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ThunderstoreCLI/Models/PackageListingV1.cs b/ThunderstoreCLI/Models/PackageListingV1.cs index 0f07ac4..b4b9f94 100644 --- a/ThunderstoreCLI/Models/PackageListingV1.cs +++ b/ThunderstoreCLI/Models/PackageListingV1.cs @@ -104,7 +104,7 @@ public class PackageVersionV1 public string? Uuid4 { get; set; } [JsonProperty("file_size")] - public int FileSize { get; set; } + public long FileSize { get; set; } [JsonIgnore] private GroupCollection? _fullNameParts;