diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a283ad2dbb..6249bc92ab 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -29,6 +29,14 @@ jobs: - name: Run tests run: xvfb-run ./build test+only --configuration=Release --where="Category!=FlakyNetwork" + - name: Publish ckan.dll to NuGet + env: + NUGET_API_KEY: ${{ secrets.NUGET_API_KEY }} + if: env.NUGET_API_KEY + run: | + curl -o nuget.exe -L 'https://dist.nuget.org/win-x86-commandline/v5.6.0/nuget.exe' + mono nuget.exe push _build/out/CKAN/Release/bin/*.nupkg ${{ secrets.NUGET_API_KEY }} -Source https://api.nuget.org/v3/index.json -SkipDuplicate + - name: Build dmg run: ./build osx --configuration=Release --exclusive - name: Build deb diff --git a/AutoUpdate/CKAN-autoupdate.csproj b/AutoUpdate/CKAN-autoupdate.csproj index bae16e8402..581f14cd2b 100644 --- a/AutoUpdate/CKAN-autoupdate.csproj +++ b/AutoUpdate/CKAN-autoupdate.csproj @@ -20,6 +20,7 @@ ..\assets\ckan.ico net48;net7.0-windows true + true 512 prompt 4 diff --git a/CHANGELOG.md b/CHANGELOG.md index c8ada8e77d..20f71d65af 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,6 +30,7 @@ All notable changes to this project will be documented in this file. - [Netkan] Fix null reference exception in swinfo transformer (#3999 by: HebaruSan) - [Netkan] Improve netkan relationship error message (#4020, #4021 by: HebaruSan) - [Core] Get KSP2 version from game assembly (#4034 by: HebaruSan) +- [Multiple] Build nuget package, support netstandard2.0 build (#4039 by: HebaruSan) ## v1.34.4 (Niven) diff --git a/Core/CKAN-core.csproj b/Core/CKAN-core.csproj index b3f998f100..bdac8c276d 100644 --- a/Core/CKAN-core.csproj +++ b/Core/CKAN-core.csproj @@ -18,32 +18,43 @@ false 7.3 IDE1006 - net48;net7.0 + netstandard2.0;net48;net7.0 PrepareResources;$(CompileDependsOn) + + CKAN + Comprehensive Kerbal Archive Network + Manages mods for KSP1 and KPS2 + $([System.Text.RegularExpressions.Regex]::Replace( + $([System.IO.File]::ReadAllText("$(MSBuildProjectDirectory)\..\CHANGELOG.md")), + "^.*?##\s+v(\S+).*$", "$1", + System.Text.RegularExpressions.RegexOptions.Singleline)) + $(Version) + The CKAN Authors + Copyright © CKAN Authors 2014–2024 + KerbalSpaceProgram Mods + true + true + MIT + README.md + https://github.com/KSP-CKAN/CKAN + https://github.com/KSP-CKAN/CKAN + git + + + + + + - - - - - - - - - - - - - - Properties\GlobalAssemblyVersionInfo.cs @@ -53,6 +64,7 @@ + diff --git a/Core/Extensions/EnumerableExtensions.cs b/Core/Extensions/EnumerableExtensions.cs index ca57a2aedf..8c6b30042c 100644 --- a/Core/Extensions/EnumerableExtensions.cs +++ b/Core/Extensions/EnumerableExtensions.cs @@ -15,16 +15,43 @@ public static ICollection AsCollection(this IEnumerable source) ? throw new ArgumentNullException(nameof(source)) : source is ICollection collection ? collection : source.ToArray(); -#if NET45 - - public static HashSet ToHashSet(this IEnumerable source) +#if NET45 || NETSTANDARD2_0 + + #if NET45 + public + #elif NETSTANDARD2_0 + internal + #endif + static HashSet ToHashSet(this IEnumerable source) { if (source == null) + { throw new ArgumentNullException(nameof(source)); + } return new HashSet(source); } + #if NET45 + public + #elif NETSTANDARD2_0 + internal + #endif + static HashSet ToHashSet(this IEnumerable source, + IEqualityComparer comparer) + { + if (source == null) + { + throw new ArgumentNullException(nameof(source)); + } + + return new HashSet(source, comparer); + } + +#endif + +#if NET45 + public static IEnumerable Append(this IEnumerable source, T next) => source.Concat(Enumerable.Repeat(next, 1)); @@ -115,7 +142,7 @@ public static TimeSpan Sum(this IEnumerable source) public static IEnumerable ZipMany(this IEnumerable seq1, IEnumerable seq2, Func> func) => seq1.Zip(seq2, func).SelectMany(seqs => seqs); -#if NETFRAMEWORK +#if NETFRAMEWORK || NETSTANDARD2_0 /// /// Eliminate duplicate elements based on the value returned by a callback @@ -142,7 +169,7 @@ public static IEnumerable TraverseNodes(this T start, Func getNext) } } -#if NETFRAMEWORK +#if NETFRAMEWORK || NETSTANDARD2_0 /// /// Make pairs out of the elements of two sequences diff --git a/Core/Registry/IRegistryQuerier.cs b/Core/Registry/IRegistryQuerier.cs index 060c216b15..378e5b3c38 100644 --- a/Core/Registry/IRegistryQuerier.cs +++ b/Core/Registry/IRegistryQuerier.cs @@ -7,6 +7,9 @@ using CKAN.Versioning; using CKAN.Games; +#if NETSTANDARD2_0 +using CKAN.Extensions; +#endif namespace CKAN { diff --git a/Core/Relationships/SanityChecker.cs b/Core/Relationships/SanityChecker.cs index ab36d3fc20..0fb88eefe3 100644 --- a/Core/Relationships/SanityChecker.cs +++ b/Core/Relationships/SanityChecker.cs @@ -1,7 +1,11 @@ using System; using System.Collections.Generic; using System.Linq; + using CKAN.Versioning; +#if NETSTANDARD2_0 +using CKAN.Extensions; +#endif namespace CKAN { diff --git a/Core/Types/CkanModule.cs b/Core/Types/CkanModule.cs index b0211c3cd6..67272748c5 100644 --- a/Core/Types/CkanModule.cs +++ b/Core/Types/CkanModule.cs @@ -14,6 +14,9 @@ using CKAN.Versioning; using CKAN.Games; +#if NETSTANDARD2_0 +using CKAN.Extensions; +#endif namespace CKAN { diff --git a/Core/Types/License.cs b/Core/Types/License.cs index b618ac1132..3eb5a6a169 100644 --- a/Core/Types/License.cs +++ b/Core/Types/License.cs @@ -3,6 +3,10 @@ using Newtonsoft.Json; +#if NETSTANDARD2_0 +using CKAN.Extensions; +#endif + namespace CKAN { /// diff --git a/GUI/CKAN-GUI.csproj b/GUI/CKAN-GUI.csproj index beb157d9d6..ff39ae5f99 100644 --- a/GUI/CKAN-GUI.csproj +++ b/GUI/CKAN-GUI.csproj @@ -21,6 +21,7 @@ net48;net7.0-windows $(TargetFramework.Replace("-windows", "")) true + true 512 prompt 4 diff --git a/README.md b/README.md index 4fe9976302..815d5902f9 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,7 @@ It provides strong assurances that mods are installed in the way prescribed by t for the correct version of Kerbal Space Program, alongside their dependencies, and without any conflicting mods. CKAN is great for players _and_ for authors: + - players can find new content and install it with just a few clicks; - modders don't have to worry about misinstall problems or outdated versions; diff --git a/Tests/Core/Registry/CompatibilitySorter.cs b/Tests/Core/Registry/CompatibilitySorter.cs index 9a323aa109..49490db012 100644 --- a/Tests/Core/Registry/CompatibilitySorter.cs +++ b/Tests/Core/Registry/CompatibilitySorter.cs @@ -5,7 +5,9 @@ using CKAN; using CKAN.Versioning; +#if NET45 using CKAN.Extensions; +#endif using Tests.Data; diff --git a/build.cake b/build.cake index e42238b02c..c1ffd67ce5 100644 --- a/build.cake +++ b/build.cake @@ -15,6 +15,9 @@ var configuration = Argument("configuration", "Debug"); var solution = Argument("solution", "CKAN.sln"); var rootDirectory = Context.Environment.WorkingDirectory; +var coreProj = rootDirectory.Combine("Core") + .CombineWithFilePath("CKAN-core.csproj") + .FullPath; var buildDirectory = rootDirectory.Combine("_build"); var nugetDirectory = buildDirectory.Combine("lib") .Combine("nuget"); @@ -190,37 +193,11 @@ Task("Restore") .Description("Intermediate - Download dependencies") .Does(() => { - if (IsRunningOnWindows()) + DotNetRestore(solution, new DotNetRestoreSettings { - DotNetRestore(solution, new DotNetRestoreSettings - { - PackagesDirectory = nugetDirectory, - EnvironmentVariables = new Dictionary { { "Configuration", configuration } }, - }); - } - else - { - // NuGet is confused by multi-targeting, and - // Mono has no idea what "net7.0" is. Only restore for buildNetFramework. - DotNetRestore(solution, new DotNetRestoreSettings - { - PackagesDirectory = nugetDirectory, - EnvironmentVariables = new Dictionary { { "Configuration", configuration } }, - MSBuildSettings = new DotNetMSBuildSettings() - .SetConfiguration(configuration) - .WithProperty("TargetFramework", - buildNetFramework), - }); - DotNetRestore(solution, new DotNetRestoreSettings - { - PackagesDirectory = nugetDirectory, - EnvironmentVariables = new Dictionary { { "Configuration", "NoGUI" } }, - MSBuildSettings = new DotNetMSBuildSettings() - .SetConfiguration("NoGUI") - .WithProperty("TargetFramework", - "net7.0"), - }); - } + PackagesDirectory = nugetDirectory, + EnvironmentVariables = new Dictionary { { "Configuration", configuration } }, + }); }); Task("Build") @@ -241,15 +218,21 @@ Task("Build") } else { - // Mono has no idea what "net7.0" is + // Use dotnet to build the Core DLL to get the nupkg + // (only created if all TargetFrameworks are built together) + DotNetBuild(coreProj, new DotNetBuildSettings + { + Configuration = configuration, + }); + // Use Mono to build for net48 since dotnet can't use WinForms on Linux MSBuild(solution, settings => settings.SetConfiguration(configuration) .WithProperty("TargetFramework", buildNetFramework)); + // Use dotnet to build the stuff Mono can't build DotNetBuild(solution, new DotNetBuildSettings { Configuration = "NoGUI", - NoRestore = true, Framework = "net7.0", }); } @@ -296,7 +279,7 @@ Task("Repack-Ckan") .Combine(configuration) .Combine("bin") .Combine(buildNetFramework)))); - // Need netstandard.dll facade to instantiate types from ValveKeyValue on Mono + // Need facade to instantiate types from netstandard2.0 DLLs on Mono assemblyPaths.Add(FacadesDirectory().CombineWithFilePath("netstandard.dll")); var ckanLogFile = repackDirectory.Combine(configuration) .CombineWithFilePath($"ckan.log"); @@ -355,6 +338,8 @@ Task("Repack-Netkan") var netkanLogFile = repackDirectory.Combine(configuration) .CombineWithFilePath($"netkan.log"); var assemblyPaths = GetFiles(string.Format("{0}/*.dll", netkanBinDirectory)); + // Need facade to instantiate types from netstandard2.0 DLLs on Mono + assemblyPaths.Add(FacadesDirectory().CombineWithFilePath("netstandard.dll")); ReportRepacking(netkanFile, netkanLogFile); ILRepack( netkanFile, @@ -446,6 +431,7 @@ Task("Test-UnitTests+Only") { Configuration = configuration, NoBuild = true, + NoLogo = true, Filter = where, ResultsDirectory = nunitOutputDirectory, Verbosity = DotNetVerbosity.Minimal, @@ -456,7 +442,9 @@ Task("Test-UnitTests+Only") DotNetTest(solution, new DotNetTestSettings { Configuration = "NoGUI", + Framework = "net7.0", NoBuild = true, + NoLogo = true, Filter = where, ResultsDirectory = nunitOutputDirectory, Verbosity = DotNetVerbosity.Minimal, @@ -471,6 +459,7 @@ Task("Test-UnitTests+Only") Configuration = configuration, Where = where, Work = nunitOutputDirectory, + NoHeader = true, // Work around System.Runtime.Remoting.RemotingException : Tcp transport error. Process = NUnit3ProcessOption.InProcess, });