diff --git a/starsky/.config/dotnet-tools.json b/starsky/.config/dotnet-tools.json index 503753ada4..e972cfd37e 100644 --- a/starsky/.config/dotnet-tools.json +++ b/starsky/.config/dotnet-tools.json @@ -3,7 +3,7 @@ "isRoot": true, "tools": { "dotnet-sonarscanner": { - "version": "8.0.0", + "version": "8.0.3", "commands": [ "dotnet-sonarscanner" ], diff --git a/starsky/.nuke/build.schema.json b/starsky/.nuke/build.schema.json index 26ccbe899d..e6e958e3f6 100644 --- a/starsky/.nuke/build.schema.json +++ b/starsky/.nuke/build.schema.json @@ -1,23 +1,111 @@ { "$schema": "http://json-schema.org/draft-04/schema#", - "$ref": "#/definitions/build", - "title": "Build Schema", + "properties": { + "Branch": { + "type": "string", + "description": "Overwrite branch name" + }, + "Configuration": { + "type": "string", + "description": "Configuration to build - Default is 'Debug' (local) or 'Release' (server)", + "enum": [ + "Debug", + "Release" + ] + }, + "NoClient": { + "type": "boolean", + "description": "Skip clientside code" + }, + "NoDependencies": { + "type": "boolean", + "description": "Skip Dependencies download e.g. exiftool / geo data, nuget/npm deps are always installed" + }, + "NoPublish": { + "type": "boolean", + "description": "Skip Publish step" + }, + "NoSonar": { + "type": "boolean", + "description": "Is SonarQube Disabled" + }, + "NoTest": { + "type": "boolean", + "description": "Is Unit Test Disabled (same as NoUnitTest, NoUnitTests, NoTest and NoTests)" + }, + "NoTests": { + "type": "boolean", + "description": "Is Unit Test Disabled (same as NoUnitTest, NoUnitTests, NoTest and NoTests)" + }, + "NoUnitTest": { + "type": "boolean", + "description": "Is Unit Test Disabled (same as NoUnitTest, NoUnitTests, NoTest and NoTests)" + }, + "NoUnitTests": { + "type": "boolean", + "description": "Is Unit Test Disabled (same as NoUnitTest, NoUnitTests, NoTest and NoTests)" + }, + "ReadyToRun": { + "type": "boolean", + "description": "Enable Ready to run builds" + }, + "Runtime": { + "type": "string", + "description": "Runtime arg" + }, + "Solution": { + "type": "string", + "description": "Path to a solution file that is automatically loaded" + } + }, "definitions": { - "build": { - "type": "object", + "Host": { + "type": "string", + "enum": [ + "AppVeyor", + "AzurePipelines", + "Bamboo", + "Bitbucket", + "Bitrise", + "GitHubActions", + "GitLab", + "Jenkins", + "Rider", + "SpaceAutomation", + "TeamCity", + "Terminal", + "TravisCI", + "VisualStudio", + "VSCode" + ] + }, + "ExecutableTarget": { + "type": "string", + "enum": [ + "BuildNetCore", + "BuildNetCoreRuntimeSpecific", + "Client", + "Compile", + "CoverageReport", + "DownloadDependencies", + "ShowSettingsInformation", + "SonarBuildTest", + "TestNetCore", + "Zip" + ] + }, + "Verbosity": { + "type": "string", + "description": "", + "enum": [ + "Verbose", + "Normal", + "Minimal", + "Quiet" + ] + }, + "NukeBuild": { "properties": { - "Branch": { - "type": "string", - "description": "Overwrite branch name" - }, - "Configuration": { - "type": "string", - "description": "Configuration to build - Default is 'Debug' (local) or 'Release' (server)", - "enum": [ - "Debug", - "Release" - ] - }, "Continue": { "type": "boolean", "description": "Indicates to continue a previously failed build attempt" @@ -27,62 +115,13 @@ "description": "Shows the help text for this build assembly" }, "Host": { - "type": "string", "description": "Host for execution. Default is 'automatic'", - "enum": [ - "AppVeyor", - "AzurePipelines", - "Bamboo", - "Bitbucket", - "Bitrise", - "GitHubActions", - "GitLab", - "Jenkins", - "Rider", - "SpaceAutomation", - "TeamCity", - "Terminal", - "TravisCI", - "VisualStudio", - "VSCode" - ] - }, - "NoClient": { - "type": "boolean", - "description": "Skip clientside code" - }, - "NoDependencies": { - "type": "boolean", - "description": "Skip Dependencies download e.g. exiftool / geo data, nuget/npm deps are always installed" + "$ref": "#/definitions/Host" }, "NoLogo": { "type": "boolean", "description": "Disables displaying the NUKE logo" }, - "NoPublish": { - "type": "boolean", - "description": "Skip Publish step" - }, - "NoSonar": { - "type": "boolean", - "description": "Is SonarQube Disabled" - }, - "NoTest": { - "type": "boolean", - "description": "Is Unit Test Disabled (same as NoUnitTest, NoUnitTests, NoTest and NoTests)" - }, - "NoTests": { - "type": "boolean", - "description": "Is Unit Test Disabled (same as NoUnitTest, NoUnitTests, NoTest and NoTests)" - }, - "NoUnitTest": { - "type": "boolean", - "description": "Is Unit Test Disabled (same as NoUnitTest, NoUnitTests, NoTest and NoTests)" - }, - "NoUnitTests": { - "type": "boolean", - "description": "Is Unit Test Disabled (same as NoUnitTest, NoUnitTests, NoTest and NoTests)" - }, "Partition": { "type": "string", "description": "Partition to use on CI" @@ -98,71 +137,30 @@ "type": "string" } }, - "ReadyToRun": { - "type": "boolean", - "description": "Enable Ready to run builds" - }, "Root": { "type": "string", "description": "Root directory during build execution" }, - "Runtime": { - "type": "string", - "description": "Runtime arg" - }, "Skip": { "type": "array", "description": "List of targets to be skipped. Empty list skips all dependencies", "items": { - "type": "string", - "enum": [ - "BuildNetCore", - "BuildNetCoreRuntimeSpecific", - "Client", - "Compile", - "CoverageReport", - "DownloadDependencies", - "ShowSettingsInformation", - "SonarBuildTest", - "TestNetCore", - "Zip" - ] + "$ref": "#/definitions/ExecutableTarget" } }, - "Solution": { - "type": "string", - "description": "Path to a solution file that is automatically loaded" - }, "Target": { "type": "array", "description": "List of targets to be invoked. Default is '{default_target}'", "items": { - "type": "string", - "enum": [ - "BuildNetCore", - "BuildNetCoreRuntimeSpecific", - "Client", - "Compile", - "CoverageReport", - "DownloadDependencies", - "ShowSettingsInformation", - "SonarBuildTest", - "TestNetCore", - "Zip" - ] + "$ref": "#/definitions/ExecutableTarget" } }, "Verbosity": { - "type": "string", "description": "Logging verbosity during build execution. Default is 'Normal'", - "enum": [ - "Minimal", - "Normal", - "Quiet", - "Verbose" - ] + "$ref": "#/definitions/Verbosity" } } } - } + }, + "$ref": "#/definitions/NukeBuild" } diff --git a/starsky/build/Constants/ReadyToRunSupportedPlatforms.cs b/starsky/build/Constants/ReadyToRunSupportedPlatforms.cs index 64dac40a49..492f9664ae 100644 --- a/starsky/build/Constants/ReadyToRunSupportedPlatforms.cs +++ b/starsky/build/Constants/ReadyToRunSupportedPlatforms.cs @@ -6,23 +6,23 @@ namespace Constants; public static class ReadyToRunSupportedPlatforms { /// - /// SDK-platform Supported target platforms - /// Windows X64 Windows (X86, X64, Arm64), Linux (X64, Arm32, Arm64), macOS (X64, Arm64) - /// win-x64 - supports: win-x86, win-x64, win-arm64, linux-x64, linux-arm, linux-arm64, osx-x64, osx-arm64 - /// Windows X86 Windows (X86), Linux (Arm32) - /// win-x86 - supports: win-x86, linux-arm - /// Linux X64 Linux (X64, Arm32, Arm64), macOS (X64, Arm64) - /// linux-x64 - supports linux-x64, linux-arm, linux-arm64, osx-x64, osx-arm64 - /// Linux Arm32 Linux Arm32 - /// linux-arm, supports linux-arm - /// Linux Arm64 Linux (X64, Arm32, Arm64), macOS (X64, Arm64) - /// linux-arm64 supports linux-x64, linux-arm, linux-arm64, osx-x64, osx-arm64 - /// macOS X64 Linux (X64, Arm32, Arm64), macOS (X64, Arm64) - /// osx-x64 supports linux-x64, linux-arm, linux-arm64, osx-x64, osx-arm64 - /// macOS Arm64 Linux (X64, Arm32, Arm64), macOS (X64, Arm64) - /// osx-arm64 supports linux-x64, linux-arm, linux-arm64, osx-x64, osx-arm64 - /// - /// @see: https://learn.microsoft.com/en-us/dotnet/core/deploying/ready-to-run + /// SDK-platform Supported target platforms + /// Windows X64 Windows (X86, X64, Arm64), Linux (X64, Arm32, Arm64), macOS (X64, Arm64) + /// win-x64 - supports: win-x86, win-x64, win-arm64, linux-x64, linux-arm, linux-arm64, osx-x64, + /// osx-arm64 + /// Windows X86 Windows (X86), Linux (Arm32) + /// win-x86 - supports: win-x86, linux-arm + /// Linux X64 Linux (X64, Arm32, Arm64), macOS (X64, Arm64) + /// linux-x64 - supports linux-x64, linux-arm, linux-arm64, osx-x64, osx-arm64 + /// Linux Arm32 Linux Arm32 + /// linux-arm, supports linux-arm + /// Linux Arm64 Linux (X64, Arm32, Arm64), macOS (X64, Arm64) + /// linux-arm64 supports linux-x64, linux-arm, linux-arm64, osx-x64, osx-arm64 + /// macOS X64 Linux (X64, Arm32, Arm64), macOS (X64, Arm64) + /// osx-x64 supports linux-x64, linux-arm, linux-arm64, osx-x64, osx-arm64 + /// macOS Arm64 Linux (X64, Arm32, Arm64), macOS (X64, Arm64) + /// osx-arm64 supports linux-x64, linux-arm, linux-arm64, osx-x64, osx-arm64 + /// @see: https://learn.microsoft.com/en-us/dotnet/core/deploying/ready-to-run /// public static readonly ImmutableDictionary> SupportedPlatforms = new Dictionary> diff --git a/starsky/build/_build.csproj b/starsky/build/_build.csproj index 80dfd2ff5f..6636a618d2 100644 --- a/starsky/build/_build.csproj +++ b/starsky/build/_build.csproj @@ -14,10 +14,10 @@ - + - - + + diff --git a/starsky/build/helpers/ClientHelper.cs b/starsky/build/helpers/ClientHelper.cs index e77799d366..0e46a0c7f4 100644 --- a/starsky/build/helpers/ClientHelper.cs +++ b/starsky/build/helpers/ClientHelper.cs @@ -4,51 +4,44 @@ using static SimpleExec.Command; using static build.Build; -namespace helpers -{ +namespace helpers; - public static class ClientHelper +public static class ClientHelper +{ + public static string GetClientAppFolder() { - public static string GetClientAppFolder() + var baseDirectory = AppDomain.CurrentDomain + .BaseDirectory; + if ( baseDirectory == null ) { - var baseDirectory = AppDomain.CurrentDomain - .BaseDirectory; - if ( baseDirectory == null ) - { - throw new DirectoryNotFoundException("base directory is null, this is wrong"); - } - - var rootDirectory = Directory.GetParent(baseDirectory)?.Parent?.Parent?.Parent?.FullName; - if ( rootDirectory == null ) - { - throw new DirectoryNotFoundException("rootDirectory is null, this is wrong"); - } - - return Path.Combine(rootDirectory, ClientAppFolder); + throw new DirectoryNotFoundException("base directory is null, this is wrong"); } - public static void NpmPreflight() + var rootDirectory = Directory.GetParent(baseDirectory)?.Parent?.Parent?.Parent?.FullName; + if ( rootDirectory == null ) { - Log.Information("Checking if Npm (and implicit: Node) is installed, will fail if not on this step"); - Run(NpmBaseCommand, "-v"); - - Log.Information("Checking if Node is installed, will fail if not on this step"); - Run(NodeBaseCommand, "-v"); + throw new DirectoryNotFoundException("rootDirectory is null, this is wrong"); } - public static void ClientCiCommand() - { - Run(NpmBaseCommand, "ci --legacy-peer-deps --prefer-offline --no-audit --no-fund", GetClientAppFolder()); - } + return Path.Combine(rootDirectory, ClientAppFolder); + } - public static void ClientBuildCommand() - { - Run(NpmBaseCommand, "run build", GetClientAppFolder()); - } + public static void NpmPreflight() + { + Log.Information( + "Checking if Npm (and implicit: Node) is installed, will fail if not on this step"); + Run(NpmBaseCommand, "-v"); - public static void ClientTestCommand() - { - Run(NpmBaseCommand, "run test:ci", GetClientAppFolder()); - } + Log.Information("Checking if Node is installed, will fail if not on this step"); + Run(NodeBaseCommand, "-v"); } + + public static void ClientCiCommand() => Run(NpmBaseCommand, + "ci --legacy-peer-deps --prefer-offline --no-audit --no-fund", GetClientAppFolder()); + + public static void ClientBuildCommand() => + Run(NpmBaseCommand, "run build", GetClientAppFolder()); + + public static void ClientTestCommand() => + Run(NpmBaseCommand, "run test:ci", GetClientAppFolder()); } diff --git a/starsky/build/helpers/CoverageReportHelper.cs b/starsky/build/helpers/CoverageReportHelper.cs index 4e107f02f6..f7f4f8a014 100644 --- a/starsky/build/helpers/CoverageReportHelper.cs +++ b/starsky/build/helpers/CoverageReportHelper.cs @@ -1,51 +1,48 @@ using System; using System.IO; +using Palmmedia.ReportGenerator.Core; using Serilog; -namespace helpers +namespace helpers; + +public static class CoverageReportHelper { - public static class CoverageReportHelper + static void Information(string value) => Log.Information(value); + + public static string? GenerateHtml(bool noUnitTest) { - static void Information(string value) + if ( noUnitTest ) { - Log.Information(value); + Information(">> MergeCoverageFiles is disable due the --no-unit-test flag"); + return null; } - public static string? GenerateHtml(bool noUnitTest) - { - if ( noUnitTest ) - { - Information(">> MergeCoverageFiles is disable due the --no-unit-test flag"); - return null; - } - - Information(">> Next: MergeCoverageFiles "); + Information(">> Next: MergeCoverageFiles "); - var rootDirectory = Directory.GetParent(AppDomain.CurrentDomain - .BaseDirectory)!.Parent!.Parent!.Parent!.FullName; - var outputCoverageFile = Path.Combine(rootDirectory, - "./starskytest/coverage-merge-cobertura.xml"); + var rootDirectory = Directory.GetParent(AppDomain.CurrentDomain + .BaseDirectory)!.Parent!.Parent!.Parent!.FullName; + var outputCoverageFile = Path.Combine(rootDirectory, + "./starskytest/coverage-merge-cobertura.xml"); - var reportFolder = - outputCoverageFile.Replace("merge-cobertura.xml", "report"); + var reportFolder = + outputCoverageFile.Replace("merge-cobertura.xml", "report"); - if ( !File.Exists(outputCoverageFile) ) - { - throw new FileNotFoundException( - $"Missing .NET Core coverage file {outputCoverageFile}"); - } + if ( !File.Exists(outputCoverageFile) ) + { + throw new FileNotFoundException( + $"Missing .NET Core coverage file {outputCoverageFile}"); + } - var args = new[] - { - $"-reports:{outputCoverageFile}", $"-targetdir:{reportFolder}", - "-reporttypes:HtmlInline" - }; + var args = new[] + { + $"-reports:{outputCoverageFile}", $"-targetdir:{reportFolder}", + "-reporttypes:HtmlInline" + }; - Palmmedia.ReportGenerator.Core.Program.Main(args); + Program.Main(args); - Information(">> ReportGenerator done"); + Information(">> ReportGenerator done"); - return reportFolder; - } + return reportFolder; } } diff --git a/starsky/build/helpers/DotnetGenericHelper.cs b/starsky/build/helpers/DotnetGenericHelper.cs index 0f4b9a36d8..ebc1008c1f 100644 --- a/starsky/build/helpers/DotnetGenericHelper.cs +++ b/starsky/build/helpers/DotnetGenericHelper.cs @@ -8,125 +8,124 @@ using static Nuke.Common.Tools.DotNet.DotNetTasks; using static build.Build; -namespace helpers +namespace helpers; + +[SuppressMessage("Sonar", + "S6664: Reduce the number of Information logging calls within this code block", + Justification = "Not production code.")] +public static class DotnetGenericHelper { - [SuppressMessage("Sonar", - "S6664: Reduce the number of Information logging calls within this code block", - Justification = "Not production code.")] - public static class DotnetGenericHelper + /// + /// dotnet restore for generic + /// + /// solution file .sln + public static void RestoreNetCoreCommand(Solution solution) { - /// - /// dotnet restore for generic - /// - /// solution file .sln - public static void RestoreNetCoreCommand(Solution solution) - { - Log.Information("dotnet restore: solution: {Solution}", solution); + Log.Information("dotnet restore: solution: {Solution}", solution); - DotNetRestore(p => p - .SetProjectFile(solution.Path) - ); + DotNetRestore(p => p + .SetProjectFile(solution.Path) + ); + } + + /// + /// dotnet build for generic helper + /// + /// the solution + /// Debug or Release + public static void BuildNetCoreGenericCommand(Solution solution, + Configuration configuration) + { + DotNetBuild(p => p + .SetConfiguration(configuration) + .EnableNoRestore() + .EnableNoLogo() + .SetProjectFile(solution)); + } + + /// + /// Download Exiftool and geo deps + /// + /// is Release + /// geo.csproj file + /// skip this step if true (external deps) + /// genericNetcoreFolder + public static void DownloadDependencies(Configuration configuration, + string geoCliCsproj, bool noDependencies, + string genericNetcoreFolder) + { + if ( noDependencies ) + { + Log.Information("skip the flag: --no-dependencies is used"); + return; } - /// - /// dotnet build for generic helper - /// - /// the solution - /// Debug or Release - public static void BuildNetCoreGenericCommand(Solution solution, - Configuration configuration) + var genericDepsFullPath = + Path.Combine(BasePath(), genericNetcoreFolder, "dependencies"); + Log.Information("genericDepsFullPath: {GenericDepsFullPath}", genericDepsFullPath); + + try { - DotNetBuild(p => p + Environment.SetEnvironmentVariable("app__DependenciesFolder", genericDepsFullPath); + Log.Information("Next: DownloadDependencies"); + Log.Information("Run: {Path}", Path.Combine( + WorkingDirectory.GetSolutionParentFolder(), geoCliCsproj) + ); + + DotNetRun(p => p .SetConfiguration(configuration) .EnableNoRestore() - .EnableNoLogo() - .SetProjectFile(solution)); + .EnableNoBuild() + .SetApplicationArguments("--runtime linux-x64,win-x64") + .SetProjectFile(Path.Combine(WorkingDirectory.GetSolutionParentFolder(), + geoCliCsproj))); } - - /// - /// Download Exiftool and geo deps - /// - /// is Release - /// geo.csproj file - /// skip this step if true (external deps) - /// genericNetcoreFolder - public static void DownloadDependencies(Configuration configuration, - string geoCliCsproj, bool noDependencies, - string genericNetcoreFolder) + catch ( Exception exception ) { - if ( noDependencies ) - { - Log.Information("skip the flag: --no-dependencies is used"); - return; - } - - var genericDepsFullPath = - Path.Combine(BasePath(), genericNetcoreFolder, "dependencies"); - Log.Information("genericDepsFullPath: {GenericDepsFullPath}", genericDepsFullPath); - - try - { - Environment.SetEnvironmentVariable("app__DependenciesFolder", genericDepsFullPath); - Log.Information("Next: DownloadDependencies"); - Log.Information("Run: {Path}", Path.Combine( - WorkingDirectory.GetSolutionParentFolder(), geoCliCsproj) - ); + Log.Information("--"); + Log.Information(exception.Message); + Log.Information("-- continue"); + } - DotNetRun(p => p - .SetConfiguration(configuration) - .EnableNoRestore() - .EnableNoBuild() - .SetApplicationArguments("--runtime linux-x64,win-x64") - .SetProjectFile(Path.Combine(WorkingDirectory.GetSolutionParentFolder(), - geoCliCsproj))); - } - catch ( Exception exception ) - { - Log.Information("--"); - Log.Information(exception.Message); - Log.Information("-- continue"); - } + Environment.SetEnvironmentVariable("app__DependenciesFolder", string.Empty); - Environment.SetEnvironmentVariable("app__DependenciesFolder", string.Empty); + Log.Information(" genericDepsFullPath: {GenericDepsFullPath}", genericDepsFullPath); + Log.Information("DownloadDependencies done"); + } - Log.Information(" genericDepsFullPath: {GenericDepsFullPath}", genericDepsFullPath); - Log.Information("DownloadDependencies done"); + public static void PublishNetCoreGenericCommand(Configuration configuration, + bool isPublishDisabled) + { + if ( isPublishDisabled ) + { + Log.Information("Skip: PublishNetCoreGenericCommand isPublishDisabled"); + return; } - public static void PublishNetCoreGenericCommand(Configuration configuration, - bool isPublishDisabled) + foreach ( var publishProject in PublishProjectsList ) { - if ( isPublishDisabled ) - { - Log.Information("Skip: PublishNetCoreGenericCommand isPublishDisabled"); - return; - } - - foreach ( var publishProject in PublishProjectsList ) - { - var publishProjectFullPath = Path.Combine( - WorkingDirectory.GetSolutionParentFolder(), - publishProject); + var publishProjectFullPath = Path.Combine( + WorkingDirectory.GetSolutionParentFolder(), + publishProject); - var outputFullPath = Path.Combine( - WorkingDirectory.GetSolutionParentFolder(), - GenericRuntimeName); + var outputFullPath = Path.Combine( + WorkingDirectory.GetSolutionParentFolder(), + GenericRuntimeName); - DotNetPublish(p => p - .SetConfiguration(configuration) - .EnableNoRestore() - .EnableNoBuild() - .EnableNoDependencies() - .SetOutput(outputFullPath) - .SetProject(publishProjectFullPath) - .EnableNoLogo()); - } + DotNetPublish(p => p + .SetConfiguration(configuration) + .EnableNoRestore() + .EnableNoBuild() + .EnableNoDependencies() + .SetOutput(outputFullPath) + .SetProject(publishProjectFullPath) + .EnableNoLogo()); } + } - static string BasePath() - { - return Directory.GetParent(AppDomain.CurrentDomain.BaseDirectory) - ?.Parent?.Parent?.Parent?.FullName!; - } + static string BasePath() + { + return Directory.GetParent(AppDomain.CurrentDomain.BaseDirectory) + ?.Parent?.Parent?.Parent?.FullName!; } } diff --git a/starsky/build/helpers/DotnetRuntimeSpecificHelper.cs b/starsky/build/helpers/DotnetRuntimeSpecificHelper.cs index 5d9dea7a4f..ec6f3065b3 100644 --- a/starsky/build/helpers/DotnetRuntimeSpecificHelper.cs +++ b/starsky/build/helpers/DotnetRuntimeSpecificHelper.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.IO; +using System.Runtime.InteropServices; using System.Text.RegularExpressions; using build; using Nuke.Common.IO; @@ -11,199 +12,198 @@ using Serilog; using static Nuke.Common.Tools.DotNet.DotNetTasks; -namespace helpers +namespace helpers; + +/// +/// use --skip to run only this test +/// +[SuppressMessage("Sonar", + "S2629: Don't use string interpolation in logging message templates", + Justification = "Not production code.")] +public static class DotnetRuntimeSpecificHelper { - /// - /// use --skip to run only this test - /// - [SuppressMessage("Sonar", - "S2629: Don't use string interpolation in logging message templates", - Justification = "Not production code.")] - public static class DotnetRuntimeSpecificHelper + static string BasePath() => + Directory.GetParent(AppDomain.CurrentDomain.BaseDirectory) + ?.Parent?.Parent?.Parent?.FullName!; + + public static void Clean(List runtimesWithoutGeneric) { - static string BasePath() + if ( runtimesWithoutGeneric.Count == 0 ) { - return Directory.GetParent(AppDomain.CurrentDomain.BaseDirectory) - ?.Parent?.Parent?.Parent?.FullName!; + return; } - public static void Clean(List runtimesWithoutGeneric) + Log.Information("Next: Clean up the folder and zip files"); + + foreach ( var runtime in runtimesWithoutGeneric ) { - if ( runtimesWithoutGeneric.Count == 0 ) + var runtimeZip = $"{ZipperHelper.ZipPrefix}{runtime}.zip"; + + Log.Information("\tRuntimeZip: " + runtimeZip + " exists: " + + File.Exists(runtimeZip)); + if ( File.Exists(runtimeZip) ) + { + File.Delete(runtimeZip); + } + + if ( Directory.Exists(Path.Combine(BasePath(), runtime)) ) + { + Log.Information($"\tnext rm folder - {Path.Combine(BasePath(), runtime)}"); + Directory.Delete(Path.Combine(BasePath(), runtime), true); + } + else { - return; + Log.Information( + $"\tskip folder due not exists - {Path.Combine(BasePath(), runtime)}"); } - Log.Information("Next: Clean up the folder and zip files"); + // get current netMoniker + var version = RuntimeInformation + .FrameworkDescription; + var netMoniker = + new Regex(".\\d+$", RegexOptions.None, TimeSpan.FromMilliseconds(100)) + .Replace(version, string.Empty).Replace(".NET ", "net"); + // e.g net6.0 or net8.0 - foreach ( var runtime in runtimesWithoutGeneric ) + if ( Directory.Exists($"obj/Release/{netMoniker}/{runtime}") ) + { + Log.Information($"\tNext: remove -> obj/Release/{netMoniker}/{runtime}"); + Directory.Delete($"obj/Release/{netMoniker}/{runtime}", true); + } + else { - var runtimeZip = $"{ZipperHelper.ZipPrefix}{runtime}.zip"; - - Log.Information("\tRuntimeZip: " + runtimeZip + " exists: " + - File.Exists(runtimeZip)); - if ( File.Exists(runtimeZip) ) - { - File.Delete(runtimeZip); - } - - if ( Directory.Exists(Path.Combine(BasePath(), runtime)) ) - { - Log.Information($"\tnext rm folder - {Path.Combine(BasePath(), runtime)}"); - Directory.Delete(Path.Combine(BasePath(), runtime), true); - } - else - { - Log.Information( - $"\tskip folder due not exists - {Path.Combine(BasePath(), runtime)}"); - } - - // get current netMoniker - var version = System.Runtime.InteropServices.RuntimeInformation - .FrameworkDescription; - var netMoniker = - new Regex(".\\d+$", RegexOptions.None, TimeSpan.FromMilliseconds(100)) - .Replace(version, string.Empty).Replace(".NET ", "net"); - // e.g net6.0 or net8.0 - - if ( Directory.Exists($"obj/Release/{netMoniker}/{runtime}") ) - { - Log.Information($"\tNext: remove -> obj/Release/{netMoniker}/{runtime}"); - Directory.Delete($"obj/Release/{netMoniker}/{runtime}", true); - } - else - { - Log.Information( - $"\tfolder is not removed -> obj/Release/{netMoniker}/{runtime}"); - } + Log.Information( + $"\tfolder is not removed -> obj/Release/{netMoniker}/{runtime}"); } + } + + Log.Information("Clean up done"); + } - Log.Information("Clean up done"); + public static void CopyDependenciesFiles(bool noDependencies, + string genericNetcoreFolder, List getRuntimesWithoutGeneric) + { + if ( noDependencies || string.IsNullOrWhiteSpace(genericNetcoreFolder) ) + { + return; } - public static void CopyDependenciesFiles(bool noDependencies, - string genericNetcoreFolder, List getRuntimesWithoutGeneric) + var genericTempFolderFullPath = + Path.Combine(BasePath(), genericNetcoreFolder, "dependencies"); + foreach ( var runtime in getRuntimesWithoutGeneric ) { - if ( noDependencies || string.IsNullOrWhiteSpace(genericNetcoreFolder) ) + var runtimeTempFolder = Path.Combine(BasePath(), runtime, "dependencies"); + + AbsolutePath.Create(genericTempFolderFullPath).Copy( + AbsolutePath.Create(runtimeTempFolder), + ExistsPolicy.FileOverwrite, createDirectories: true); + + // For Windows, it's not needed to copy unix dependencies + if ( runtime.StartsWith("win") && + Directory.Exists(Path.Combine(runtimeTempFolder, "exiftool-unix")) ) { - return; + Directory.Delete(Path.Combine(runtimeTempFolder, "exiftool-unix"), true); + Log.Information("removed exiftool-unix for windows"); } - var genericTempFolderFullPath = - Path.Combine(BasePath(), genericNetcoreFolder, "dependencies"); - foreach ( var runtime in getRuntimesWithoutGeneric ) + // ReSharper disable once InvertIf + if ( runtime.StartsWith("win") && + File.Exists(Path.Combine(runtimeTempFolder, "exiftool.tar.gz")) ) { - var runtimeTempFolder = Path.Combine(BasePath(), runtime, "dependencies"); - FileSystemTasks.CopyDirectoryRecursively(genericTempFolderFullPath, - runtimeTempFolder, DirectoryExistsPolicy.Merge, FileExistsPolicy.Overwrite); - - // For Windows its not needed to copy unix dependencies - if ( runtime.StartsWith("win") && - Directory.Exists(Path.Combine(runtimeTempFolder, "exiftool-unix")) ) - { - Directory.Delete(Path.Combine(runtimeTempFolder, "exiftool-unix"), true); - Log.Information("removed exiftool-unix for windows"); - } - - // ReSharper disable once InvertIf - if ( runtime.StartsWith("win") && - File.Exists(Path.Combine(runtimeTempFolder, "exiftool.tar.gz")) ) - { - File.Delete(Path.Combine(runtimeTempFolder, "exiftool.tar.gz")); - Log.Information("removed exiftool.tar.gz for windows"); - } + File.Delete(Path.Combine(runtimeTempFolder, "exiftool.tar.gz")); + Log.Information("removed exiftool.tar.gz for windows"); } } + } + + /// + /// Specific build for runtime + /// Runs the command: dotnet build + /// + /// the solution file (sln) + /// Config file + /// which runtime e.g. linux-arm or osx-x64 + /// Is Ready To Run Enabled + public static void BuildNetCoreCommand(Solution solution, Configuration + configuration, string runtime, bool isReadyToRunEnabled) + { + Log.Information("> dotnet build next for: solution: " + solution + " runtime: " + + runtime); + + var readyToRunArgument = + RuntimeIdentifier.IsReadyToRunSupported(runtime) && isReadyToRunEnabled + ? "-p:PublishReadyToRun=true" + : ""; + + DotNetBuild(p => p + .SetProjectFile(solution) + // Implicit restore here, since .NET 8 self-contained is disabled + // in dotnet restore and there a no options to enable it + .EnableNoLogo() + .DisableRunCodeAnalysis() + .EnableSelfContained() + .SetConfiguration(configuration) + .SetProcessArgumentConfigurator(args => + args + // OverwriteRuntimeIdentifier is done via Directory.Build.props + // Building a solution with a specific RuntimeIdentifier is not supported + // Don't use SetRuntime + .Add($"/p:OverwriteRuntimeIdentifier={runtime}") + // Warnings are disabled because in Generic build they are already checked + .Add("-v q") + .Add("/p:WarningLevel=0") + // SonarQube analysis is done in the generic build + .Add("/p:noSonar=true") + .Add(readyToRunArgument) + )); + } - /// - /// Specific build for runtime - /// Runs the command: dotnet build - /// - /// the solution file (sln) - /// Config file - /// which runtime e.g. linux-arm or osx-x64 - /// Is Ready To Run Enabled - public static void BuildNetCoreCommand(Solution solution, Configuration - configuration, string runtime, bool isReadyToRunEnabled) + /// + /// Runs the command: dotnet publish + /// For RuntimeSpecific + /// + /// Release + /// runtime identifier + /// Is Ready To Run Enabled + public static void PublishNetCoreGenericCommand(Configuration configuration, + string runtime, bool isReadyToRunEnabled) + { + foreach ( var publishProject in Build.PublishProjectsList ) { - Log.Information("> dotnet build next for: solution: " + solution + " runtime: " + - runtime); + Log.Information(">> next publishProject: " + + publishProject + " runtime: " + runtime); + + var publishProjectFullPath = Path.Combine( + WorkingDirectory.GetSolutionParentFolder(), + publishProject); + + var outputFullPath = Path.Combine( + WorkingDirectory.GetSolutionParentFolder(), + runtime); var readyToRunArgument = - RuntimeIdentifier.IsReadyToRunSupported(runtime) && isReadyToRunEnabled + RuntimeIdentifier.IsReadyToRunSupported(runtime) && + isReadyToRunEnabled && + Build.ReadyToRunProjectsList.Contains(publishProject) ? "-p:PublishReadyToRun=true" : ""; - DotNetBuild(p => p - .SetProjectFile(solution) - // Implicit restore here, since .NET 8 self contained is disabled - // in dotnet restore and there a no options to enable it - .EnableNoLogo() - .DisableRunCodeAnalysis() - .EnableSelfContained() + DotNetPublish(p => p .SetConfiguration(configuration) + .EnableNoRestore() + .EnableNoBuild() + .EnableNoDependencies() + .EnableSelfContained() + .SetOutput(outputFullPath) + .SetProject(publishProjectFullPath) + .SetRuntime(runtime) + .EnableNoLogo() .SetProcessArgumentConfigurator(args => - args - // OverwriteRuntimeIdentifier is done via Directory.Build.props - // Building a solution with a specific RuntimeIdentifier is not supported - // Dont use SetRuntime + args.Add("/p:noSonar=true") .Add($"/p:OverwriteRuntimeIdentifier={runtime}") - // Warnings are disabled because in Generic build they are already checked - .Add("-v q") - .Add("/p:WarningLevel=0") - // SonarQube analysis is done in the generic build - .Add("/p:noSonar=true") .Add(readyToRunArgument) - )); - } - - /// - /// Runs the command: dotnet publish - /// For RuntimeSpecific - /// - /// Release - /// runtime identifier - /// Is Ready To Run Enabled - public static void PublishNetCoreGenericCommand(Configuration configuration, - string runtime, bool isReadyToRunEnabled) - { - foreach ( var publishProject in Build.PublishProjectsList ) - { - Log.Information(">> next publishProject: " + - publishProject + " runtime: " + runtime); - - var publishProjectFullPath = Path.Combine( - WorkingDirectory.GetSolutionParentFolder(), - publishProject); - - var outputFullPath = Path.Combine( - WorkingDirectory.GetSolutionParentFolder(), - runtime); - - var readyToRunArgument = - RuntimeIdentifier.IsReadyToRunSupported(runtime) && - isReadyToRunEnabled && - Build.ReadyToRunProjectsList.Contains(publishProject) - ? "-p:PublishReadyToRun=true" - : ""; - - DotNetPublish(p => p - .SetConfiguration(configuration) - .EnableNoRestore() - .EnableNoBuild() - .EnableNoDependencies() - .EnableSelfContained() - .SetOutput(outputFullPath) - .SetProject(publishProjectFullPath) - .SetRuntime(runtime) - .EnableNoLogo() - .SetProcessArgumentConfigurator(args => - args.Add("/p:noSonar=true") - .Add($"/p:OverwriteRuntimeIdentifier={runtime}") - .Add(readyToRunArgument) - ) - ); - } + ) + ); } } } diff --git a/starsky/build/helpers/DotnetTestHelper.cs b/starsky/build/helpers/DotnetTestHelper.cs index 04556c39c2..5bcb6061b4 100644 --- a/starsky/build/helpers/DotnetTestHelper.cs +++ b/starsky/build/helpers/DotnetTestHelper.cs @@ -5,111 +5,110 @@ using Nuke.Common.Tooling; using Nuke.Common.Tools.DotNet; using Serilog; -using static Nuke.Common.IO.FileSystemTasks; using static Nuke.Common.Tools.DotNet.DotNetTasks; -namespace helpers +namespace helpers; + +[SuppressMessage("Sonar", + "S6664: Reduce the number of Information logging calls within this code block", + Justification = "Not production code.")] +public static class DotnetTestHelper { - [SuppressMessage("Sonar", - "S6664: Reduce the number of Information logging calls within this code block", - Justification = "Not production code.")] - public static class DotnetTestHelper + static bool DirectoryExists(string path) + { + return Directory.Exists(path); + } + + public static void TestNetCoreGenericCommand(Configuration configuration, bool noUnitTest) { - static bool DirectoryExists(string path) + Log.Information(">> next: TestNetCoreGenericCommand"); + + if ( noUnitTest ) { - return Directory.Exists(path); + Log.Information(">> TestNetCore is disable due the --no-unit-test flag"); + return; } - public static void TestNetCoreGenericCommand(Configuration configuration, bool noUnitTest) + var projects = GetFilesHelper.GetFiles("*test/*.csproj"); + if ( projects.Count == 0 ) { - Log.Information(">> next: TestNetCoreGenericCommand"); + throw new FileNotFoundException("missing tests in *test/*.csproj"); + } + + foreach ( var project in projects ) + { + var projectFullPath = Path.Combine(WorkingDirectory.GetSolutionParentFolder(), + project); + Log.Information("Testing project {Project}", project); + + var testParentPath = Directory.GetParent(projectFullPath)?.FullName!; + Log.Information("testParentPath {TestParentPath} ", testParentPath); + + /* clean test results */ + var testResultsFolder = Path.Combine(testParentPath, "TestResults"); + if ( DirectoryExists(testResultsFolder) ) + { + Log.Information(">> Removing folder => {TestResultsFolder}", testResultsFolder); + Directory.Delete(testResultsFolder, true); + } + + var runSettingsFile = Path.Combine( + WorkingDirectory.GetSolutionParentFolder(), "build.vstest.runsettings"); - if ( noUnitTest ) + Log.Information("runSettingsFile {RunSettingsFile}", runSettingsFile); + + try + { + // search for: dotnet test + DotNetTest(p => p + .SetConfiguration(configuration) + .EnableNoRestore() + .EnableNoBuild() + .SetVerbosity(DotNetVerbosity.normal) + .SetLoggers("trx;LogFileName=test_results.trx") + .SetDataCollector("XPlat Code Coverage") + .SetSettingsFile(runSettingsFile) + .SetProjectFile(projectFullPath)); + } + catch ( ProcessException ) { - Log.Information(">> TestNetCore is disable due the --no-unit-test flag"); - return; + var trxFullFilePath = Path.Combine( + testParentPath, + "TestResults", + "test_results.trx"); + + TrxParserHelper.DisplayFileTests(trxFullFilePath); + throw; } - var projects = GetFilesHelper.GetFiles("*test/*.csproj"); - if ( projects.Count == 0 ) + var coverageEnum = GetFilesHelper.GetFiles("**/coverage.opencover.xml"); + + foreach ( var coverageItem in coverageEnum ) { - throw new FileNotFoundException("missing tests in *test/*.csproj"); + Log.Information("coverageItem: {CoverageItem}", coverageItem); } - foreach ( var project in projects ) + // Get the FirstOrDefault() but there is no LINQ here + var coverageFilePath = + Path.Combine(testParentPath, "netcore-coverage.opencover.xml"); + Log.Information("next copy: coverageFilePath {CoverageFilePath}", coverageFilePath); + + foreach ( var item in coverageEnum ) { - var projectFullPath = Path.Combine(WorkingDirectory.GetSolutionParentFolder(), - project); - Log.Information("Testing project {Project}", project); - - var testParentPath = Directory.GetParent(projectFullPath)?.FullName!; - Log.Information("testParentPath {TestParentPath} ", testParentPath); - - /* clean test results */ - var testResultsFolder = Path.Combine(testParentPath, "TestResults"); - if ( DirectoryExists(testResultsFolder) ) - { - Log.Information(">> Removing folder => {TestResultsFolder}", testResultsFolder); - Directory.Delete(testResultsFolder, true); - } - - var runSettingsFile = Path.Combine( - WorkingDirectory.GetSolutionParentFolder(), "build.vstest.runsettings"); - - Log.Information("runSettingsFile {RunSettingsFile}", runSettingsFile); - - try - { - // search for: dotnet test - DotNetTest(p => p - .SetConfiguration(configuration) - .EnableNoRestore() - .EnableNoBuild() - .SetVerbosity(DotNetVerbosity.normal) - .SetLoggers("trx;LogFileName=test_results.trx") - .SetDataCollector("XPlat Code Coverage") - .SetSettingsFile(runSettingsFile) - .SetProjectFile(projectFullPath)); - } - catch ( ProcessException ) - { - var trxFullFilePath = Path.Combine( - testParentPath, - "TestResults", - "test_results.trx"); - - TrxParserHelper.DisplayFileTests(trxFullFilePath); - throw; - } - - var coverageEnum = GetFilesHelper.GetFiles("**/coverage.opencover.xml"); - - foreach ( var coverageItem in coverageEnum ) - { - Log.Information("coverageItem: {CoverageItem}", coverageItem); - } - - // Get the FirstOrDefault() but there is no LINQ here - var coverageFilePath = - Path.Combine(testParentPath, "netcore-coverage.opencover.xml"); - Log.Information("next copy: coverageFilePath {CoverageFilePath}", coverageFilePath); - - foreach ( var item in coverageEnum ) - { - CopyFile(Path.Combine(WorkingDirectory.GetSolutionParentFolder(), item), - coverageFilePath, FileExistsPolicy.Overwrite); - } - - if ( !FileExists(coverageFilePath) ) - { - throw new FileNotFoundException("CoverageFile missing " + coverageFilePath); - } + var fromPath = AbsolutePath.Create(Path.Combine(WorkingDirectory.GetSolutionParentFolder(), item)); + var toPath = AbsolutePath.Create(coverageFilePath); + fromPath.Copy(toPath, ExistsPolicy.FileOverwrite); } - } - static bool FileExists(string path) - { - return File.Exists(path); + if ( !FileExists(coverageFilePath) ) + { + throw new FileNotFoundException("CoverageFile missing " + coverageFilePath); + } } } + + static bool FileExists(string path) + { + return File.Exists(path); + } } diff --git a/starsky/build/helpers/HttpQuery.cs b/starsky/build/helpers/HttpQuery.cs index d98f64cc9a..c094c3b9cd 100644 --- a/starsky/build/helpers/HttpQuery.cs +++ b/starsky/build/helpers/HttpQuery.cs @@ -48,12 +48,13 @@ public static Version ParseJsonVersionNumbers(string json) return SafeVersion(hightestVersion); } - private static Version SafeVersion(string? version) + static Version SafeVersion(string? version) { if ( string.IsNullOrEmpty(version) ) { return new Version(0, 0); } + try { return new Version(version); diff --git a/starsky/build/helpers/MergeCoverageFiles.cs b/starsky/build/helpers/MergeCoverageFiles.cs index fc655ddac8..4030bbf190 100644 --- a/starsky/build/helpers/MergeCoverageFiles.cs +++ b/starsky/build/helpers/MergeCoverageFiles.cs @@ -1,106 +1,98 @@ using System; using System.IO; +using Palmmedia.ReportGenerator.Core; using Serilog; -namespace helpers +namespace helpers; + +public static class MergeCoverageFiles { - public static class MergeCoverageFiles + static void Information(string value) => Log.Information(value); + + static bool FileExists(string value) => File.Exists(value); + + static void DeleteFile(string value) => File.Delete(value); + + static void MoveFile(string from, string to) => File.Move(from, to, true); + + static void CopyFile(string from, string to) => File.Copy(from, to, true); + + public static void Merge(bool noUnitTest) { - static void Information(string value) + var rootDirectory = Directory.GetParent(AppDomain.CurrentDomain + .BaseDirectory!)!.Parent!.Parent!.Parent!.FullName; + + if ( noUnitTest ) { - Log.Information(value); + Information(">> MergeCoverageFiles is disable due the --no-unit-test flag"); + return; } - static bool FileExists(string value) + var jestCoverageFile = Path.Combine(rootDirectory, + "starsky/clientapp/coverage/cobertura-coverage.xml"); + if ( !FileExists(jestCoverageFile) ) { - return File.Exists(value); + throw new FileNotFoundException($"Missing jest coverage file {jestCoverageFile}"); } - static void DeleteFile(string value) + var netCoreCoverageFile = + Path.Combine(rootDirectory, "starskytest/netcore-coverage.opencover.xml"); + if ( !FileExists(netCoreCoverageFile) ) { - File.Delete(value); + throw new FileNotFoundException($"Missing .NET coverage file ${netCoreCoverageFile}"); } - static void MoveFile(string from, string to) + var outputCoverageFile = + Path.Combine(rootDirectory, "starskytest/coverage-merge-cobertura.xml"); + + if ( FileExists(outputCoverageFile) ) { - File.Move(from, to, true); + DeleteFile(outputCoverageFile); } - static void CopyFile(string from, string to) + var outputCoverageSonarQubeFile = + Path.Combine(rootDirectory, "starskytest/coverage-merge-sonarqube.xml"); + + if ( FileExists(outputCoverageSonarQubeFile) ) { - File.Copy(from, to, true); + DeleteFile(outputCoverageSonarQubeFile); } - public static void Merge(bool noUnitTest) + // Gets the coverage file from the client folder + if ( FileExists("./starsky/clientapp/coverage/cobertura-coverage.xml") ) { - var rootDirectory = Directory.GetParent(AppDomain.CurrentDomain - .BaseDirectory!)!.Parent!.Parent!.Parent!.FullName; - - if ( noUnitTest ) - { - Information($">> MergeCoverageFiles is disable due the --no-unit-test flag"); - return; - } - - var jestCoverageFile = Path.Combine(rootDirectory, "starsky/clientapp/coverage/cobertura-coverage.xml"); - if ( !FileExists(jestCoverageFile) ) - { - throw new FileNotFoundException($"Missing jest coverage file {jestCoverageFile}"); - } - - var netCoreCoverageFile = Path.Combine(rootDirectory, "starskytest/netcore-coverage.opencover.xml"); - if ( !FileExists(netCoreCoverageFile) ) - { - throw new FileNotFoundException($"Missing .NET coverage file ${netCoreCoverageFile}"); - } - - var outputCoverageFile = Path.Combine(rootDirectory, "starskytest/coverage-merge-cobertura.xml"); - - if ( FileExists(outputCoverageFile) ) - { - DeleteFile(outputCoverageFile); - } - - var outputCoverageSonarQubeFile = Path.Combine(rootDirectory, "starskytest/coverage-merge-sonarqube.xml"); - - if ( FileExists(outputCoverageSonarQubeFile) ) - { - DeleteFile(outputCoverageSonarQubeFile); - } - - // Gets the coverage file from the client folder - if ( FileExists($"./starsky/clientapp/coverage/cobertura-coverage.xml") ) - { - Information($"Copy ./starsky/clientapp/coverage/cobertura-coverage.xml ./starskytest/jest-coverage.cobertura.xml"); - CopyFile($"./starsky/clientapp/coverage/cobertura-coverage.xml", $"./starskytest/jest-coverage.cobertura.xml"); - } - - var args = new[] - { - $"-reports:{rootDirectory}/starskytest/*coverage.*.xml", - $"-targetdir:{rootDirectory}/starskytest/", - "-reporttypes:Cobertura;SonarQube" - }; - - Palmmedia.ReportGenerator.Core.Program.Main(args); - - // And rename it - MoveFile($"{rootDirectory}/starskytest/Cobertura.xml", outputCoverageFile); - MoveFile($"{rootDirectory}/starskytest/SonarQube.xml", outputCoverageSonarQubeFile); - - if ( !FileExists(outputCoverageSonarQubeFile) ) - { - throw new FileNotFoundException($"Missing Sonarqube coverage file {outputCoverageSonarQubeFile}"); - } - Information($"Sonarqube Coverage file is ready: {outputCoverageSonarQubeFile}"); - - if ( !FileExists(outputCoverageFile) ) - { - throw new FileNotFoundException($"Missing Cobertura coverage file {outputCoverageFile}"); - } - - Information($"Cobertura Coverage file is ready: {outputCoverageFile}"); + Information( + "Copy ./starsky/clientapp/coverage/cobertura-coverage.xml ./starskytest/jest-coverage.cobertura.xml"); + CopyFile("./starsky/clientapp/coverage/cobertura-coverage.xml", + "./starskytest/jest-coverage.cobertura.xml"); + } + + var args = new[] + { + $"-reports:{rootDirectory}/starskytest/*coverage.*.xml", + $"-targetdir:{rootDirectory}/starskytest/", "-reporttypes:Cobertura;SonarQube" + }; + + Program.Main(args); + + // And rename it + MoveFile($"{rootDirectory}/starskytest/Cobertura.xml", outputCoverageFile); + MoveFile($"{rootDirectory}/starskytest/SonarQube.xml", outputCoverageSonarQubeFile); + + if ( !FileExists(outputCoverageSonarQubeFile) ) + { + throw new FileNotFoundException( + $"Missing Sonarqube coverage file {outputCoverageSonarQubeFile}"); } - } + Information($"Sonarqube Coverage file is ready: {outputCoverageSonarQubeFile}"); + + if ( !FileExists(outputCoverageFile) ) + { + throw new FileNotFoundException( + $"Missing Cobertura coverage file {outputCoverageFile}"); + } + + Information($"Cobertura Coverage file is ready: {outputCoverageFile}"); + } } diff --git a/starsky/build/helpers/ProjectCheckNetCoreCommandHelper.cs b/starsky/build/helpers/ProjectCheckNetCoreCommandHelper.cs index 9d7d8898ff..6de7f7371b 100644 --- a/starsky/build/helpers/ProjectCheckNetCoreCommandHelper.cs +++ b/starsky/build/helpers/ProjectCheckNetCoreCommandHelper.cs @@ -6,111 +6,110 @@ using static SimpleExec.Command; using static build.Build; -namespace helpers +namespace helpers; + +public static partial class ProjectCheckNetCoreCommandHelper { - public static partial class ProjectCheckNetCoreCommandHelper + static string GetBuildToolsFolder() { - static string GetBuildToolsFolder() + var baseDirectory = AppDomain.CurrentDomain + .BaseDirectory; + if ( baseDirectory == null ) { - var baseDirectory = AppDomain.CurrentDomain - .BaseDirectory; - if ( baseDirectory == null ) - { - throw new DirectoryNotFoundException("base directory is null, this is wrong"); - } - - var slnRootDirectory = Directory.GetParent(baseDirectory)?.Parent?.Parent?.Parent - ?.Parent?.FullName; - if ( slnRootDirectory == null ) - { - throw new DirectoryNotFoundException("slnRootDirectory is null, this is wrong"); - } + throw new DirectoryNotFoundException("base directory is null, this is wrong"); + } - return Path.Combine(slnRootDirectory, BuildToolsPath); + var slnRootDirectory = Directory.GetParent(baseDirectory)?.Parent?.Parent?.Parent + ?.Parent?.FullName; + if ( slnRootDirectory == null ) + { + throw new DirectoryNotFoundException("slnRootDirectory is null, this is wrong"); } - /// - /// Check for values in Csproj files - /// - /// the value to check for - /// if is missing - static void CheckForInCsProj(string valueToCheckFor) + return Path.Combine(slnRootDirectory, BuildToolsPath); + } + + /// + /// Check for values in Csproj files + /// + /// the value to check for + /// if is missing + static void CheckForInCsProj(string valueToCheckFor) + { + var projects = GetFilesHelper.GetFiles("**.csproj"); + var missingProjects = new List(); + foreach ( var project in projects ) { - var projects = GetFilesHelper.GetFiles("**.csproj"); - var missingProjects = new List(); - foreach ( var project in projects ) - { - var projectFullPath = - Path.Combine(WorkingDirectory.GetSolutionParentFolder(), project); - var projectContent = File.ReadAllText(projectFullPath); - - if ( !projectContent.Contains(valueToCheckFor) ) - { - missingProjects.Add(project); - } - } + var projectFullPath = + Path.Combine(WorkingDirectory.GetSolutionParentFolder(), project); + var projectContent = File.ReadAllText(projectFullPath); - if ( missingProjects.Count > 0 ) + if ( !projectContent.Contains(valueToCheckFor) ) { - throw new ArgumentException($"Missing {valueToCheckFor} in: " + - string.Join(" , ", missingProjects) + " projects " + - $"Please add {valueToCheckFor} to the .csproj files"); + missingProjects.Add(project); } } - static void ProjectGuid() + if ( missingProjects.Count > 0 ) { - var projects = GetFilesHelper.GetFiles("**.csproj"); - var uniqueGuids = new List(); + throw new ArgumentException($"Missing {valueToCheckFor} in: " + + string.Join(" , ", missingProjects) + " projects " + + $"Please add {valueToCheckFor} to the .csproj files"); + } + } - foreach ( var project in projects ) - { - var projectFullPath = - Path.Combine(WorkingDirectory.GetSolutionParentFolder(), project); - var projectContent = File.ReadAllText(projectFullPath); + static void ProjectGuid() + { + var projects = GetFilesHelper.GetFiles("**.csproj"); + var uniqueGuids = new List(); - var fileXmlMatch = ProjectGuidRegex().Match(projectContent); + foreach ( var project in projects ) + { + var projectFullPath = + Path.Combine(WorkingDirectory.GetSolutionParentFolder(), project); + var projectContent = File.ReadAllText(projectFullPath); - if ( !fileXmlMatch.Success ) - { - throw new NotSupportedException($"✖ {project} - No ProjectGuid in file"); - } + var fileXmlMatch = ProjectGuidRegex().Match(projectContent); - if ( uniqueGuids.Contains(fileXmlMatch.Groups[0].Value) ) - { - throw new NotSupportedException("✖ {project} - ProjectGuid is not Unique"); - } + if ( !fileXmlMatch.Success ) + { + throw new NotSupportedException($"✖ {project} - No ProjectGuid in file"); + } - uniqueGuids.Add(fileXmlMatch.Groups[0].Value); - Log.Information("✓ {Project} - Is Ok", project); + if ( uniqueGuids.Contains(fileXmlMatch.Groups[0].Value) ) + { + throw new NotSupportedException("✖ {project} - ProjectGuid is not Unique"); } + + uniqueGuids.Add(fileXmlMatch.Groups[0].Value); + Log.Information("✓ {Project} - Is Ok", project); } + } - public static void ProjectCheckNetCoreCommand() - { - // Nullable is required for all projects to be enabled - CheckForInCsProj("enable"); - // ImplicitUsings is not required to be enabled - CheckForInCsProj(""); + public static void ProjectCheckNetCoreCommand() + { + // Nullable is required for all projects to be enabled + CheckForInCsProj("enable"); + // ImplicitUsings is not required to be enabled + CheckForInCsProj(""); - // Make sure every project has an unique projectGuid - ProjectGuid(); + // Make sure every project has an unique projectGuid + ProjectGuid(); - ClientHelper.NpmPreflight(); + ClientHelper.NpmPreflight(); - // check branch names on CI - // release-version-check.js triggers app-version-update.js to update the csproj and package.json files - Run(NpmBaseCommand, "run release-version-check", GetBuildToolsFolder()); + // check branch names on CI + // release-version-check.js triggers app-version-update.js to update the csproj and package.json files + Run(NpmBaseCommand, "run release-version-check", GetBuildToolsFolder()); - /* List of nuget packages */ - Run(NpmBaseCommand, "run nuget-package-list", GetBuildToolsFolder()); - } + /* List of nuget packages */ + Run(NpmBaseCommand, "run nuget-package-list", GetBuildToolsFolder()); + } - const string BuildToolsPath = "starsky-tools/build-tools/"; + const string BuildToolsPath = "starsky-tools/build-tools/"; - [GeneratedRegex( - "(){(([0-9A-Fa-f]{8}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{12}))}(<\\/ProjectGuid>)", - RegexOptions.IgnoreCase, "nl-NL")] - private static partial Regex ProjectGuidRegex(); - } + [GeneratedRegex( + "(){(([0-9A-Fa-f]{8}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{12}))}(<\\/ProjectGuid>)", + RegexOptions.IgnoreCase, "nl-NL")] + private static partial Regex ProjectGuidRegex(); } diff --git a/starsky/build/helpers/RuntimeIdentifier.cs b/starsky/build/helpers/RuntimeIdentifier.cs index de50b2ab06..e1d71dfd98 100644 --- a/starsky/build/helpers/RuntimeIdentifier.cs +++ b/starsky/build/helpers/RuntimeIdentifier.cs @@ -30,7 +30,6 @@ public static string GetCurrentRuntimeIdentifier() return $"{os}-{architecture}"; } - public static bool IsReadyToRunSupported(string toRuntimeIdentifier) { var currentIdentifier = GetCurrentRuntimeIdentifier(); diff --git a/starsky/build/helpers/SonarQube.cs b/starsky/build/helpers/SonarQube.cs index 02b1e317ef..512ad5cee2 100644 --- a/starsky/build/helpers/SonarQube.cs +++ b/starsky/build/helpers/SonarQube.cs @@ -12,294 +12,285 @@ using static Nuke.Common.Tools.DotNet.DotNetTasks; using static SimpleExec.Command; -namespace helpers +namespace helpers; + +[SuppressMessage("ReSharper", "ArrangeTypeMemberModifiers")] +[SuppressMessage("Sonar", + "S2629: Don't use string interpolation in logging message templates", + Justification = "Not production code.")] +[SuppressMessage("Sonar", + "S6664: Reduce the number of Information logging calls within this code block", + Justification = "Not production code.")] +public static class SonarQube { - [SuppressMessage("ReSharper", "ArrangeTypeMemberModifiers")] - [SuppressMessage("Sonar", - "S2629: Don't use string interpolation in logging message templates", - Justification = "Not production code.")] - [SuppressMessage("Sonar", - "S6664: Reduce the number of Information logging calls within this code block", - Justification = "Not production code.")] - public static class SonarQube + public const string SonarQubePackageName = "dotnet-sonarscanner"; + + /// + /// @see: https://www.nuget.org/packages/dotnet-sonarscanner + /// + private const string SonarQubePackageVersion = "8.0.3"; + + private const string SonarQubeDotnetSonarScannerApi = + "https://api.nuget.org/v3-flatcontainer/dotnet-sonarscanner/index.json"; + + private const string GitCommand = "git"; + private const string DefaultBranchName = "master"; + + public static void InstallSonarTool(bool noUnitTest, bool noSonar) { - public const string SonarQubePackageName = "dotnet-sonarscanner"; + if ( noUnitTest ) + { + Information(">> SonarBegin is disable due the --no-unit-test flag"); + return; + } - /// - /// @see: https://www.nuget.org/packages/dotnet-sonarscanner - /// - public const string SonarQubePackageVersion = "8.0.0"; + if ( noSonar ) + { + Information(">> SonarBegin is disable due the --no-sonar flag"); + return; + } + + CheckLatestVersionDotNetSonarScanner().Wait(); - public const string SonarQubeDotnetSonarScannerApi = - "https://api.nuget.org/v3-flatcontainer/dotnet-sonarscanner/index.json"; + var rootDirectory = Directory.GetParent(AppDomain.CurrentDomain + .BaseDirectory)!.Parent!.Parent!.Parent!.FullName; - public const string GitCommand = "git"; - public const string DefaultBranchName = "master"; + Log.Information(rootDirectory); - public static void InstallSonarTool(bool noUnitTest, bool noSonar) + var envs = + Environment.GetEnvironmentVariables() as + IReadOnlyDictionary; + + var toolList = DotNet($"tool list", rootDirectory, envs, null, true); + + if ( toolList.Any(p => p.Text.Contains(SonarQubePackageName) + && toolList.Any(p => p.Text.Contains(SonarQubePackageVersion))) ) { - if ( noUnitTest ) - { - Information($">> SonarBegin is disable due the --no-unit-test flag"); - return; - } + Log.Information("Next: tool restore"); + DotNet($"tool restore", rootDirectory, envs, null, true); - if ( noSonar ) - { - Information($">> SonarBegin is disable due the --no-sonar flag"); - return; - } + Log.Information("Skip creation of manifest files and install"); + return; + } - CheckLatestVersionDotNetSonarScanner().Wait(); + Log.Information("Next: Create new manifest file"); + + DotNet($"new tool-manifest --force", rootDirectory, envs, null, true); + + Log.Information("Next: Install Sonar tool"); + DotNetToolInstall(p => p + .SetPackageName(SonarQubePackageName) + .SetProcessWorkingDirectory(rootDirectory) + .SetVersion(SonarQubePackageVersion)); + } + + private static string? EnvironmentVariable(string input) => + Environment.GetEnvironmentVariable(input); + + private static void Information(string input) => Log.Information(input); + + static async Task CheckLatestVersionDotNetSonarScanner() + { + var result = await HttpQuery.GetJsonFromApi(SonarQubeDotnetSonarScannerApi); + if ( result == null ) + { + Log.Information("Nuget API is not available, " + + "so skip checking the latest version of {SonarQubePackageName}", + SonarQubePackageName); + return; + } + + var latestVersionByApi = HttpQuery.ParseJsonVersionNumbers(result); + if ( latestVersionByApi > new Version(SonarQubePackageVersion) ) + { + Log.Warning("Please upgrade to the latest version " + + "of dotnet-sonarscanner {LatestVersionByApi} \n\n", latestVersionByApi); + Log.Warning("Update the following values: \n" + + "- build/helpers/SonarQube.cs -> SonarQubePackageVersion to {LatestVersionByApi} \n" + + "The _build project will auto update: \n" + + "- .config/dotnet-tools.json", latestVersionByApi); + } + } - var rootDirectory = Directory.GetParent(AppDomain.CurrentDomain - .BaseDirectory!)!.Parent!.Parent!.Parent!.FullName; - Log.Information(rootDirectory); + private static void IsJavaInstalled() + { + Log.Information("Checking if Java is installed, will fail if not on this step"); + Run(Build.JavaBaseCommand, "-version"); + } - var envs = - Environment.GetEnvironmentVariables() as - IReadOnlyDictionary; + public static string? GetSonarToken() + { + var sonarToken = EnvironmentVariable("STARSKY_SONAR_TOKEN"); + if ( string.IsNullOrEmpty(sonarToken) ) + { + sonarToken = EnvironmentVariable("SONAR_TOKEN"); + } - var toolList = DotNet($"tool list", rootDirectory, envs, null, true); + return sonarToken; + } - if ( toolList.Any(p => p.Text.Contains(SonarQubePackageName) - && toolList.Any(p => p.Text.Contains(SonarQubePackageVersion))) ) - { - Log.Information("Next: tool restore"); - DotNet($"tool restore", rootDirectory, envs, null, true); + public static string? GetSonarKey() => EnvironmentVariable("STARSKY_SONAR_KEY"); - Log.Information("Skip creation of manifest files and install"); - return; - } + public static bool SonarBegin(bool noUnitTest, bool noSonar, string branchName, + string clientAppProject, string coverageFile) + { + Information($">> SonarQube key={GetSonarKey()}"); - Log.Information("Next: Create new manifest file"); + var sonarToken = GetSonarToken(); - DotNet($"new tool-manifest --force", rootDirectory, envs, null, true); + var organisation = EnvironmentVariable("STARSKY_SONAR_ORGANISATION"); - Log.Information("Next: Install Sonar tool"); - DotNetToolInstall(p => p - .SetPackageName(SonarQubePackageName) - .SetProcessWorkingDirectory(rootDirectory) - .SetVersion(SonarQubePackageVersion)); + var url = EnvironmentVariable("STARSKY_SONAR_URL"); + if ( string.IsNullOrEmpty(url) ) + { + url = "https://sonarcloud.io"; } - private static string? EnvironmentVariable(string input) + if ( string.IsNullOrEmpty(GetSonarKey()) || string.IsNullOrEmpty(sonarToken) || + string.IsNullOrEmpty(organisation) ) { - return Environment.GetEnvironmentVariable(input); + Information( + $">> SonarQube is disabled $ key={GetSonarKey()}|token={sonarToken}|organisation={organisation}"); + return false; } - private static void Information(string input) + if ( noUnitTest ) { - Log.Information(input); + Information(">> SonarBegin is disable due the --no-unit-test flag"); + return false; } - static async Task CheckLatestVersionDotNetSonarScanner() + if ( noSonar ) { - var result = await HttpQuery.GetJsonFromApi(SonarQubeDotnetSonarScannerApi); - if ( result == null ) - { - Log.Information("Nuget API is not available, " + - "so skip checking the latest version of {SonarQubePackageName}", - SonarQubePackageName); - return; - } - - var latestVersionByApi = HttpQuery.ParseJsonVersionNumbers(result); - if ( latestVersionByApi > new Version(SonarQubePackageVersion) ) - { - Log.Warning("Please upgrade to the latest version " + - "of dotnet-sonarscanner {LatestVersionByApi} \n\n", latestVersionByApi); - Log.Warning("Update the following values: \n" + - "- build/helpers/SonarQube.cs -> SonarQubePackageVersion to {LatestVersionByApi} \n" + - "The _build project will auto update: \n" + - "- .config/dotnet-tools.json", latestVersionByApi); - } + Information(">> SonarBegin is disable due the --no-sonar flag"); + return false; } + IsJavaInstalled(); + + // Current branch name + var mainRepoPath = Directory.GetParent(".")?.FullName; + + var (gitBranchName, _) = + ReadAsync(GitCommand, " branch --show-current", mainRepoPath!).Result; - private static void IsJavaInstalled() + // allow to overwrite the branch name + if ( string.IsNullOrEmpty(branchName) && !string.IsNullOrEmpty(gitBranchName) ) { - Log.Information("Checking if Java is installed, will fail if not on this step"); - Run(Build.JavaBaseCommand, "-version"); + branchName = gitBranchName.Trim(); // fallback as (no branch) } - public static string? GetSonarToken() + // replace default value to master + if ( branchName == "(no branch)" || string.IsNullOrEmpty(branchName) ) { - var sonarToken = EnvironmentVariable("STARSKY_SONAR_TOKEN"); - if ( string.IsNullOrEmpty(sonarToken) ) - { - sonarToken = EnvironmentVariable("SONAR_TOKEN"); - } + branchName = DefaultBranchName; + } - return sonarToken; + /* this should fix No inputs were found in config file 'tsconfig.json'. */ + var tsconfig = Path.Combine(clientAppProject, "tsconfig.json"); + Information(">> tsconfig: " + tsconfig); + + // For Pull Requests + var isPrBuild = EnvironmentVariable("GITHUB_ACTIONS") != null && + EnvironmentVariable("GITHUB_JOB") != null && + EnvironmentVariable("GITHUB_BASE_REF") != null && + !string.IsNullOrEmpty(EnvironmentVariable("PR_NUMBER_GITHUB")); + + var githubPrNumber = EnvironmentVariable("PR_NUMBER_GITHUB"); + var githubBaseBranch = EnvironmentVariable("GITHUB_BASE_REF"); + var githubRepoSlug = EnvironmentVariable("GITHUB_REPOSITORY"); + + Information($">> Selecting Branch: {branchName}"); + + var sonarQubeCoverageFile = + Path.Combine(WorkingDirectory.GetSolutionParentFolder(), coverageFile); + Information(">> SonarQubeCoverageFile: " + sonarQubeCoverageFile); + + var sonarArguments = new StringBuilder() + .Append("sonarscanner ") + .Append("begin ") + // .Append($"/d:sonar.verbose=true ") + .Append($"/d:sonar.host.url={url} ") + .Append($"/k:{GetSonarKey()} ") + .Append("/n:Starsky ") + .Append($"/d:sonar.token={sonarToken} ") + .Append("/o:" + organisation + " ") + .Append($"/d:sonar.typescript.tsconfigPath={tsconfig} ") + .Append($"/d:sonar.coverageReportPaths={sonarQubeCoverageFile} ") + .Append("/d:sonar.exclusions=**/build/*,**/build/helpers/*," + + "**/documentation/*," + + "**/Interfaces/IQuery.cs," + + "**/setupTests.js,**/react-app-env.d.ts,**/service-worker.ts," + + "*webhtmlcli/**/*.js,**/wwwroot/js/**/*,**/*/Migrations/*,**/*spec.tsx," + + "**/*stories.tsx,**/*spec.ts,**/src/main.tsx,**/src/index.tsx,**/src/style/css/vendor/*,**/node_modules/*," + + "**/prestorybook.js,**/vite.config.ts,**/.storybook/**,**/jest.setup.ts," + + "**/_bigimages-helper.js ") + .Append("/d:sonar.coverage.exclusions=**/build/*,**/build/helpers/*," + + "**/build/Constants/*," + + "**/documentation/*," + + "**/Interfaces/IQuery.cs," + + "**/setupTests.js,**/react-app-env.d.ts,**/service-worker.ts," + + "*webhtmlcli/**/*.js,**/wwwroot/js/**/*,**/*/Migrations/*," + + "**/*spec.ts,**/*stories.tsx,**/*spec.tsx,**/src/main.tsx,**/src/index.tsx,**/node_modules/*," + + "**/prestorybook.js,**/vite.config.ts,**/.storybook/**,**/jest.setup.ts," + + "**/_bigimages-helper.js "); + + // Normal build + if ( !isPrBuild ) + { + Information(">> Normal Build (non-pr)"); + sonarArguments + .Append($"/d:sonar.branch.name={branchName} "); } - public static string? GetSonarKey() + // Pull Request Build + if ( isPrBuild ) { - return EnvironmentVariable("STARSKY_SONAR_KEY"); + Information($">> PR Build isPRBuild={true} githubPrNumber " + + $"{githubPrNumber} githubBaseBranch {githubBaseBranch} githubRepoSlug {githubRepoSlug}"); + + sonarArguments + .Append($"/d:sonar.pullrequest.key={githubPrNumber} ") + .Append($"/d:sonar.pullrequest.branch={gitBranchName} ") + .Append($"/d:sonar.pullrequest.base={githubBaseBranch} ") + .Append("/d:sonar.pullrequest.provider=github ") + .Append("/d:sonar.pullrequest.github.endpoint=https://api.github.com/ ") + .Append($"/d:sonar.pullrequest.github.repository={githubRepoSlug} "); } - public static bool SonarBegin(bool noUnitTest, bool noSonar, string branchName, - string clientAppProject, string coverageFile) + DotNet(sonarArguments.ToString()); + return true; + } + + public static void SonarEnd(bool noUnitTest, bool noSonar) + { + var sonarToken = GetSonarToken(); + if ( string.IsNullOrEmpty(sonarToken) ) { - Information($">> SonarQube key={GetSonarKey()}"); - - var sonarToken = GetSonarToken(); - - var organisation = EnvironmentVariable("STARSKY_SONAR_ORGANISATION"); - - var url = EnvironmentVariable("STARSKY_SONAR_URL"); - if ( string.IsNullOrEmpty(url) ) - { - url = "https://sonarcloud.io"; - } - - if ( string.IsNullOrEmpty(GetSonarKey()) || string.IsNullOrEmpty(sonarToken) || - string.IsNullOrEmpty(organisation) ) - { - Information( - $">> SonarQube is disabled $ key={GetSonarKey()}|token={sonarToken}|organisation={organisation}"); - return false; - } - - if ( noUnitTest ) - { - Information($">> SonarBegin is disable due the --no-unit-test flag"); - return false; - } - - if ( noSonar ) - { - Information($">> SonarBegin is disable due the --no-sonar flag"); - return false; - } - - IsJavaInstalled(); - - // Current branch name - var mainRepoPath = Directory.GetParent(".")?.FullName; - - var (gitBranchName, _) = - ReadAsync(GitCommand, " branch --show-current", mainRepoPath!).Result; - - // allow to overwrite the branch name - if ( string.IsNullOrEmpty(branchName) && !string.IsNullOrEmpty(gitBranchName) ) - { - branchName = gitBranchName.Trim(); // fallback as (no branch) - } - - // replace default value to master - if ( branchName == "(no branch)" || string.IsNullOrEmpty(branchName) ) - { - branchName = DefaultBranchName; - } - - /* this should fix No inputs were found in config file 'tsconfig.json'. */ - var tsconfig = Path.Combine(clientAppProject, "tsconfig.json"); - Information(">> tsconfig: " + tsconfig); - - // For Pull Requests - var isPrBuild = EnvironmentVariable("GITHUB_ACTIONS") != null && - EnvironmentVariable("GITHUB_JOB") != null && - EnvironmentVariable("GITHUB_BASE_REF") != null && - !string.IsNullOrEmpty(EnvironmentVariable("PR_NUMBER_GITHUB")); - - var githubPrNumber = EnvironmentVariable("PR_NUMBER_GITHUB"); - var githubBaseBranch = EnvironmentVariable("GITHUB_BASE_REF"); - var githubRepoSlug = EnvironmentVariable("GITHUB_REPOSITORY"); - - Information($">> Selecting Branch: {branchName}"); - - var sonarQubeCoverageFile = - Path.Combine(WorkingDirectory.GetSolutionParentFolder(), coverageFile); - Information(">> SonarQubeCoverageFile: " + sonarQubeCoverageFile); - - var sonarArguments = new StringBuilder() - .Append($"sonarscanner ") - .Append($"begin ") - // .Append($"/d:sonar.verbose=true ") - .Append($"/d:sonar.host.url={url} ") - .Append($"/k:{GetSonarKey()} ") - .Append($"/n:Starsky ") - .Append($"/d:sonar.token={sonarToken} ") - .Append($"/o:" + organisation + " ") - .Append($"/d:sonar.typescript.tsconfigPath={tsconfig} ") - .Append($"/d:sonar.coverageReportPaths={sonarQubeCoverageFile} ") - .Append($"/d:sonar.exclusions=**/build/*,**/build/helpers/*," + - "**/documentation/*," + - "**/Interfaces/IQuery.cs," + - $"**/setupTests.js,**/react-app-env.d.ts,**/service-worker.ts," + - $"*webhtmlcli/**/*.js,**/wwwroot/js/**/*,**/*/Migrations/*,**/*spec.tsx," + - $"**/*stories.tsx,**/*spec.ts,**/src/main.tsx,**/src/index.tsx,**/src/style/css/vendor/*,**/node_modules/*," + - $"**/prestorybook.js,**/vite.config.ts,**/.storybook/**,**/jest.setup.ts," + - $"**/_bigimages-helper.js ") - .Append($"/d:sonar.coverage.exclusions=**/build/*,**/build/helpers/*," + - "**/build/Constants/*," + - "**/documentation/*," + - "**/Interfaces/IQuery.cs," + - $"**/setupTests.js,**/react-app-env.d.ts,**/service-worker.ts," + - $"*webhtmlcli/**/*.js,**/wwwroot/js/**/*,**/*/Migrations/*," + - $"**/*spec.ts,**/*stories.tsx,**/*spec.tsx,**/src/main.tsx,**/src/index.tsx,**/node_modules/*," + - $"**/prestorybook.js,**/vite.config.ts,**/.storybook/**,**/jest.setup.ts," + - $"**/_bigimages-helper.js "); - - // Normal build - if ( !isPrBuild ) - { - Information($">> Normal Build (non-pr)"); - sonarArguments - .Append($"/d:sonar.branch.name={branchName} "); - } - - // Pull Request Build - if ( isPrBuild ) - { - Information($">> PR Build isPRBuild={true} githubPrNumber " + - $"{githubPrNumber} githubBaseBranch {githubBaseBranch} githubRepoSlug {githubRepoSlug}"); - - sonarArguments - .Append($"/d:sonar.pullrequest.key={githubPrNumber} ") - .Append($"/d:sonar.pullrequest.branch={gitBranchName} ") - .Append($"/d:sonar.pullrequest.base={githubBaseBranch} ") - .Append($"/d:sonar.pullrequest.provider=github ") - .Append($"/d:sonar.pullrequest.github.endpoint=https://api.github.com/ ") - .Append($"/d:sonar.pullrequest.github.repository={githubRepoSlug} "); - } - - DotNet(sonarArguments.ToString()); - return true; + Information($">> SonarQube is disabled $ login={sonarToken}"); + return; } - public static void SonarEnd(bool noUnitTest, bool noSonar) + if ( noUnitTest ) { - var sonarToken = GetSonarToken(); - if ( string.IsNullOrEmpty(sonarToken) ) - { - Information($">> SonarQube is disabled $ login={sonarToken}"); - return; - } - - if ( noUnitTest ) - { - Information($">> SonarEnd is disable due the --no-unit-test flag"); - return; - } - - if ( noSonar ) - { - Information($">> SonarEnd is disable due the --no-sonar flag"); - return; - } - - var sonarArguments = new StringBuilder() - .Append($"sonarscanner ") - .Append($"end ") - .Append($"/d:sonar.token={sonarToken} "); - - DotNet(sonarArguments.ToString()); - - Log.Information("- - - - - - - - - - Sonar done - - - - - - - - - - \n"); + Information(">> SonarEnd is disable due the --no-unit-test flag"); + return; } + + if ( noSonar ) + { + Information(">> SonarEnd is disable due the --no-sonar flag"); + return; + } + + var sonarArguments = new StringBuilder() + .Append("sonarscanner ") + .Append("end ") + .Append($"/d:sonar.token={sonarToken} "); + + DotNet(sonarArguments.ToString()); + + Log.Information("- - - - - - - - - - Sonar done - - - - - - - - - - \n"); } } diff --git a/starsky/build/helpers/ZipperHelper.cs b/starsky/build/helpers/ZipperHelper.cs index 00858d2e81..64c33ed2d9 100644 --- a/starsky/build/helpers/ZipperHelper.cs +++ b/starsky/build/helpers/ZipperHelper.cs @@ -6,109 +6,106 @@ using build; using Serilog; -namespace helpers +namespace helpers; + +[SuppressMessage("Usage", + "S1118:Add a 'protected' constructor " + + "or the 'static' keyword to the class declaration", + Justification = "Not production code.")] +[SuppressMessage("Sonar", + "S2629: Don't use string interpolation in logging message templates", + Justification = "Not production code.")] +public sealed class ZipperHelper { - [SuppressMessage("Usage", - "S1118:Add a 'protected' constructor " + - "or the 'static' keyword to the class declaration", - Justification = "Not production code.")] - [SuppressMessage("Sonar", - "S2629: Don't use string interpolation in logging message templates", - Justification = "Not production code.")] - public sealed class ZipperHelper + public const string ZipPrefix = "starsky-"; + + const string CoverageReportZip = "coverage-report.zip"; + + static string BasePath() => + Directory.GetParent(AppDomain.CurrentDomain + .BaseDirectory)!.Parent!.Parent!.Parent!.FullName; + + public static void ZipGeneric() { - public const string ZipPrefix = "starsky-"; + var fromFolder = Path.Join(BasePath(), Build.GenericRuntimeName); + + if ( !Directory.Exists(fromFolder) ) + { + throw new DirectoryNotFoundException( + $"dir {Build.GenericRuntimeName} not found {fromFolder}"); + } + + var zipPath = Path.Join(BasePath(), + ZipPrefix + Build.GenericRuntimeName + ".zip"); + + if ( File.Exists(zipPath) ) + { + File.Delete(zipPath); + } - static string BasePath() + Log.Information($"next: {Build.GenericRuntimeName} zip ~ {fromFolder} -> {zipPath}"); + ZipFile.CreateFromDirectory(fromFolder, + zipPath); + } + + public static void ZipRuntimes(List getRuntimesWithoutGeneric) + { + if ( getRuntimesWithoutGeneric.Count == 0 ) { - return Directory.GetParent(AppDomain.CurrentDomain - .BaseDirectory)!.Parent!.Parent!.Parent!.FullName; + Log.Information("There are no runtime specific items selected\n" + + "So skip ZipRuntimes"); + return; } - public static void ZipGeneric() + foreach ( var runtime in getRuntimesWithoutGeneric ) { - var fromFolder = Path.Join(BasePath(), Build.GenericRuntimeName); + var runtimeFullPath = Path.Join(BasePath(), runtime); - if ( !Directory.Exists(fromFolder) ) + if ( !Directory.Exists(runtimeFullPath) ) { throw new DirectoryNotFoundException( - $"dir {Build.GenericRuntimeName} not found {fromFolder}"); + $"dir {Build.GenericRuntimeName} not found ~ {runtimeFullPath}"); } var zipPath = Path.Join(BasePath(), - ZipPrefix + Build.GenericRuntimeName + ".zip"); + ZipPrefix + runtime + ".zip"); if ( File.Exists(zipPath) ) { File.Delete(zipPath); } - Log.Information($"next: {Build.GenericRuntimeName} zip ~ {fromFolder} -> {zipPath}"); - ZipFile.CreateFromDirectory(fromFolder, - zipPath); + Log.Information($"next: {runtime} zip ~ {runtimeFullPath} -> {zipPath}"); + + ZipFile.CreateFromDirectory(runtimeFullPath, zipPath); } + } - public static void ZipRuntimes(List getRuntimesWithoutGeneric) + public static void ZipHtmlCoverageReport(string? fromFolder, + bool noUnitTest) + { + if ( noUnitTest ) { - if ( getRuntimesWithoutGeneric.Count == 0 ) - { - Log.Information("There are no runtime specific items selected\n" + - "So skip ZipRuntimes"); - return; - } - - foreach ( var runtime in getRuntimesWithoutGeneric ) - { - var runtimeFullPath = Path.Join(BasePath(), runtime); - - if ( !Directory.Exists(runtimeFullPath) ) - { - throw new DirectoryNotFoundException( - $"dir {Build.GenericRuntimeName} not found ~ {runtimeFullPath}"); - } - - var zipPath = Path.Join(BasePath(), - ZipPrefix + runtime + ".zip"); - - if ( File.Exists(zipPath) ) - { - File.Delete(zipPath); - } - - Log.Information($"next: {runtime} zip ~ {runtimeFullPath} -> {zipPath}"); - - ZipFile.CreateFromDirectory(runtimeFullPath, zipPath); - } + Log.Information(">> ZipHtmlCoverageReport " + + "is disable due the --no-unit-test flag\n" + + "So skip ZipHtmlCoverageReport"); + return; } - const string CoverageReportZip = "coverage-report.zip"; - - public static void ZipHtmlCoverageReport(string? fromFolder, - bool noUnitTest) + if ( string.IsNullOrEmpty(fromFolder) || !Directory.Exists(fromFolder) ) { - if ( noUnitTest ) - { - Log.Information(">> ZipHtmlCoverageReport " + - "is disable due the --no-unit-test flag\n" + - "So skip ZipHtmlCoverageReport"); - return; - } - - if ( string.IsNullOrEmpty(fromFolder) || !Directory.Exists(fromFolder) ) - { - throw new DirectoryNotFoundException($"dir {fromFolder} not found"); - } - - var zipPath = Path.Join(BasePath(), "starskytest", CoverageReportZip); + throw new DirectoryNotFoundException($"dir {fromFolder} not found"); + } - if ( File.Exists(zipPath) ) - { - File.Delete(zipPath); - } + var zipPath = Path.Join(BasePath(), "starskytest", CoverageReportZip); - Log.Information($"next: zip {fromFolder} -> {zipPath}"); - ZipFile.CreateFromDirectory(fromFolder, - zipPath); + if ( File.Exists(zipPath) ) + { + File.Delete(zipPath); } + + Log.Information($"next: zip {fromFolder} -> {zipPath}"); + ZipFile.CreateFromDirectory(fromFolder, + zipPath); } } diff --git a/starsky/nuget-packages-list.json b/starsky/nuget-packages-list.json index dfb0b1c5fa..ce8b7e5e07 100644 --- a/starsky/nuget-packages-list.json +++ b/starsky/nuget-packages-list.json @@ -1,7 +1,7 @@ [ "Microsoft.AspNetCore.Mvc.NewtonsoftJson 8.0.8", "Microsoft.Extensions.Hosting.WindowsServices 8.0.0", - "Swashbuckle.AspNetCore 6.7.1", + "Swashbuckle.AspNetCore 6.7.3", "Microsoft.Extensions.Caching.Abstractions 8.0.0", "Microsoft.Extensions.Caching.Memory 8.0.0", "Microsoft.Extensions.Hosting.Abstractions 8.0.0", @@ -9,7 +9,7 @@ "Microsoft.Extensions.Diagnostics.HealthChecks 8.0.8", "Microsoft.Extensions.Diagnostics.HealthChecks.Abstractions 8.0.8", "AspNetCore.HealthChecks.MySql 8.0.1", - "AspNetCore.HealthChecks.Sqlite 8.0.1", + "AspNetCore.HealthChecks.Sqlite 8.1.0", "Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore 8.0.8", "MedallionShell 1.6.2", "RazorLight 2.3.1", @@ -52,9 +52,9 @@ "System.Text.Json 8.0.4", "Microsoft.AspNetCore.Identity.EntityFrameworkCore 8.0.8", "Microsoft.Extensions.Hosting 8.0.0", - "Microsoft.NET.Test.Sdk 17.11.0", - "MSTest.TestAdapter 3.5.2", - "MSTest.TestFramework 3.5.2", + "Microsoft.NET.Test.Sdk 17.11.1", + "MSTest.TestAdapter 3.6.0", + "MSTest.TestFramework 3.6.0", "coverlet.collector 6.0.2", "Microsoft.AspNetCore.Mvc.Formatters.Json 2.2.0", "Microsoft.AspNetCore.Identity 2.2.0" diff --git a/starsky/starsky.feature.health/starsky.feature.health.csproj b/starsky/starsky.feature.health/starsky.feature.health.csproj index e54f919878..8befb222f1 100644 --- a/starsky/starsky.feature.health/starsky.feature.health.csproj +++ b/starsky/starsky.feature.health/starsky.feature.health.csproj @@ -18,7 +18,7 @@ - + diff --git a/starsky/starsky/starsky.csproj b/starsky/starsky/starsky.csproj index cfd57caa40..7839711cea 100644 --- a/starsky/starsky/starsky.csproj +++ b/starsky/starsky/starsky.csproj @@ -61,7 +61,7 @@ - + diff --git a/starsky/starskytest/starsky.foundation.native/OpenApplicationNative/Helpers/MacOsOpenUrlTests.cs b/starsky/starskytest/starsky.foundation.native/OpenApplicationNative/Helpers/MacOsOpenUrlTests.cs index 75c306cbeb..e0b1e94d41 100644 --- a/starsky/starskytest/starsky.foundation.native/OpenApplicationNative/Helpers/MacOsOpenUrlTests.cs +++ b/starsky/starskytest/starsky.foundation.native/OpenApplicationNative/Helpers/MacOsOpenUrlTests.cs @@ -21,7 +21,7 @@ public class MacOsOpenUrlTests [TestMethod] public void OpenDefault_NonMacOS() { - var result = MacOsOpenUrl.OpenDefault(["any value"], OSPlatform.Linux); + var result = MacOsOpenUrl.OpenDefault(["OpenDefault_NonMacOS any value"], OSPlatform.Linux); Assert.IsNull(result); } @@ -105,7 +105,8 @@ public void TestMethodWithDefaultApp__MacOnly() [TestMethod] public void OpenApplicationAtUrl_NonMacOs() { - var result = MacOsOpenUrl.OpenApplicationAtUrl(new List { "any value" }, "app", + var result = MacOsOpenUrl.OpenApplicationAtUrl( + new List { "OpenApplicationAtUrl_NonMacOs any value" }, "app", OSPlatform.Linux); Assert.IsNull(result); } diff --git a/starsky/starskytest/starsky.foundation.native/OpenApplicationNative/Helpers/WindowsOpenDesktopAppTests.cs b/starsky/starskytest/starsky.foundation.native/OpenApplicationNative/Helpers/WindowsOpenDesktopAppTests.cs index 2a3eb0239f..b1aaea8913 100644 --- a/starsky/starskytest/starsky.foundation.native/OpenApplicationNative/Helpers/WindowsOpenDesktopAppTests.cs +++ b/starsky/starskytest/starsky.foundation.native/OpenApplicationNative/Helpers/WindowsOpenDesktopAppTests.cs @@ -82,7 +82,9 @@ private static CreateFakeStarskyWindowsExe SetupEnsureAssociationsSet() [TestMethod] public void W_OpenDefault_NonWindows() { - var result = WindowsOpenDesktopApp.OpenDefault(["any value"], OSPlatform.Linux); + var result = + WindowsOpenDesktopApp.OpenDefault(["W_OpenDefault_NonWindows any value"], + OSPlatform.Linux); Assert.IsNull(result); } @@ -95,7 +97,8 @@ public void W_OpenDefault2_NonWindows() return; } - var result = WindowsOpenDesktopApp.OpenDefault(["any value"], OSPlatform.Windows); + var result = WindowsOpenDesktopApp.OpenDefault(["W_OpenDefault2_NonWindows any value"], + OSPlatform.Windows); Assert.IsTrue(result); } @@ -109,7 +112,7 @@ public void W_OpenDefault3_NonWindows() return; } - var result = WindowsOpenDesktopApp.OpenDefault(["any value"]); + var result = WindowsOpenDesktopApp.OpenDefault(["W_OpenDefault3_NonWindows any value"]); Console.WriteLine(result); @@ -144,7 +147,8 @@ public async Task W_OpenDefault_HappyFlow__WindowsOnly() [TestMethod] public void W_OpenApplicationAtUrl_NonWindows() { - var result = WindowsOpenDesktopApp.OpenApplicationAtUrl(new List { "any value" }, + var result = WindowsOpenDesktopApp.OpenApplicationAtUrl( + new List { "W_OpenApplicationAtUrl_NonWindows any value" }, "app", OSPlatform.Linux); Assert.IsNull(result); } @@ -161,7 +165,8 @@ public void W_OpenApplicationAtUrl2_NonWindows() Assert.ThrowsException(() => { // Code that is expected to throw the exception - WindowsOpenDesktopApp.OpenApplicationAtUrl(["any value"], + WindowsOpenDesktopApp.OpenApplicationAtUrl( + ["W_OpenApplicationAtUrl2_NonWindows any value"], "/not_found_849539453", OSPlatform.Windows); }); } @@ -178,7 +183,8 @@ public void W_OpenApplicationAtUrl3_NonWindows() Assert.ThrowsException(() => { // Code that is expected to throw the exception - WindowsOpenDesktopApp.OpenApplicationAtUrl(["any value"], + WindowsOpenDesktopApp.OpenApplicationAtUrl( + ["W_OpenApplicationAtUrl3_NonWindows any value"], "app"); }); } diff --git a/starsky/starskytest/starskytest.csproj b/starsky/starskytest/starskytest.csproj index 7b1c6da3b2..09a4fd9981 100644 --- a/starsky/starskytest/starskytest.csproj +++ b/starsky/starskytest/starskytest.csproj @@ -25,9 +25,9 @@ - - - + + + all runtime; build; native; contentfiles; analyzers; buildtransitive