From fdb5b058f832f7fa0d55cec4e36a5b4f7dd09e34 Mon Sep 17 00:00:00 2001 From: Matthias Koch Date: Thu, 18 Jan 2024 11:30:08 +0100 Subject: [PATCH 01/56] fix(components): fallback to GitHub Actions --- source/Nuke.Components/ICreateGitHubRelease.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/Nuke.Components/ICreateGitHubRelease.cs b/source/Nuke.Components/ICreateGitHubRelease.cs index 5057b045f..0a57bc72e 100644 --- a/source/Nuke.Components/ICreateGitHubRelease.cs +++ b/source/Nuke.Components/ICreateGitHubRelease.cs @@ -24,7 +24,7 @@ public interface ICreateGitHubRelease : IHazGitRepository, IHazChangelog { public const string GitHubRelease = nameof(GitHubRelease); - [Parameter] [Secret] string GitHubToken => TryGetValue(() => GitHubToken) ?? GitHubActions.Instance.Token; + [Parameter] [Secret] string GitHubToken => TryGetValue(() => GitHubToken) ?? GitHubActions.Instance?.Token; string Name { get; } bool Prerelease => false; From 37f14582d8ae3270adac6ebaad73f06e68a1980b Mon Sep 17 00:00:00 2001 From: Matthias Koch Date: Thu, 18 Jan 2024 11:29:35 +0100 Subject: [PATCH 02/56] chore: update secrets --- appveyor.yml | 6 +++--- build/Build.CI.AppVeyor.cs | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 3e2a0fb73..decd911ec 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -35,9 +35,9 @@ artifacts: environment: PublicNuGetApiKey: - secure: dSaquYHVNEAZO+hhGGoGqeHaVP99BP8koHTTqcD3WInWBTmB7yE4CzxZ1pWypnX2 + secure: AzhHrKZGYyWnvMtPg06Q7PMJPp47dl5NxAHaE9ZB9tjIWVqmySx3F26YtVhRSPGa GitHubReleaseGitHubToken: - secure: a5UfxXiDEere9GkCCN9TUZMUdyzjC01cvHthbMLtSl0w+/giDwOyApiHRRRrwyKL5yd/vjD6xDBTBj+W/ZxKzMtzC+gDCSTNO8bSJG9Rh2n9eGzLtWzEFDw/zDYZXe5N + secure: a5UfxXiDEere9GkCCN9TURaC8CmN/ZaqWIeoHbHNshmXWLedwrEAdwGNzPf3dusKEykOMB7T/fIorZHPIqSRuuR3JsMya/3zPrvozT5o1A5qf6LpNAtWpdB20+3rvupZ SignPathApiToken: secure: uQTH2MxpqiqWTy7EJkjtNc43ipG17EUOQN99QsODRNgtNEcikDaP0t4ylekK/ibn TwitterConsumerKey: @@ -49,7 +49,7 @@ environment: TwitterAccessTokenSecret: secure: /RrBl2p46rlgpzBHweWeD0spt3JNZDsM8vABoI9Ao29+Z9D4rUYvpM5oHUWA8Lb6 SlackWebhook: - secure: xENxLITTR28hBLEY51YWMeHhxkhg1h1tLY1zGre1/hmM/XDRPsJCxvZvTHFhtfLsQ3cF7GQi3xDaShkVVR7zoXHsIYT+KT0zLnq9FSEvr5c= + secure: xENxLITTR28hBLEY51YWMeHhxkhg1h1tLY1zGre1/hl7LyoC3HT+0Ft9rXAZBoUij6kag6PsFaF+7siaJIG7EFgnyXe9uK3sstrgKNl1bk0= DiscordWebhook: secure: K5WG8m71vcB56C75b0ErFPLYTsqywhPy8hSn49uqc5XBE7txUnZqWBHfbWCuU9AdFkm3TNgSYLoejjF59OgiACEn45fghVe7XCwAXo2l54ZXl08MZyBkJ8by9HsZirL9W+SeysNdw/Cfc0sxKrWcpDkn1IH2zZ+iXAgqBsW2CNY= MastodonAccessToken: diff --git a/build/Build.CI.AppVeyor.cs b/build/Build.CI.AppVeyor.cs index 51dd13e13..1c3099eda 100644 --- a/build/Build.CI.AppVeyor.cs +++ b/build/Build.CI.AppVeyor.cs @@ -34,14 +34,14 @@ SkipTags = true, InvokedTargets = new[] { nameof(ITest.Test), nameof(IPack.Pack) }, Secrets = new string[0])] -[AppVeyorSecret(nameof(PublicNuGetApiKey), "dSaquYHVNEAZO+hhGGoGqeHaVP99BP8koHTTqcD3WInWBTmB7yE4CzxZ1pWypnX2")] -[AppVeyorSecret(ICreateGitHubRelease.GitHubRelease + nameof(ICreateGitHubRelease.GitHubToken), "a5UfxXiDEere9GkCCN9TUZMUdyzjC01cvHthbMLtSl0w+/giDwOyApiHRRRrwyKL5yd/vjD6xDBTBj+W/ZxKzMtzC+gDCSTNO8bSJG9Rh2n9eGzLtWzEFDw/zDYZXe5N")] +[AppVeyorSecret(nameof(PublicNuGetApiKey), "AzhHrKZGYyWnvMtPg06Q7PMJPp47dl5NxAHaE9ZB9tjIWVqmySx3F26YtVhRSPGa")] +[AppVeyorSecret(ICreateGitHubRelease.GitHubRelease + nameof(ICreateGitHubRelease.GitHubToken), "a5UfxXiDEere9GkCCN9TURaC8CmN/ZaqWIeoHbHNshmXWLedwrEAdwGNzPf3dusKEykOMB7T/fIorZHPIqSRuuR3JsMya/3zPrvozT5o1A5qf6LpNAtWpdB20+3rvupZ")] [AppVeyorSecret(ISignPackages.SignPath + nameof(ISignPackages.ApiToken), "uQTH2MxpqiqWTy7EJkjtNc43ipG17EUOQN99QsODRNgtNEcikDaP0t4ylekK/ibn")] [AppVeyorSecret(IHazTwitterCredentials.Twitter + nameof(IHazTwitterCredentials.ConsumerKey), "T61zL4r+xtyj7b0aOGYCsyixrXHooXE759T8z3M67Lw=")] [AppVeyorSecret(IHazTwitterCredentials.Twitter + nameof(IHazTwitterCredentials.ConsumerSecret), "CZwdlO4PHT51Xr0Pe/mT6WpfBzQXsL0C3yWfHgXqdYrf22rx8ePEt5qpszWckbHE5Vh5ErtVfIAQgLeFrqe2Gg==")] [AppVeyorSecret(IHazTwitterCredentials.Twitter + nameof(IHazTwitterCredentials.AccessToken), "nnv1h5nkNm4MS50soQHiYZk9hnPkWEMQP/5cdf6RJfDIL1gUYxLR7uBaAi1M4sswT0TQ7oL4TBIN/yziq33N5A==")] [AppVeyorSecret(IHazTwitterCredentials.Twitter + nameof(IHazTwitterCredentials.AccessTokenSecret), "/RrBl2p46rlgpzBHweWeD0spt3JNZDsM8vABoI9Ao29+Z9D4rUYvpM5oHUWA8Lb6")] -[AppVeyorSecret(nameof(SlackWebhook), "xENxLITTR28hBLEY51YWMeHhxkhg1h1tLY1zGre1/hmM/XDRPsJCxvZvTHFhtfLsQ3cF7GQi3xDaShkVVR7zoXHsIYT+KT0zLnq9FSEvr5c=")] +[AppVeyorSecret(nameof(SlackWebhook), "xENxLITTR28hBLEY51YWMeHhxkhg1h1tLY1zGre1/hl7LyoC3HT+0Ft9rXAZBoUij6kag6PsFaF+7siaJIG7EFgnyXe9uK3sstrgKNl1bk0=")] [AppVeyorSecret(nameof(DiscordWebhook), "K5WG8m71vcB56C75b0ErFPLYTsqywhPy8hSn49uqc5XBE7txUnZqWBHfbWCuU9AdFkm3TNgSYLoejjF59OgiACEn45fghVe7XCwAXo2l54ZXl08MZyBkJ8by9HsZirL9W+SeysNdw/Cfc0sxKrWcpDkn1IH2zZ+iXAgqBsW2CNY=")] [AppVeyorSecret(nameof(MastodonAccessToken), "pD/C1TvhUnFtb0oLUvlf2NtjkWeZQcrUVvYJE/LgZb8nxagK8Lwk+OR7TUqOh+Nn")] partial class Build From 78bb364409bb657c79c4e0b817b44b0c0ccb2cd4 Mon Sep 17 00:00:00 2001 From: Matthias Koch Date: Mon, 22 Jan 2024 13:11:11 +0100 Subject: [PATCH 03/56] chore: update download links --- docs/07-ide/visual-studio.md | 2 +- docs/07-ide/vscode.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/07-ide/visual-studio.md b/docs/07-ide/visual-studio.md index 7eae418f5..7842ffea3 100644 --- a/docs/07-ide/visual-studio.md +++ b/docs/07-ide/visual-studio.md @@ -5,7 +5,7 @@ title: Visual Studio import DownloadButton from '@site/src/components/DownloadButton'; In [Visual Studio](https://visualstudio.microsoft.com/) you can install the _NUKE Support extension_ to be more productive in writing, running, and debugging your builds. diff --git a/docs/07-ide/vscode.md b/docs/07-ide/vscode.md index bb3ea2b8e..c5a794e47 100644 --- a/docs/07-ide/vscode.md +++ b/docs/07-ide/vscode.md @@ -6,7 +6,7 @@ import DownloadButton from '@site/src/components/DownloadButton'; import ControlKey from '@site/src/components/ControlKey'; In [Visual Studio Code](https://code.visualstudio.com/) you can install the _NUKE Support extension_ to be more productive in writing, running, and debugging your builds. From da755bf40a88085a053f424b31ff4751c15d73a3 Mon Sep 17 00:00:00 2001 From: Matthias Koch Date: Sat, 27 Jan 2024 05:05:52 +0100 Subject: [PATCH 04/56] docs: remove download events --- docs/07-ide/resharper.md | 4 +--- docs/07-ide/rider.md | 4 +--- docs/07-ide/visual-studio.md | 4 +--- docs/07-ide/vscode.md | 4 +--- 4 files changed, 4 insertions(+), 12 deletions(-) diff --git a/docs/07-ide/resharper.md b/docs/07-ide/resharper.md index 4818f0c70..98280d11e 100644 --- a/docs/07-ide/resharper.md +++ b/docs/07-ide/resharper.md @@ -4,9 +4,7 @@ title: ReSharper import DownloadButton from '@site/src/components/DownloadButton'; - + In [ReSharper](https://www.jetbrains.com/resharper) you can install the _NUKE Support extension_ to be more productive in writing, running, and debugging your builds. diff --git a/docs/07-ide/rider.md b/docs/07-ide/rider.md index 247dc80aa..7c38a4eb1 100644 --- a/docs/07-ide/rider.md +++ b/docs/07-ide/rider.md @@ -5,9 +5,7 @@ sidebar_position: 1 import DownloadButton from '@site/src/components/DownloadButton'; - + In [JetBrains Rider](https://www.jetbrains.com/rider) you can install the _NUKE Support plugin_ to be more productive in writing, running, and debugging your builds. diff --git a/docs/07-ide/visual-studio.md b/docs/07-ide/visual-studio.md index 7842ffea3..c0afa572d 100644 --- a/docs/07-ide/visual-studio.md +++ b/docs/07-ide/visual-studio.md @@ -4,9 +4,7 @@ title: Visual Studio import DownloadButton from '@site/src/components/DownloadButton'; - + In [Visual Studio](https://visualstudio.microsoft.com/) you can install the _NUKE Support extension_ to be more productive in writing, running, and debugging your builds. diff --git a/docs/07-ide/vscode.md b/docs/07-ide/vscode.md index c5a794e47..f894096e3 100644 --- a/docs/07-ide/vscode.md +++ b/docs/07-ide/vscode.md @@ -5,9 +5,7 @@ title: Visual Studio Code import DownloadButton from '@site/src/components/DownloadButton'; import ControlKey from '@site/src/components/ControlKey'; - + In [Visual Studio Code](https://code.visualstudio.com/) you can install the _NUKE Support extension_ to be more productive in writing, running, and debugging your builds. From 92cc2a0d6986ea67621a13c7de9a37805af834a4 Mon Sep 17 00:00:00 2001 From: Matthias Koch Date: Sat, 3 Feb 2024 01:09:45 +0100 Subject: [PATCH 05/56] chore: update CONTRIBUTING.md --- CONTRIBUTING.md | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 32d893388..561e2cc95 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -4,7 +4,7 @@ As a community, we want to help each other, provide constructive feedback, and m ## Consumer Expectations -NUKE is a personal project that was made open-source to let the whole community benefit from it **free of charge** but also ["as is"](https://github.com/nuke-build/nuke/blob/develop/LICENSE). Like a lot of open-source projects, it is primarily maintained and developed by a [single person](https://github.com/matkoch). Some of the **most time-consuming tasks** around the project are: +NUKE is a personal project that was made open-source to let the whole community benefit from it **free of charge** but also ["as is"](https://github.com/nuke-build/nuke/blob/develop/LICENSE). Like many open-source projects, it is primarily maintained and developed by a [single person](https://github.com/matkoch). Some of the **most time-consuming tasks** around the project are: - Development of the NuGet package itself (C#, .NET, MSBuild) - Collecting CLI metadata (.NET ClI, MSBuild, Docker, +30 others) @@ -14,32 +14,31 @@ NUKE is a personal project that was made open-source to let the whole community - Hosting (Azure, Cloudflare, Algolia, Fathom) - Documentation, presentation slides, and blog posts - Helping in GitHub issues/discussions, Slack, and Discord -- Talking at conferences and meetups including travel +- Talking at conferences and meetups, including travel - Promotion on Twitter and Mastodon -This list should give you an impression of what it took to make NUKE what it is today and what it continuously takes to move it forward. Obviously though, there's only a limited amount of time a single person can dedicate besides their personal life and real job [without burning out](https://www.jeffgeerling.com/blog/2022/burden-open-source-maintainer). +This list should give you an impression of what it took to make NUKE what it is today and what it continuously takes to move it forward. Obviously, though, there's only a limited amount of time a single person can dedicate besides their personal life and real job [without burning out](https://www.jeffgeerling.com/blog/2022/burden-open-source-maintainer). -Therefore, **everything that benefits a larger audience is prioritized** over digging into issues that only affect a single or few individuals. Please don't take offense when your issue or pull-request is not getting the attention you were hoping for. It is simply a time management decision. +Therefore, **everything that benefits a larger audience is prioritized** over digging into issues that only affect a single or few individuals. Please don't take offense when your issue or pull request is not getting the attention you were hoping for. It is simply a time management decision. ## Baseline Contributions -There are a number of minimal to zero efforts you can make to show your support for the project: +There are several minimal to zero efforts you can make to show your support for the project: - Give the [GitHub project](https://github.com/nuke-build/nuke/stargazers) a star (and tell your team) - Follow [@nukebuildnet](https://twitter.com/nukebuildnet) and [@nuke@dotnet.social](https://dotnet.social/@nuke) -- Upvote, share, and comment our content (see [#mentions](https://app.slack.com/client/T9QUKHC4A/CDJD8CGQ5) on Slack) +- Upvote, share and comment on our content (see [#mentions](https://app.slack.com/client/T9QUKHC4A/CDJD8CGQ5) on Slack) - Talk about NUKE on social media and let others know where it can help (tag us!) The above points are considered somewhat of the norm in exchange for using the project free of charge. ## Sustainability Contributions -There are plenty of ways to show your commitment to the project and strengthen its longevity. These are typically tied to contributing time or money, but also allow for prioritizing your individual issues in return: +There are plenty of ways to show your commitment to the project and strengthen its longevity. These are typically tied to contributing time or money but also allow for prioritizing your own issues in return: - [Convince your company to sponsor](https://humanwhocodes.com/blog/2021/05/talk-to-your-company-sponsoring-open-source/) - Sponsor personally (e.g., when the project improves your work performance reviews) -- Fix or investigate issues that are marked as [`good first issue`](https://github.com/nuke-build/nuke/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) -- Take ownership for a tool wrapper or CI/CD service (.NET CLI, GitHub Actions, ...) +- Take ownership of a tool wrapper or CI/CD service (.NET CLI, GitHub Actions, etc.) - Write a blog post or give a meetup talk (let us know!) - Help others in GitHub issues/discussions or on Slack and Discord @@ -54,14 +53,14 @@ Evaluate whether your topic is going to be a valid issue: - Have you read and searched the [documentation](https://nuke.build/docs/introduction/)? - Have you checked the [FAQ](https://nuke.build/faq/)? - Is your issue more of a question? Ask on [GitHub discussions](https://github.com/nuke-build/nuke/discussions), [Slack](https://nuke.build/slack), or [Discord](https://nuke.build/discord)! -- Have you checked existing/closed issues? Maybe your version is behind? -- Did you verify it's not an external tool issue? Invoke the command manually! -- Don't file issues for tool wrappers. Send a pull-request instead! +- Have you checked existing/closed issues? Is your version behind? +- Have you verified it's not an external tool issue? Invoke the command manually! +- Don't file issues for tool wrappers. Send a pull request instead! - Refrain from debating the governance or state of the project out of your own interests (see [consumer expectations](#consumer-expectations) & [sustainability contributions](#sustainability-contributions)) ### When creating an issue -Choose one of the [issue templates](https://github.com/nuke-build/nuke/issues/new/choose) and fill it out as good as possible. This includes, but is not limited to: +Choose one of the [issue templates](https://github.com/nuke-build/nuke/issues/new/choose) and fill it out as well as possible. This includes, but is not limited to: - State the issue as short as possible (more likely there's time to comprehend it) - Use [markdown](https://docs.github.com/en/get-started/writing-on-github) for code, logs, and other special text fragments @@ -74,12 +73,12 @@ Choose one of the [issue templates](https://github.com/nuke-build/nuke/issues/ne Once the `triage` label is removed from your issue, you will know how it is seen from the project's perspective: -- Issues labelled as `area:cicd` or `area:tools` usually can be fixed in user code +- Issues labeled as `area:cicd` or `area:tools` usually can be fixed in user code - [Custom arguments](https://nuke.build/docs/common/cli-tools/#custom-arguments) can be wrapped in local extension methods - Additional steps in CI/CD configuration generation can be added through inheritance -- If your issue is labelled as `good first issue`, consider sending a pull-request +- If your issue is labeled as `good first issue`, consider sending a pull-request -Depending on the priority, available time, and your personal commitment to the project, the issue will be addressed sooner or later. In (hopefully) rare cases, it might also be closed due to missing resources. +The issue will be addressed sooner or later depending on the priority, available time, and your commitment to the project. In rare cases, it might also be closed due to missing resources. ## Pull-Requests @@ -96,9 +95,9 @@ In your own interest of getting a pull-request merged (timely): - Aim for qualitative and readable code - Follow the coding style of the existing codebase -- Make sure the project builds and all tests pass +- Make sure the project builds, and all tests pass - Don't copy/paste chunks of code, even when it's meant as a draft -- Drafting APIs is okay, as long as you're ready to finish it later +- Drafting APIs is okay as long as you're ready to finish it later - Add tests when meaningful, particularly when there is a related test class already ### When creating a pull-request @@ -118,7 +117,8 @@ For tool wrappers (e.g. [.NET CLI](https://github.com/nuke-build/nuke/blob/devel - `` in between paragraphs (as opposed to `

...

`) - Don't explicitly define `secret: false` (it's the default) - Don't provide `default: xxx` (it's obsolete) -- Don't generate the code; it will be done manually once per release +- Test your changes by calling the `GenerateTools` target +- Don't commit generated code; it will be done manually once per release ### After creating a pull-request From 6fe1e3b72dd9550032daedae5edcbdb3c0291f9c Mon Sep 17 00:00:00 2001 From: Matthias Koch Date: Wed, 21 Feb 2024 17:05:32 +0100 Subject: [PATCH 06/56] feat(utilities): add extensions --- .../Collections/Enumerable.ToEmptyIfNull.cs | 25 +++++++++++++++++++ .../Nuke.Utilities/Text/String.Emptiness.cs | 22 +++++++++++++++- source/Nuke.Utilities/Text/String.Split.cs | 13 ++++++++-- .../Text/String.StartsEndsContains.cs | 9 +++++++ 4 files changed, 66 insertions(+), 3 deletions(-) create mode 100644 source/Nuke.Utilities/Collections/Enumerable.ToEmptyIfNull.cs diff --git a/source/Nuke.Utilities/Collections/Enumerable.ToEmptyIfNull.cs b/source/Nuke.Utilities/Collections/Enumerable.ToEmptyIfNull.cs new file mode 100644 index 000000000..131d204a0 --- /dev/null +++ b/source/Nuke.Utilities/Collections/Enumerable.ToEmptyIfNull.cs @@ -0,0 +1,25 @@ +// Copyright 2024 Maintainers of NUKE. +// Distributed under the MIT License. +// https://github.com/nuke-build/nuke/blob/master/LICENSE + +using System.Collections.Generic; + +namespace Nuke.Common.Utilities.Collections; + +public static partial class EnumerableExtensions +{ + public static IEnumerable ToEmptyIfNull(this IEnumerable enumerable) + { + return enumerable ?? []; + } + + public static T[] ToEmptyIfNull(this T[] array) + { + return array ?? []; + } + + public static IList ToEmptyIfNull(this IList list) + { + return list ?? []; + } +} diff --git a/source/Nuke.Utilities/Text/String.Emptiness.cs b/source/Nuke.Utilities/Text/String.Emptiness.cs index d25cfca3c..f48cfe61c 100644 --- a/source/Nuke.Utilities/Text/String.Emptiness.cs +++ b/source/Nuke.Utilities/Text/String.Emptiness.cs @@ -19,7 +19,7 @@ public static bool IsNullOrEmpty(this string str) } /// - /// Indicates whether a specified string is null, empty, or consists only of white-space characters. + /// Indicates whether a specified string is null, empty, or only white-space. /// [Pure] [ContractAnnotation("null => halt")] @@ -27,4 +27,24 @@ public static bool IsNullOrWhiteSpace(this string str) { return string.IsNullOrWhiteSpace(str); } + + /// + /// Returns null if the specified string is empty. + /// + [Pure] + [ContractAnnotation("null => null")] + public static string ToNullIfEmpty(this string str) + { + return str.IsNullOrEmpty() ? null : str; + } + + /// + /// Returns null if the specified string is empty or only white-space. + /// + [Pure] + [ContractAnnotation("null => null")] + public static string ToNullIfWhiteSpace(this string str) + { + return str.IsNullOrWhiteSpace() ? null : str; + } } diff --git a/source/Nuke.Utilities/Text/String.Split.cs b/source/Nuke.Utilities/Text/String.Split.cs index 602e64121..3c1f72758 100644 --- a/source/Nuke.Utilities/Text/String.Split.cs +++ b/source/Nuke.Utilities/Text/String.Split.cs @@ -64,9 +64,18 @@ public static IEnumerable SplitCamelHumps(this string str, params string /// Splits a given string by new-lines with empty entries preserved. /// [Pure] - public static string[] SplitLineBreaks(this string str) + public static string[] SplitLineBreaks(this string str, StringSplitOptions options = StringSplitOptions.None) { - return str.Split(new[] { "\r\n", "\n" }, StringSplitOptions.None); + return str.Split(new[] { "\r\n", "\n" }, options); + } + + /// + /// Splits a given string by paragraphs (double new-line) with empty entries preserved. + /// + [Pure] + public static string[] SplitParagraphs(this string str, StringSplitOptions options = StringSplitOptions.None) + { + return str.Split(new[] { "\r\n\r\n", "\n\n" }, options); } /// diff --git a/source/Nuke.Utilities/Text/String.StartsEndsContains.cs b/source/Nuke.Utilities/Text/String.StartsEndsContains.cs index 31f2799f0..495fb676d 100644 --- a/source/Nuke.Utilities/Text/String.StartsEndsContains.cs +++ b/source/Nuke.Utilities/Text/String.StartsEndsContains.cs @@ -20,6 +20,15 @@ public static bool ContainsOrdinalIgnoreCase(this string str, string other) return str.IndexOf(other, StringComparison.OrdinalIgnoreCase) >= 0; } + /// + /// Indicates whether a collection of strings contains any other string under comparison. + /// + [Pure] + public static bool ContainsAnyOrdinalIgnoreCase(this IEnumerable str, params string[] others) + { + return others.Any(x => str.Contains(x, StringComparer.OrdinalIgnoreCase)); + } + /// /// Indicates whether a string equals another string under comparison. /// From 425c9f24ca36d0276a53cb596959e092a7e93028 Mon Sep 17 00:00:00 2001 From: Nefarion Date: Wed, 20 Mar 2024 02:27:54 +0100 Subject: [PATCH 07/56] feat(cicd): update GitLab for v16.10 (#1341) --- source/Nuke.Common/CI/GitLab/GitLab.cs | 765 +++++++++++++++++++++++-- 1 file changed, 733 insertions(+), 32 deletions(-) diff --git a/source/Nuke.Common/CI/GitLab/GitLab.cs b/source/Nuke.Common/CI/GitLab/GitLab.cs index 94cb1d888..c8b6aae22 100644 --- a/source/Nuke.Common/CI/GitLab/GitLab.cs +++ b/source/Nuke.Common/CI/GitLab/GitLab.cs @@ -1,4 +1,4 @@ -// Copyright 2023 Maintainers of NUKE. +// Copyright 2024 Maintainers of NUKE. // Distributed under the MIT License. // https://github.com/nuke-build/nuke/blob/master/LICENSE @@ -61,7 +61,7 @@ private string GetSectionId(string text) } /// - /// Mark that job is executed in CI environment. + /// Available for all jobs executed in CI/CD. true when available. /// public bool Ci => EnvironmentInfo.GetVariable("CI"); @@ -71,7 +71,9 @@ private string GetSectionId(string text) public string CommitRefName => EnvironmentInfo.GetVariable("CI_COMMIT_REF_NAME"); /// - /// $CI_COMMIT_REF_NAME lowercased, shortened to 63 bytes, and with everything except 0-9 and a-z replaced with -. No leading / trailing -. Use in URLs, host names and domain names. + /// $CI_COMMIT_REF_NAME lowercased, shortened to 63 bytes, and with everything except 0-9 and a-z replaced with -. + /// No leading / trailing -. + /// Use in URLs, host names and domain names. /// public string CommitRefSlug => EnvironmentInfo.GetVariable("CI_COMMIT_REF_SLUG"); @@ -81,27 +83,32 @@ private string GetSectionId(string text) public string CommitSha => EnvironmentInfo.GetVariable("CI_COMMIT_SHA"); /// - /// The commit tag name. Present only when building tags. + /// The commit tag name. + /// Available only in pipelines for tags. /// [CanBeNull] public string CommitTag => EnvironmentInfo.GetVariable("CI_COMMIT_TAG"); /// - /// The path to CI config file. Defaults to .gitlab-ci.yml. + /// The path to the CI/CD configuration file. + /// Defaults to .gitlab-ci.yml. + /// Read-only inside a running pipeline. /// public string ConfigPath => EnvironmentInfo.GetVariable("CI_CONFIG_PATH"); /// - /// Marks that the job is executed in a disposable environment (something that is created only for this job and disposed of/destroyed after the execution - all executors except shell and ssh). If the environment is disposable, it is set to true, otherwise it is not defined at all. + /// Only available if the job is executed in a disposable environment (something that is created only for this job and disposed of/destroyed after the execution - all executors except shell and ssh). + /// true when available. /// public bool DisposableEnvironment => EnvironmentInfo.GetVariable("CI_DISPOSABLE_ENVIRONMENT"); /// - /// The unique id of the current job that GitLab CI uses internally. + /// The internal ID of the job, unique across all jobs in the GitLab instance. /// public long JobId => EnvironmentInfo.GetVariable("CI_JOB_ID"); /// - /// The flag to indicate that job was manually started. + /// Only available if the job was started manually. + /// true when available. /// public bool JobManual => EnvironmentInfo.GetVariable("CI_JOB_MANUAL"); @@ -116,32 +123,34 @@ private string GetSectionId(string text) public string JobStage => EnvironmentInfo.GetVariable("CI_JOB_STAGE"); /// - /// Token used for authenticating with the GitLab Container Registry. + /// A token to authenticate with certain API endpoints. + /// The token is valid as long as the job is running. /// public string JobToken => EnvironmentInfo.GetVariable("CI_JOB_TOKEN"); /// - /// The URL to clone the Git repository. + /// The full path to Git clone (HTTP) the repository with a CI/CD job token, in the format https://gitlab-ci-token:$CI_JOB_TOKEN@gitlab.example.com/my-group/my-project.git. /// public string RepositoryUrl => EnvironmentInfo.GetVariable("CI_REPOSITORY_URL"); /// - /// The description of the runner as saved in GitLab. + /// The description of the runner. /// public string RunnerDescription => EnvironmentInfo.GetVariable("CI_RUNNER_DESCRIPTION"); /// - /// The unique id of runner being used. + /// The unique ID of the runner being used. /// public long RunnerId => EnvironmentInfo.GetVariable("CI_RUNNER_ID"); /// - /// The defined runner tags. + /// A comma-separated list of the runner tags. /// public string RunnerTags => EnvironmentInfo.GetVariable("CI_RUNNER_TAGS"); /// - /// The unique id of the current pipeline that GitLab CI uses internally. + /// The instance-level ID of the current pipeline. + /// This ID is unique across all projects on the GitLab instance. /// public long PipelineId => EnvironmentInfo.GetVariable("CI_PIPELINE_ID"); @@ -151,7 +160,9 @@ private string GetSectionId(string text) public bool PipelineTriggered => EnvironmentInfo.GetVariable("CI_PIPELINE_TRIGGERED"); /// - /// The source for this pipeline, one of: push, web, trigger, schedule, api, external. Pipelines created before 9.5 will have unknown as source. + /// How the pipeline was triggered. + /// Can be push, web, schedule, api, external, chat, webide, merge_request_event, external_pull_request_event, parent_pipeline, trigger, or pipeline. + /// For a description of each value, see Common if clauses for rules, which uses this variable to control when jobs run. /// public string PipelineSource => EnvironmentInfo.GetVariable("CI_PIPELINE_SOURCE"); @@ -161,87 +172,103 @@ private string GetSectionId(string text) public string ProjectDirectory => EnvironmentInfo.GetVariable("CI_PROJECT_DIR"); /// - /// The unique id of the current project that GitLab CI uses internally. + /// The ID of the current project. + /// This ID is unique across all projects on the GitLab instance. /// public long ProjectId => EnvironmentInfo.GetVariable("CI_PROJECT_ID"); /// - /// The project name that is currently being built (actually it is project folder name). + /// The name of the directory for the project. + /// For example if the project URL is gitlab.example.com/group-name/project-1, $CI_PROJECT_NAME is project-1. /// public string ProjectName => EnvironmentInfo.GetVariable("CI_PROJECT_NAME"); /// - /// The project namespace (username or groupname) that is currently being built. + /// The project namespace (username or group name) of the job. /// public string ProjectNamespace => EnvironmentInfo.GetVariable("CI_PROJECT_NAMESPACE"); /// - /// The namespace with project name. + /// The project namespace with the project name included. /// public string ProjectPath => EnvironmentInfo.GetVariable("CI_PROJECT_PATH"); /// - /// $CI_PROJECT_PATH lowercased and with everything except 0-9 and a-z replaced with -. Use in URLs and domain names. + /// $CI_PROJECT_PATH in lowercase with characters that are not a-z or 0-9 replaced with - and shortened to 63 bytes. + /// Use in URLs and domain names. /// public string ProjectPathSlug => EnvironmentInfo.GetVariable("CI_PROJECT_PATH_SLUG"); /// - /// The HTTP address to access project. + /// The HTTP(S) address of the project. /// public string ProjectUrl => EnvironmentInfo.GetVariable("CI_PROJECT_URL"); /// - /// The project visibility (internal, private, public). + /// The project visibility. + /// Can be internal, private, or public. /// public GitLabProjectVisibility ProjectVisibility => EnvironmentInfo.GetVariable("CI_PROJECT_VISIBILITY"); /// - /// If the Container Registry is enabled it returns the address of GitLab's Container Registry. + /// Address of the container registry server, formatted as <host>[:<port>]. + /// For example: registry.gitlab.example.com. + /// Only available if the container registry is enabled for the GitLab instance. /// public string Registry => EnvironmentInfo.GetVariable("CI_REGISTRY"); /// - /// If the Container Registry is enabled for the project it returns the address of the registry tied to the specific project. + /// Base address for the container registry to push, pull, or tag project's images, formatted as <host>[:<port>]/<project_full_path>. + /// For example: registry.gitlab.example.com/my_group/my_project. + /// Image names must follow the container registry naming convention. + /// Only available if the container registry is enabled for the project. /// public string RegistryImage => EnvironmentInfo.GetVariable("CI_REGISTRY_IMAGE"); /// - /// The password to use to push containers to the GitLab Container Registry. + /// The password to push containers to the GitLab project's container registry. + /// Only available if the container registry is enabled for the project. + /// This password value is the same as the $CI_JOB_TOKEN and is valid only as long as the job is running. + /// Use the $CI_DEPLOY_PASSWORD for long-lived access to the registry /// public string RegistryPassword => EnvironmentInfo.GetVariable("CI_REGISTRY_PASSWORD"); /// - /// The username to use to push containers to the GitLab Container Registry. + /// The username to push containers to the project's GitLab container registry. + /// Only available if the container registry is enabled for the project. /// public string RegistryUser => EnvironmentInfo.GetVariable("CI_REGISTRY_USER"); /// - /// The name of CI server that is used to coordinate jobs. + /// The name of CI/CD server that coordinates jobs. /// public string ServerName => EnvironmentInfo.GetVariable("CI_SERVER_NAME"); /// - /// GitLab revision that is used to schedule jobs. + /// GitLab revision that schedules jobs. /// public string ServerRevision => EnvironmentInfo.GetVariable("CI_SERVER_REVISION"); /// - /// GitLab version that is used to schedule jobs. + /// The full version of the GitLab instance. /// public string ServerVersion => EnvironmentInfo.GetVariable("CI_SERVER_VERSION"); /// - /// The id of the user who started the job. + /// The numeric ID of the user who started the pipeline, unless the job is a manual job. + /// In manual jobs, the value is the ID of the user who started the job. /// public long GitLabUserId => EnvironmentInfo.GetVariable("GITLAB_USER_ID"); /// - /// The email of the user who started the job. + /// The email of the user who started the pipeline, unless the job is a manual job. + /// In manual jobs, the value is the email of the user who started the job. /// public string GitLabUserEmail => EnvironmentInfo.GetVariable("GITLAB_USER_EMAIL"); /// - /// The login username of the user who started the job. + /// The username of the user who started the pipeline, unless the job is a manual job. + /// In manual jobs, the value is the username of the user who started the job. /// public string GitLabUserLogin => EnvironmentInfo.GetVariable("GITLAB_USER_LOGIN"); @@ -249,4 +276,678 @@ private string GetSectionId(string text) /// The real name of the user who started the job. /// public string GitLabUserName => EnvironmentInfo.GetVariable("GITLAB_USER_NAME"); + + /// ---- /// + /// + /// The Source chat channel that triggered the ChatOps command. + /// + public string ChatChannel => EnvironmentInfo.GetVariable("CHAT_CHANNEL"); + + /// + /// The additional arguments passed with the ChatOps command. + /// + public string ChatInput => EnvironmentInfo.GetVariable("CHAT_INPUT"); + + /// + /// The chat service's user ID of the user who triggered the ChatOps command. + /// + public string ChatUserId => EnvironmentInfo.GetVariable("CHAT_USER_ID"); + + /// + /// The GitLab API v4 root URL. + /// + public string ApiV4Url => EnvironmentInfo.GetVariable("CI_API_V4_URL"); + + /// + /// The GitLab API GraphQL root URL. + /// + public string ApiGraphqlUrl => EnvironmentInfo.GetVariable("CI_API_GRAPHQL_URL"); + + /// + /// The top-level directory where builds are executed. + /// + public string BuildsDir => EnvironmentInfo.GetVariable("CI_BUILDS_DIR"); + + /// + /// The author of the commit in Name <email> format. + /// + public string CommitAuthor => EnvironmentInfo.GetVariable("CI_COMMIT_AUTHOR"); + + /// + /// The previous latest commit present on a branch or tag. + /// Is always 0000000000000000000000000000000000000000 for merge request pipelines, the first commit in pipelines for branches or tags, or when manually running a pipeline. + /// + public string CommitBeforeSha => EnvironmentInfo.GetVariable("CI_COMMIT_BEFORE_SHA"); + + /// + /// The commit branch name. + /// Available in branch pipelines, including pipelines for the default branch. + /// Not available in merge request pipelines or tag pipelines. + /// + public string CommitBranch => EnvironmentInfo.GetVariable("CI_COMMIT_BRANCH"); + + /// + /// The description of the commit. + /// If the title is shorter than 100 characters, the message without the first line. + /// + public string CommitDescription => EnvironmentInfo.GetVariable("CI_COMMIT_DESCRIPTION"); + + /// + /// The full commit message. + /// + public string CommitMessage => EnvironmentInfo.GetVariable("CI_COMMIT_MESSAGE"); + + /// + /// true if the job is running for a protected reference, false otherwise. + /// + public bool CommitRefProtected => EnvironmentInfo.GetVariable("CI_COMMIT_REF_PROTECTED"); + + /// + /// The first eight characters of $CI_COMMIT_SHA. + /// + public string CommitShortSha => EnvironmentInfo.GetVariable("CI_COMMIT_SHORT_SHA"); + + /// + /// The commit tag message. + /// Available only in pipelines for tags. + /// + public string CommitTagMessage => EnvironmentInfo.GetVariable("CI_COMMIT_TAG_MESSAGE"); + + /// + /// The timestamp of the commit in the ISO 8601 format. + /// For example, 2022-01-31T16:47:55Z. + /// UTC by default. + /// + public string CommitTimestamp => EnvironmentInfo.GetVariable("CI_COMMIT_TIMESTAMP"); + + /// + /// The title of the commit. + /// The full first line of the message. + /// + public string CommitTitle => EnvironmentInfo.GetVariable("CI_COMMIT_TITLE"); + + /// + /// The unique ID of build execution in a single executor. + /// + public string ConcurrentId => EnvironmentInfo.GetVariable("CI_CONCURRENT_ID"); + + /// + /// The unique ID of build execution in a single executor and project. + /// + public string ConcurrentProjectId => EnvironmentInfo.GetVariable("CI_CONCURRENT_PROJECT_ID"); + + /// + /// true if debug logging (tracing) is enabled. + /// + public bool DebugTrace => EnvironmentInfo.GetVariable("CI_DEBUG_TRACE"); + + /// + /// true if service container logging is enabled. + /// + public bool DebugServices => EnvironmentInfo.GetVariable("CI_DEBUG_SERVICES"); + + /// + /// The name of the project's default branch. + /// + public string DefaultBranch => EnvironmentInfo.GetVariable("CI_DEFAULT_BRANCH"); + + /// + /// The direct group image prefix for pulling images through the Dependency Proxy. + /// + public string DependencyProxyDirectGroupImagePrefix => EnvironmentInfo.GetVariable("CI_DEPENDENCY_PROXY_DIRECT_GROUP_IMAGE_PREFIX"); + + /// + /// The top-level group image prefix for pulling images through the Dependency Proxy. + /// + public string DependencyProxyGroupImagePrefix => EnvironmentInfo.GetVariable("CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX"); + + /// + /// The password to pull images through the Dependency Proxy. + /// + public string DependencyProxyPassword => EnvironmentInfo.GetVariable("CI_DEPENDENCY_PROXY_PASSWORD"); + + /// + /// The server for logging in to the Dependency Proxy. + /// This is equivalent to $CI_SERVER_HOST:$CI_SERVER_PORT. + /// + public string DependencyProxyServer => EnvironmentInfo.GetVariable("CI_DEPENDENCY_PROXY_SERVER"); + + /// + /// The username to pull images through the Dependency Proxy. + /// + public string DependencyProxyUser => EnvironmentInfo.GetVariable("CI_DEPENDENCY_PROXY_USER"); + + /// + /// Only available if the pipeline runs during a deploy freeze window. + /// true when available. + /// + public bool DeployFreeze => EnvironmentInfo.GetVariable("CI_DEPLOY_FREEZE"); + + /// + /// The authentication password of the GitLab Deploy Token, if the project has one. + /// + public string DeployPassword => EnvironmentInfo.GetVariable("CI_DEPLOY_PASSWORD"); + + /// + /// The authentication username of the GitLab Deploy Token, if the project has one. + /// + public string DeployUser => EnvironmentInfo.GetVariable("CI_DEPLOY_USER"); + + /// + /// The name of the environment for this job. + /// Available if environment:name is set. + /// + public string EnvironmentName => EnvironmentInfo.GetVariable("CI_ENVIRONMENT_NAME"); + + /// + /// The simplified version of the environment name, suitable for inclusion in DNS, URLs, Kubernetes labels, and so on. + /// Available if environment:name is set. + /// The slug is truncated to 24 characters. + /// A random suffix is automatically added to uppercase environment names. + /// + public string EnvironmentSlug => EnvironmentInfo.GetVariable("CI_ENVIRONMENT_SLUG"); + + /// + /// The URL of the environment for this job. + /// Available if environment:url is set. + /// + public string EnvironmentUrl => EnvironmentInfo.GetVariable("CI_ENVIRONMENT_URL"); + + /// + /// The action annotation specified for this job's environment. + /// Available if environment:action is set. + /// Can be start, prepare, or stop. + /// + public string EnvironmentAction => EnvironmentInfo.GetVariable("CI_ENVIRONMENT_ACTION"); + + /// + /// The deployment tier of the environment for this job. + /// + public string EnvironmentTier => EnvironmentInfo.GetVariable("CI_ENVIRONMENT_TIER"); + + /// + /// The description of the release. + /// Available only on pipelines for tags. + /// Description length is limited to first 1024 characters. + /// + public string ReleaseDescription => EnvironmentInfo.GetVariable("CI_RELEASE_DESCRIPTION"); + + /// + /// Only available if FIPS mode is enabled in the GitLab instance. + /// true when available. + /// + public bool GitLabFipsMode => EnvironmentInfo.GetVariable("CI_GITLAB_FIPS_MODE"); + + /// + /// Only available if the pipeline's project has an open requirement. + /// true when available. + /// + public bool HasOpenRequirements => EnvironmentInfo.GetVariable("CI_HAS_OPEN_REQUIREMENTS"); + + /// + /// The name of the Docker image running the job. + /// + public string JobImage => EnvironmentInfo.GetVariable("CI_JOB_IMAGE"); + + /// + /// A RS256 JSON web token to authenticate with third party systems that support JWT authentication, for example HashiCorp's Vault. + /// Deprecated in GitLab 15.9 and scheduled to be removed in GitLab 17.0. + /// Use ID tokens instead. + /// + [Obsolete] public string JobJwt => EnvironmentInfo.GetVariable("CI_JOB_JWT"); + + /// + /// The same value as $CI_JOB_JWT. + /// Deprecated in GitLab 15.9 and scheduled to be removed in GitLab 17.0. + /// Use ID tokens instead. + /// + [Obsolete] public string JobJwtV1 => EnvironmentInfo.GetVariable("CI_JOB_JWT_V1"); + + /// + /// A newly formatted RS256 JSON web token to increase compatibility. + /// Similar to $CI_JOB_JWT, except the issuer (iss) claim is changed from gitlab.com to https://gitlab.com, sub has changed from job_id to a string that contains the project path, and an aud claim is added. + /// The aud field is a constant value. + /// Trusting JWTs in multiple relying parties can lead to one RP sending a JWT to another one and acting maliciously as a job. + /// Deprecated in GitLab 15.9 and scheduled to be removed in GitLab 17.0. + /// Use ID tokens instead. + /// + [Obsolete] public string JobJwtV2 => EnvironmentInfo.GetVariable("CI_JOB_JWT_V2"); + + /// + /// $CI_JOB_NAME in lowercase, shortened to 63 bytes, and with everything except 0-9 and a-z replaced with -. + /// No leading / trailing -. + /// Use in paths. + /// + public string JobNameSlug => EnvironmentInfo.GetVariable("CI_JOB_NAME_SLUG"); + + /// + /// The status of the job as each runner stage is executed. + /// Use with after_script. + /// Can be success, failed, or canceled. + /// + public string JobStatus => EnvironmentInfo.GetVariable("CI_JOB_STATUS"); + + /// + /// The job timeout, in seconds. + /// + public string JobTimeout => EnvironmentInfo.GetVariable("CI_JOB_TIMEOUT"); + + /// + /// The job details URL. + /// + public string JobUrl => EnvironmentInfo.GetVariable("CI_JOB_URL"); + + /// + /// The date and time when a job started, in ISO 8601 format. + /// For example, 2022-01-31T16:47:55Z. + /// UTC by default. + /// + public string JobStartedAt => EnvironmentInfo.GetVariable("CI_JOB_STARTED_AT"); + + /// + /// Only available if the pipeline has a Kubernetes cluster available for deployments. + /// true when available. + /// + public bool KubernetesActive => EnvironmentInfo.GetVariable("CI_KUBERNETES_ACTIVE"); + + /// + /// The index of the job in the job set. + /// Only available if the job uses parallel. + /// + public string NodeIndex => EnvironmentInfo.GetVariable("CI_NODE_INDEX"); + + /// + /// The total number of instances of this job running in parallel. + /// Set to 1 if the job does not use parallel. + /// + public string NodeTotal => EnvironmentInfo.GetVariable("CI_NODE_TOTAL"); + + /// + /// A comma-separated list of up to four merge requests that use the current branch and project as the merge request source. + /// Only available in branch and merge request pipelines if the branch has an associated merge request. + /// For example, gitlab-org/gitlab!333,gitlab-org/gitlab-foss!11. + /// + public string OpenMergeRequests => EnvironmentInfo.GetVariable("CI_OPEN_MERGE_REQUESTS"); + + /// + /// The configured domain that hosts GitLab Pages. + /// + public string PagesDomain => EnvironmentInfo.GetVariable("CI_PAGES_DOMAIN"); + + /// + /// The URL for a GitLab Pages site. + /// Always a subdomain of $CI_PAGES_DOMAIN. + /// + public string PagesUrl => EnvironmentInfo.GetVariable("CI_PAGES_URL"); + + /// + /// The project-level IID (internal ID) of the current pipeline. + /// This ID is unique only within the current project. + /// + public string PipelineIid => EnvironmentInfo.GetVariable("CI_PIPELINE_IID"); + + /// + /// The URL for the pipeline details. + /// + public string PipelineUrl => EnvironmentInfo.GetVariable("CI_PIPELINE_URL"); + + /// + /// The date and time when the pipeline was created, in ISO 8601 format. + /// For example, 2022-01-31T16:47:55Z. + /// UTC by default. + /// + public string PipelineCreatedAt => EnvironmentInfo.GetVariable("CI_PIPELINE_CREATED_AT"); + + /// + /// The pipeline name defined in workflow:name + /// + public string PipelineName => EnvironmentInfo.GetVariable("CI_PIPELINE_NAME"); + + /// + /// The full path the repository is cloned to, and where the job runs from. + /// If the GitLab Runner builds_dir parameter is set, this variable is set relative to the value of builds_dir. + /// For more information, see the Advanced GitLab Runner configuration. + /// + public string ProjectDir => EnvironmentInfo.GetVariable("CI_PROJECT_DIR"); + + /// + /// The project namespace ID of the job. + /// + public string ProjectNamespaceId => EnvironmentInfo.GetVariable("CI_PROJECT_NAMESPACE_ID"); + + /// + /// A comma-separated, lowercase list of the languages used in the repository. + /// For example ruby,javascript,html,css. + /// The maximum number of languages is limited to 5. + /// An issue proposes to increase the limit. + /// + public string ProjectRepositoryLanguages => EnvironmentInfo.GetVariable("CI_PROJECT_REPOSITORY_LANGUAGES"); + + /// + /// The root project namespace (username or group name) of the job. + /// For example, if $CI_PROJECT_NAMESPACE is root-group/child-group/grandchild-group, $CI_PROJECT_ROOT_NAMESPACE is root-group. + /// + public string ProjectRootNamespace => EnvironmentInfo.GetVariable("CI_PROJECT_ROOT_NAMESPACE"); + + /// + /// The human-readable project name as displayed in the GitLab web interface. + /// + public string ProjectTitle => EnvironmentInfo.GetVariable("CI_PROJECT_TITLE"); + + /// + /// The project description as displayed in the GitLab web interface. + /// + public string ProjectDescription => EnvironmentInfo.GetVariable("CI_PROJECT_DESCRIPTION"); + + /// + /// The project external authorization classification label. + /// + public string ProjectClassificationLabel => EnvironmentInfo.GetVariable("CI_PROJECT_CLASSIFICATION_LABEL"); + + /// + /// The OS/architecture of the GitLab Runner executable. + /// Might not be the same as the environment of the executor. + /// + public string RunnerExecutableArch => EnvironmentInfo.GetVariable("CI_RUNNER_EXECUTABLE_ARCH"); + + /// + /// The revision of the runner running the job. + /// + public string RunnerRevision => EnvironmentInfo.GetVariable("CI_RUNNER_REVISION"); + + /// + /// The runner's unique ID, used to authenticate new job requests. + /// In GitLab 14.9 and later, the token contains a prefix, and the first 17 characters are used. + /// Prior to 14.9, the first eight characters are used. + /// + public string RunnerShortToken => EnvironmentInfo.GetVariable("CI_RUNNER_SHORT_TOKEN"); + + /// + /// The version of the GitLab Runner running the job. + /// + public string RunnerVersion => EnvironmentInfo.GetVariable("CI_RUNNER_VERSION"); + + /// + /// The host of the GitLab instance URL, without protocol or port. + /// For example gitlab.example.com. + /// + public string ServerHost => EnvironmentInfo.GetVariable("CI_SERVER_HOST"); + + /// + /// The port of the GitLab instance URL, without host or protocol. + /// For example 8080. + /// + public string ServerPort => EnvironmentInfo.GetVariable("CI_SERVER_PORT"); + + /// + /// The protocol of the GitLab instance URL, without host or port. + /// For example https. + /// + public string ServerProtocol => EnvironmentInfo.GetVariable("CI_SERVER_PROTOCOL"); + + /// + /// The SSH host of the GitLab instance, used for access to Git repositories via SSH. + /// For example gitlab.com. + /// + public string ServerShellSshHost => EnvironmentInfo.GetVariable("CI_SERVER_SHELL_SSH_HOST"); + + /// + /// The SSH port of the GitLab instance, used for access to Git repositories via SSH. + /// For example 22. + /// + public string ServerShellSshPort => EnvironmentInfo.GetVariable("CI_SERVER_SHELL_SSH_PORT"); + + /// + /// File containing the TLS CA certificate to verify the GitLab server when tls-ca-file set in runner settings. + /// + public string ServerTlsCaFile => EnvironmentInfo.GetVariable("CI_SERVER_TLS_CA_FILE"); + + /// + /// File containing the TLS certificate to verify the GitLab server when tls-cert-file set in runner settings. + /// + public string ServerTlsCertFile => EnvironmentInfo.GetVariable("CI_SERVER_TLS_CERT_FILE"); + + /// + /// File containing the TLS key to verify the GitLab server when tls-key-file set in runner settings. + /// + public string ServerTlsKeyFile => EnvironmentInfo.GetVariable("CI_SERVER_TLS_KEY_FILE"); + + /// + /// The base URL of the GitLab instance, including protocol and port. + /// For example https://gitlab.example.com:8080. + /// + public string ServerUrl => EnvironmentInfo.GetVariable("CI_SERVER_URL"); + + /// + /// The major version of the GitLab instance. + /// For example, if the GitLab version is 13.6.1, the $CI_SERVER_VERSION_MAJOR is 13. + /// + public string ServerVersionMajor => EnvironmentInfo.GetVariable("CI_SERVER_VERSION_MAJOR"); + + /// + /// The minor version of the GitLab instance. + /// For example, if the GitLab version is 13.6.1, the $CI_SERVER_VERSION_MINOR is 6. + /// + public string ServerVersionMinor => EnvironmentInfo.GetVariable("CI_SERVER_VERSION_MINOR"); + + /// + /// The patch version of the GitLab instance. + /// For example, if the GitLab version is 13.6.1, the $CI_SERVER_VERSION_PATCH is 1. + /// + public string ServerVersionPatch => EnvironmentInfo.GetVariable("CI_SERVER_VERSION_PATCH"); + + /// + /// Available for all jobs executed in CI/CD. yes when available. + /// + public string Server => EnvironmentInfo.GetVariable("CI_SERVER"); + + /// + /// Only available if the job is executed in a shared environment (something that is persisted across CI/CD invocations, like the shell or ssh executor). + /// true when available. + /// + public bool SharedEnvironment => EnvironmentInfo.GetVariable("CI_SHARED_ENVIRONMENT"); + + /// + /// The host of the registry used by CI/CD templates. + /// Defaults to registry.gitlab.com. + /// + public string TemplateRegistryHost => EnvironmentInfo.GetVariable("CI_TEMPLATE_REGISTRY_HOST"); + + /// + /// Available for all jobs executed in CI/CD. true when available. + /// + public bool GitLabCi => EnvironmentInfo.GetVariable("GITLAB_CI"); + + /// + /// The comma-separated list of licensed features available for the GitLab instance and license. + /// + public string GitLabFeatures => EnvironmentInfo.GetVariable("GITLAB_FEATURES"); + + /// + /// The path to the kubeconfig file with contexts for every shared agent connection. + /// Only available when a GitLab agent is authorized to access the project. + /// + public string Kubeconfig => EnvironmentInfo.GetVariable("KUBECONFIG"); + + /// + /// The webhook payload. + /// Only available when a pipeline is triggered with a webhook. + /// + public string TriggerPayload => EnvironmentInfo.GetVariable("TRIGGER_PAYLOAD"); + + /// + /// Approval status of the merge request. true when merge request approvals is available and the merge request has been approved. + /// + public bool MergeRequestApproved => EnvironmentInfo.GetVariable("CI_MERGE_REQUEST_APPROVED"); + + /// + /// Comma-separated list of usernames of assignees for the merge request. + /// + public string MergeRequestAssignees => EnvironmentInfo.GetVariable("CI_MERGE_REQUEST_ASSIGNEES"); + + /// + /// The base SHA of the merge request diff. + /// + public string MergeRequestDiffBaseSha => EnvironmentInfo.GetVariable("CI_MERGE_REQUEST_DIFF_BASE_SHA"); + + /// + /// The version of the merge request diff. + /// + public string MergeRequestDiffId => EnvironmentInfo.GetVariable("CI_MERGE_REQUEST_DIFF_ID"); + + /// + /// The event type of the merge request. + /// Can be detached, merged_result or merge_train. + /// + public string MergeRequestEventType => EnvironmentInfo.GetVariable("CI_MERGE_REQUEST_EVENT_TYPE"); + + /// + /// The description of the merge request. + /// If the description is more than 2700 characters long, only the first 2700 characters are stored in the variable. + /// + public string MergeRequestDescription => EnvironmentInfo.GetVariable("CI_MERGE_REQUEST_DESCRIPTION"); + + /// + /// true if $CI_MERGE_REQUEST_DESCRIPTION is truncated down to 2700 characters because the description of the merge request is too long. + /// + public bool MergeRequestDescriptionIsTruncated => EnvironmentInfo.GetVariable("CI_MERGE_REQUEST_DESCRIPTION_IS_TRUNCATED"); + + /// + /// The instance-level ID of the merge request. + /// This is a unique ID across all projects on the GitLab instance. + /// + public string MergeRequestId => EnvironmentInfo.GetVariable("CI_MERGE_REQUEST_ID"); + + /// + /// The project-level IID (internal ID) of the merge request. + /// This ID is unique for the current project, and is the number used in the merge request URL, page title, and other visible locations. + /// + public string MergeRequestIid => EnvironmentInfo.GetVariable("CI_MERGE_REQUEST_IID"); + + /// + /// Comma-separated label names of the merge request. + /// + public string MergeRequestLabels => EnvironmentInfo.GetVariable("CI_MERGE_REQUEST_LABELS"); + + /// + /// The milestone title of the merge request. + /// + public string MergeRequestMilestone => EnvironmentInfo.GetVariable("CI_MERGE_REQUEST_MILESTONE"); + + /// + /// The ID of the project of the merge request. + /// + public string MergeRequestProjectId => EnvironmentInfo.GetVariable("CI_MERGE_REQUEST_PROJECT_ID"); + + /// + /// The path of the project of the merge request. + /// For example namespace/awesome-project. + /// + public string MergeRequestProjectPath => EnvironmentInfo.GetVariable("CI_MERGE_REQUEST_PROJECT_PATH"); + + /// + /// The URL of the project of the merge request. + /// For example, http://192.168.10.15:3000/namespace/awesome-project. + /// + public string MergeRequestProjectUrl => EnvironmentInfo.GetVariable("CI_MERGE_REQUEST_PROJECT_URL"); + + /// + /// The ref path of the merge request. + /// For example, refs/merge-requests/1/head. + /// + public string MergeRequestRefPath => EnvironmentInfo.GetVariable("CI_MERGE_REQUEST_REF_PATH"); + + /// + /// The source branch name of the merge request. + /// + public string MergeRequestSourceBranchName => EnvironmentInfo.GetVariable("CI_MERGE_REQUEST_SOURCE_BRANCH_NAME"); + + /// + /// true when the source branch of the merge request is protected. + /// + public bool MergeRequestSourceBranchProtected => EnvironmentInfo.GetVariable("CI_MERGE_REQUEST_SOURCE_BRANCH_PROTECTED"); + + /// + /// The HEAD SHA of the source branch of the merge request. + /// The variable is empty in merge request pipelines. + /// The SHA is present only in merged results pipelines. + /// + public string MergeRequestSourceBranchSha => EnvironmentInfo.GetVariable("CI_MERGE_REQUEST_SOURCE_BRANCH_SHA"); + + /// + /// The ID of the source project of the merge request. + /// + public string MergeRequestSourceProjectId => EnvironmentInfo.GetVariable("CI_MERGE_REQUEST_SOURCE_PROJECT_ID"); + + /// + /// The path of the source project of the merge request. + /// + public string MergeRequestSourceProjectPath => EnvironmentInfo.GetVariable("CI_MERGE_REQUEST_SOURCE_PROJECT_PATH"); + + /// + /// The URL of the source project of the merge request. + /// + public string MergeRequestSourceProjectUrl => EnvironmentInfo.GetVariable("CI_MERGE_REQUEST_SOURCE_PROJECT_URL"); + + /// + /// true when the squash on merge option is set. + /// + public bool MergeRequestSquashOnMerge => EnvironmentInfo.GetVariable("CI_MERGE_REQUEST_SQUASH_ON_MERGE"); + + /// + /// The target branch name of the merge request. + /// + public string MergeRequestTargetBranchName => EnvironmentInfo.GetVariable("CI_MERGE_REQUEST_TARGET_BRANCH_NAME"); + + /// + /// true when the target branch of the merge request is protected. + /// + public bool MergeRequestTargetBranchProtected => EnvironmentInfo.GetVariable("CI_MERGE_REQUEST_TARGET_BRANCH_PROTECTED"); + + /// + /// The HEAD SHA of the target branch of the merge request. + /// The variable is empty in merge request pipelines. + /// The SHA is present only in merged results pipelines. + /// + public string MergeRequestTargetBranchSha => EnvironmentInfo.GetVariable("CI_MERGE_REQUEST_TARGET_BRANCH_SHA"); + + /// + /// The title of the merge request. + /// + public string MergeRequestTitle => EnvironmentInfo.GetVariable("CI_MERGE_REQUEST_TITLE"); + + /// + /// Pull request ID from GitHub. + /// + public string ExternalPullRequestIid => EnvironmentInfo.GetVariable("CI_EXTERNAL_PULL_REQUEST_IID"); + + /// + /// The source repository name of the pull request. + /// + public string ExternalPullRequestSourceRepository => EnvironmentInfo.GetVariable("CI_EXTERNAL_PULL_REQUEST_SOURCE_REPOSITORY"); + + /// + /// The target repository name of the pull request. + /// + public string ExternalPullRequestTargetRepository => EnvironmentInfo.GetVariable("CI_EXTERNAL_PULL_REQUEST_TARGET_REPOSITORY"); + + /// + /// The source branch name of the pull request. + /// + public string ExternalPullRequestSourceBranchName => EnvironmentInfo.GetVariable("CI_EXTERNAL_PULL_REQUEST_SOURCE_BRANCH_NAME"); + + /// + /// The HEAD SHA of the source branch of the pull request. + /// + public string ExternalPullRequestSourceBranchSha => EnvironmentInfo.GetVariable("CI_EXTERNAL_PULL_REQUEST_SOURCE_BRANCH_SHA"); + + /// + /// The target branch name of the pull request. + /// + public string ExternalPullRequestTargetBranchName => EnvironmentInfo.GetVariable("CI_EXTERNAL_PULL_REQUEST_TARGET_BRANCH_NAME"); + + /// + /// The HEAD SHA of the target branch of the pull request. + /// + public string ExternalPullRequestTargetBranchSha => EnvironmentInfo.GetVariable("CI_EXTERNAL_PULL_REQUEST_TARGET_BRANCH_SHA"); } From c5f62500d6bc6bd7d788b5b8f276be6b3c14fb47 Mon Sep 17 00:00:00 2001 From: Sam13 Date: Wed, 20 Mar 2024 02:32:02 +0100 Subject: [PATCH 08/56] fix(tools): tool path for DotCoverTasks on Unix (#1347) --- source/Nuke.Common/Tools/DotCover/DotCoverTasks.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/Nuke.Common/Tools/DotCover/DotCoverTasks.cs b/source/Nuke.Common/Tools/DotCover/DotCoverTasks.cs index 3f20ecbe0..60a7d2aab 100644 --- a/source/Nuke.Common/Tools/DotCover/DotCoverTasks.cs +++ b/source/Nuke.Common/Tools/DotCover/DotCoverTasks.cs @@ -12,6 +12,6 @@ internal static string GetToolPath() { return NuGetToolPathResolver.GetPackageExecutable( "JetBrains.dotCover.DotNetCliTool|JetBrains.dotCover.CommandLineTools", - EnvironmentInfo.IsWin ? "dotCover.exe" : "dotCover.sh|dotCover.exe"); + EnvironmentInfo.IsWin ? "dotCover.exe" : "dotCover.sh|dotCover.dll"); } } From 1f2031d927fbcec8ce4b10aba3b5e8bab59e94cc Mon Sep 17 00:00:00 2001 From: Marko Lahma Date: Wed, 20 Mar 2024 03:35:36 +0200 Subject: [PATCH 09/56] feat(cicd): update actions/cache and actions/upload-artifact to v4 (#1335) --- .github/workflows/alpha-deployment.yml | 2 +- .github/workflows/macos-latest.yml | 2 +- .github/workflows/ubuntu-latest.yml | 2 +- .github/workflows/windows-latest.yml | 2 +- ...ribute=GitHubActionsAttribute.verified.txt | 24 +++++++++---------- ...ribute=GitHubActionsAttribute.verified.txt | 24 +++++++++---------- .../GitHubActionsArtifactStep.cs | 2 +- .../Configuration/GitHubActionsCacheStep.cs | 2 +- 8 files changed, 30 insertions(+), 30 deletions(-) diff --git a/.github/workflows/alpha-deployment.yml b/.github/workflows/alpha-deployment.yml index db618b266..69b7d54e5 100644 --- a/.github/workflows/alpha-deployment.yml +++ b/.github/workflows/alpha-deployment.yml @@ -30,7 +30,7 @@ jobs: with: fetch-depth: 0 - name: 'Cache: .nuke/temp, ~/.nuget/packages' - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: | .nuke/temp diff --git a/.github/workflows/macos-latest.yml b/.github/workflows/macos-latest.yml index 4eaebdbca..9db41a37b 100644 --- a/.github/workflows/macos-latest.yml +++ b/.github/workflows/macos-latest.yml @@ -34,7 +34,7 @@ jobs: with: fetch-depth: 0 - name: 'Cache: .nuke/temp, ~/.nuget/packages' - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: | .nuke/temp diff --git a/.github/workflows/ubuntu-latest.yml b/.github/workflows/ubuntu-latest.yml index 96b5f5199..06b3edcd3 100644 --- a/.github/workflows/ubuntu-latest.yml +++ b/.github/workflows/ubuntu-latest.yml @@ -34,7 +34,7 @@ jobs: with: fetch-depth: 0 - name: 'Cache: .nuke/temp, ~/.nuget/packages' - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: | .nuke/temp diff --git a/.github/workflows/windows-latest.yml b/.github/workflows/windows-latest.yml index e42daf33b..b8b183eeb 100644 --- a/.github/workflows/windows-latest.yml +++ b/.github/workflows/windows-latest.yml @@ -34,7 +34,7 @@ jobs: with: fetch-depth: 0 - name: 'Cache: .nuke/temp, ~/.nuget/packages' - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: | .nuke/temp diff --git a/source/Nuke.Common.Tests/CI/ConfigurationGenerationTest.Test_testName=detailed-triggers_attribute=GitHubActionsAttribute.verified.txt b/source/Nuke.Common.Tests/CI/ConfigurationGenerationTest.Test_testName=detailed-triggers_attribute=GitHubActionsAttribute.verified.txt index 09545feca..baa10b88e 100644 --- a/source/Nuke.Common.Tests/CI/ConfigurationGenerationTest.Test_testName=detailed-triggers_attribute=GitHubActionsAttribute.verified.txt +++ b/source/Nuke.Common.Tests/CI/ConfigurationGenerationTest.Test_testName=detailed-triggers_attribute=GitHubActionsAttribute.verified.txt @@ -59,7 +59,7 @@ jobs: lfs: true fetch-depth: 2 - name: 'Cache: .nuke/temp, ~/.nuget/packages' - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: | .nuke/temp @@ -71,19 +71,19 @@ jobs: OptionalInput: ${{ github.event.inputs.OptionalInput }} RequiredInput: ${{ github.event.inputs.RequiredInput }} - name: 'Publish: src' - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: success() || failure() with: name: src path: src - name: 'Publish: test-results' - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: success() || failure() with: name: test-results path: output/test-results - name: 'Publish: coverage-report.zip' - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: success() || failure() with: name: coverage-report.zip @@ -102,7 +102,7 @@ jobs: lfs: true fetch-depth: 2 - name: 'Cache: .nuke/temp, ~/.nuget/packages' - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: | .nuke/temp @@ -114,19 +114,19 @@ jobs: OptionalInput: ${{ github.event.inputs.OptionalInput }} RequiredInput: ${{ github.event.inputs.RequiredInput }} - name: 'Publish: src' - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: success() || failure() with: name: src path: src - name: 'Publish: test-results' - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: success() || failure() with: name: test-results path: output/test-results - name: 'Publish: coverage-report.zip' - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: success() || failure() with: name: coverage-report.zip @@ -145,7 +145,7 @@ jobs: lfs: true fetch-depth: 2 - name: 'Cache: .nuke/temp, ~/.nuget/packages' - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: | .nuke/temp @@ -157,19 +157,19 @@ jobs: OptionalInput: ${{ github.event.inputs.OptionalInput }} RequiredInput: ${{ github.event.inputs.RequiredInput }} - name: 'Publish: src' - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: success() || failure() with: name: src path: src - name: 'Publish: test-results' - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: success() || failure() with: name: test-results path: output/test-results - name: 'Publish: coverage-report.zip' - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: success() || failure() with: name: coverage-report.zip diff --git a/source/Nuke.Common.Tests/CI/ConfigurationGenerationTest.Test_testName=simple-triggers_attribute=GitHubActionsAttribute.verified.txt b/source/Nuke.Common.Tests/CI/ConfigurationGenerationTest.Test_testName=simple-triggers_attribute=GitHubActionsAttribute.verified.txt index 17617c171..740323d94 100644 --- a/source/Nuke.Common.Tests/CI/ConfigurationGenerationTest.Test_testName=simple-triggers_attribute=GitHubActionsAttribute.verified.txt +++ b/source/Nuke.Common.Tests/CI/ConfigurationGenerationTest.Test_testName=simple-triggers_attribute=GitHubActionsAttribute.verified.txt @@ -29,7 +29,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: 'Cache: .nuke/temp, ~/.nuget/packages' - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: | .nuke/temp @@ -41,17 +41,17 @@ jobs: ApiKey: ${{ secrets.API_KEY }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: 'Publish: src' - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: src path: src - name: 'Publish: test-results' - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: test-results path: output/test-results - name: 'Publish: coverage-report.zip' - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: coverage-report.zip path: output/coverage-report.zip @@ -61,7 +61,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: 'Cache: .nuke/temp, ~/.nuget/packages' - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: | .nuke/temp @@ -73,17 +73,17 @@ jobs: ApiKey: ${{ secrets.API_KEY }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: 'Publish: src' - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: src path: src - name: 'Publish: test-results' - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: test-results path: output/test-results - name: 'Publish: coverage-report.zip' - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: coverage-report.zip path: output/coverage-report.zip @@ -93,7 +93,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: 'Cache: .nuke/temp, ~/.nuget/packages' - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: | .nuke/temp @@ -105,17 +105,17 @@ jobs: ApiKey: ${{ secrets.API_KEY }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: 'Publish: src' - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: src path: src - name: 'Publish: test-results' - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: test-results path: output/test-results - name: 'Publish: coverage-report.zip' - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: coverage-report.zip path: output/coverage-report.zip diff --git a/source/Nuke.Common/CI/GitHubActions/Configuration/GitHubActionsArtifactStep.cs b/source/Nuke.Common/CI/GitHubActions/Configuration/GitHubActionsArtifactStep.cs index 74b3f8f60..4cde5be24 100644 --- a/source/Nuke.Common/CI/GitHubActions/Configuration/GitHubActionsArtifactStep.cs +++ b/source/Nuke.Common/CI/GitHubActions/Configuration/GitHubActionsArtifactStep.cs @@ -17,7 +17,7 @@ public class GitHubActionsArtifactStep : GitHubActionsStep public override void Write(CustomFileWriter writer) { writer.WriteLine("- name: " + $"Publish: {Name}".SingleQuote()); - writer.WriteLine(" uses: actions/upload-artifact@v3"); + writer.WriteLine(" uses: actions/upload-artifact@v4"); using (writer.Indent()) { diff --git a/source/Nuke.Common/CI/GitHubActions/Configuration/GitHubActionsCacheStep.cs b/source/Nuke.Common/CI/GitHubActions/Configuration/GitHubActionsCacheStep.cs index bf93df153..744461d8e 100644 --- a/source/Nuke.Common/CI/GitHubActions/Configuration/GitHubActionsCacheStep.cs +++ b/source/Nuke.Common/CI/GitHubActions/Configuration/GitHubActionsCacheStep.cs @@ -23,7 +23,7 @@ public override void Write(CustomFileWriter writer) writer.WriteLine("- name: " + $"Cache: {IncludePatterns.JoinCommaSpace()}".SingleQuote()); using (writer.Indent()) { - writer.WriteLine("uses: actions/cache@v3"); + writer.WriteLine("uses: actions/cache@v4"); writer.WriteLine("with:"); using (writer.Indent()) { From e43f15dee4854218a493e98bbbea8d323e1ce348 Mon Sep 17 00:00:00 2001 From: Marko Lahma Date: Wed, 20 Mar 2024 03:40:04 +0200 Subject: [PATCH 10/56] chore: upgrade NuGet.Packaging to v6.9.1 (#1334) --- source/Nuke.MSBuildTasks/Nuke.MSBuildTasks.csproj | 2 +- source/Nuke.Tooling/Nuke.Tooling.csproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/source/Nuke.MSBuildTasks/Nuke.MSBuildTasks.csproj b/source/Nuke.MSBuildTasks/Nuke.MSBuildTasks.csproj index 071f0d270..57c0b11f8 100644 --- a/source/Nuke.MSBuildTasks/Nuke.MSBuildTasks.csproj +++ b/source/Nuke.MSBuildTasks/Nuke.MSBuildTasks.csproj @@ -11,7 +11,7 @@ - + diff --git a/source/Nuke.Tooling/Nuke.Tooling.csproj b/source/Nuke.Tooling/Nuke.Tooling.csproj index 2cf6a0ba7..bc0de0ef9 100644 --- a/source/Nuke.Tooling/Nuke.Tooling.csproj +++ b/source/Nuke.Tooling/Nuke.Tooling.csproj @@ -10,7 +10,7 @@ - + From a130e1bcd979c7cda16870a27168dfb3948fe8a8 Mon Sep 17 00:00:00 2001 From: Marko Lahma Date: Wed, 20 Mar 2024 03:42:06 +0200 Subject: [PATCH 11/56] chore: upgrade Microsoft.Build to v17.9.5 (#1333) --- source/Nuke.ProjectModel/Nuke.ProjectModel.csproj | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source/Nuke.ProjectModel/Nuke.ProjectModel.csproj b/source/Nuke.ProjectModel/Nuke.ProjectModel.csproj index 923c081a6..cf7b4233b 100644 --- a/source/Nuke.ProjectModel/Nuke.ProjectModel.csproj +++ b/source/Nuke.ProjectModel/Nuke.ProjectModel.csproj @@ -15,10 +15,10 @@ - - - - + + + + From be14f9e88a5ee72f96f719bc5427a701508a1c29 Mon Sep 17 00:00:00 2001 From: Marko Lahma Date: Wed, 20 Mar 2024 03:47:15 +0200 Subject: [PATCH 12/56] fix(tools): tool path for EntityFrameworkTasks (#1332) --- .../EntityFramework/EntityFramework.json | 20 ++++++++++++++++--- .../EntityFrameworkSettings.cs | 20 +++++++++++++++++++ .../EntityFramework/EntityFrameworkTasks.cs | 20 +++++++++++++++++++ 3 files changed, 57 insertions(+), 3 deletions(-) create mode 100644 source/Nuke.Common/Tools/EntityFramework/EntityFrameworkSettings.cs create mode 100644 source/Nuke.Common/Tools/EntityFramework/EntityFrameworkTasks.cs diff --git a/source/Nuke.Common/Tools/EntityFramework/EntityFramework.json b/source/Nuke.Common/Tools/EntityFramework/EntityFramework.json index 499090b5d..99d9b81be 100644 --- a/source/Nuke.Common/Tools/EntityFramework/EntityFramework.json +++ b/source/Nuke.Common/Tools/EntityFramework/EntityFramework.json @@ -6,13 +6,15 @@ "name": "EntityFramework", "officialUrl": "https://docs.microsoft.com/en-us/ef/core/miscellaneous/cli/dotnet", "help": "The command-line interface (CLI) tools for Entity Framework Core perform design-time development tasks. For example, they create migrations, apply migrations, and generate code for a model based on an existing database. The commands are an extension to the cross-platform dotnet command, which is part of the .NET Core SDK. These tools work with .NET Core projects.If you're using Visual Studio, we recommend the Package Manager Console tools instead:
  • They automatically work with the current project selected in the Package Manager Console without requiring that you manually switch directories.
  • They automatically open files generated by a command after the command is completed.
", - "pathExecutable": "dotnet", + "nugetPackageId": "dotnet-ef", + "customExecutable": true, "tasks": [ { "help": "The dotnet ef database drop command is used to drop the database.", "postfix": "DatabaseDrop", "definiteArgument": "ef database drop", "settingsClass": { + "baseClass": "EntityFrameworkSettings", "properties": [ { "name": "Force", @@ -34,6 +36,7 @@ "postfix": "DatabaseUpdate", "definiteArgument": "ef database update", "settingsClass": { + "baseClass": "EntityFrameworkSettings", "properties": [ { "name": "Migration", @@ -54,19 +57,24 @@ "help": "The dotnet ef dbcontext info command is used to get information about a DbContext type.", "postfix": "DbContextInfo", "definiteArgument": "ef dbcontext info", - "settingsClass": {} + "settingsClass": { + "baseClass": "EntityFrameworkSettings" + } }, { "help": "The dotnet ef dbcontext list command is used to list available DbContext types.", "postfix": "DbContextList", "definiteArgument": "ef dbcontext list", - "settingsClass": {} + "settingsClass": { + "baseClass": "EntityFrameworkSettings" + } }, { "help": "The dotnet ef dbcontext scaffold command is used to generate code for a DbContext and entity types for a database. In order for this command to generate an entity type, the database table must have a primary key.", "postfix": "DbContextScaffold", "definiteArgument": "ef dbcontext scaffold", "settingsClass": { + "baseClass": "EntityFrameworkSettings", "properties": [ { "name": "Connection", @@ -160,6 +168,7 @@ "postfix": "DbContextScript", "definiteArgument": "ef dbcontext script", "settingsClass": { + "baseClass": "EntityFrameworkSettings", "properties": [ { "name": "Output", @@ -175,6 +184,7 @@ "postfix": "MigrationsAdd", "definiteArgument": "ef migrations add", "settingsClass": { + "baseClass": "EntityFrameworkSettings", "properties": [ { "name": "Name", @@ -202,6 +212,7 @@ "postfix": "MigrationsList", "definiteArgument": "ef migrations list", "settingsClass": { + "baseClass": "EntityFrameworkSettings", "properties": [ { "name": "Connection", @@ -223,6 +234,7 @@ "postfix": "MigrationsRemove", "definiteArgument": "ef migrations remove", "settingsClass": { + "baseClass": "EntityFrameworkSettings", "properties": [ { "name": "Force", @@ -238,6 +250,7 @@ "postfix": "MigrationsBundle", "definiteArgument": "ef migrations bundle", "settingsClass": { + "baseClass": "EntityFrameworkSettings", "properties": [ { "name": "Output", @@ -271,6 +284,7 @@ "postfix": "MigrationsScript", "definiteArgument": "ef migrations script", "settingsClass": { + "baseClass": "EntityFrameworkSettings", "properties": [ { "name": "From", diff --git a/source/Nuke.Common/Tools/EntityFramework/EntityFrameworkSettings.cs b/source/Nuke.Common/Tools/EntityFramework/EntityFrameworkSettings.cs new file mode 100644 index 000000000..a88d2becd --- /dev/null +++ b/source/Nuke.Common/Tools/EntityFramework/EntityFrameworkSettings.cs @@ -0,0 +1,20 @@ +// Copyright 2024 Maintainers of NUKE. +// Distributed under the MIT License. +// https://github.com/nuke-build/nuke/blob/master/LICENSE + +using System; +using System.Linq; +using JetBrains.Annotations; +using Nuke.Common.Tooling; + +namespace Nuke.Common.Tools.EntityFramework; + +[PublicAPI] +[Serializable] +public abstract class EntityFrameworkSettings : ToolSettings +{ + protected string GetProcessToolPath() + { + return EntityFrameworkTasks.GetToolPath(); + } +} diff --git a/source/Nuke.Common/Tools/EntityFramework/EntityFrameworkTasks.cs b/source/Nuke.Common/Tools/EntityFramework/EntityFrameworkTasks.cs new file mode 100644 index 000000000..fd72b2310 --- /dev/null +++ b/source/Nuke.Common/Tools/EntityFramework/EntityFrameworkTasks.cs @@ -0,0 +1,20 @@ +// Copyright 2024 Maintainers of NUKE. +// Distributed under the MIT License. +// https://github.com/nuke-build/nuke/blob/master/LICENSE + +using System; +using System.Linq; +using Nuke.Common.Tooling; + +namespace Nuke.Common.Tools.EntityFramework; + +partial class EntityFrameworkTasks +{ + internal static string GetToolPath(string framework = null) + { + return NuGetToolPathResolver.GetPackageExecutable( + packageId: "dotnet-ef", + packageExecutable: "dotnet-ef.dll|dotnet-ef.exe", + framework: framework); + } +} From 6d21f4303d7aa304b937ac5156d1784d8149e17a Mon Sep 17 00:00:00 2001 From: Marko Lahma Date: Wed, 20 Mar 2024 03:50:31 +0200 Subject: [PATCH 13/56] feat(cicd): update GitHubActionsImage enum (#1325) --- source/Nuke.Common/CI/GitHubActions/GitHubActionsImage.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/source/Nuke.Common/CI/GitHubActions/GitHubActionsImage.cs b/source/Nuke.Common/CI/GitHubActions/GitHubActionsImage.cs index a0705dec8..03ae3cc74 100644 --- a/source/Nuke.Common/CI/GitHubActions/GitHubActionsImage.cs +++ b/source/Nuke.Common/CI/GitHubActions/GitHubActionsImage.cs @@ -20,6 +20,7 @@ public enum GitHubActionsImage [EnumValue("ubuntu-22.04")] Ubuntu2204, [EnumValue("ubuntu-20.04")] Ubuntu2004, [EnumValue("ubuntu-18.04")] Ubuntu1804, + [EnumValue("macos-14")] MacOs14, [EnumValue("macos-12")] MacOs12, [EnumValue("macos-11")] MacOs11, [EnumValue("macos-10.15")] MacOs1015, From d87fc6b8839270085b2db4065d06d4e3ae8c2c6e Mon Sep 17 00:00:00 2001 From: Amadeusz Sadowski Date: Wed, 20 Mar 2024 02:52:20 +0100 Subject: [PATCH 14/56] chore: upgrade Octokit to v9.1.1 (#1318) --- source/Nuke.Common/Nuke.Common.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/Nuke.Common/Nuke.Common.csproj b/source/Nuke.Common/Nuke.Common.csproj index a1a6a9c52..0a45af6b9 100644 --- a/source/Nuke.Common/Nuke.Common.csproj +++ b/source/Nuke.Common/Nuke.Common.csproj @@ -27,7 +27,7 @@ - +
From 91516c1e62bdee7fe78c06bec204cb834e5af2ae Mon Sep 17 00:00:00 2001 From: Christian Klemm Date: Wed, 20 Mar 2024 02:54:10 +0100 Subject: [PATCH 15/56] fix(cicd): missing parameters for AzurePipelines.SetVariable (#1316) --- source/Nuke.Common/CI/AzurePipelines/AzurePipelines.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/source/Nuke.Common/CI/AzurePipelines/AzurePipelines.cs b/source/Nuke.Common/CI/AzurePipelines/AzurePipelines.cs index 4701a441d..e82cd11c9 100644 --- a/source/Nuke.Common/CI/AzurePipelines/AzurePipelines.cs +++ b/source/Nuke.Common/CI/AzurePipelines/AzurePipelines.cs @@ -205,14 +205,16 @@ public void LogIssue( .AddPairWhenValueNotNull("code", code)); } - public void SetVariable(string name, string value, bool? isSecret = null) + public void SetVariable(string name, string value, bool? isSecret = null, bool? isOutput = null, bool? isReadOnly = null) { WriteCommand( "task.setvariable", value, dictionaryConfigurator: x => x .AddPair("variable", name) - .AddPairWhenValueNotNull("issecret", isSecret)); + .AddPairWhenValueNotNull("issecret", isSecret) + .AddPairWhenValueNotNull("isoutput", isOutput) + .AddPairWhenValueNotNull("isreadonly", isReadOnly)); } private string GetText(AzurePipelinesIssueType type) From 85655ddf8f2060c71a8e4a8b06bb5b0fda621e28 Mon Sep 17 00:00:00 2001 From: ITaluone <44049228+ITaluone@users.noreply.github.com> Date: Wed, 20 Mar 2024 03:04:57 +0100 Subject: [PATCH 16/56] feat(tooling): add AddUnixSymlink extension (#1309) --- source/Nuke.Tooling/ToolingExtensions.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/source/Nuke.Tooling/ToolingExtensions.cs b/source/Nuke.Tooling/ToolingExtensions.cs index 86ae0f568..5a976b291 100644 --- a/source/Nuke.Tooling/ToolingExtensions.cs +++ b/source/Nuke.Tooling/ToolingExtensions.cs @@ -32,6 +32,14 @@ public static AbsolutePath SetExecutable(this AbsolutePath path, bool updateVcsI return path; } + public static AbsolutePath AddUnixSymlink(this AbsolutePath path, AbsolutePath linkPath, bool force = false) + { + if (EnvironmentInfo.IsUnix) + ProcessTasks.StartProcess("ln", $"-s{(force ? "f" : "")} {path} {linkPath}", logInvocation: false, logOutput: false); + + return path; + } + public static AbsolutePath SetUnixPermissions(this AbsolutePath path, string permissions) { if (EnvironmentInfo.IsUnix) From b74711517e3e063fc2471e335c65b5e665f5b2a9 Mon Sep 17 00:00:00 2001 From: ITaluone <44049228+ITaluone@users.noreply.github.com> Date: Wed, 20 Mar 2024 03:14:56 +0100 Subject: [PATCH 17/56] fix(tools): missing DotNetTasks arguments (#1314) --- source/Nuke.Common/Tools/DotNet/DotNet.json | 24 +++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/source/Nuke.Common/Tools/DotNet/DotNet.json b/source/Nuke.Common/Tools/DotNet/DotNet.json index 0442d6fea..e59216b7c 100644 --- a/source/Nuke.Common/Tools/DotNet/DotNet.json +++ b/source/Nuke.Common/Tools/DotNet/DotNet.json @@ -1202,6 +1202,12 @@ "format": "--skip-manifest-update", "help": "Skip updating the workload manifests. The workload manifests define what assets and versions need to be installed for each workload." }, + { + "name": "SkipSignCheck", + "type": "bool", + "format": "--skip-sign-check", + "help": "Skipping the nuget package signature verification." + }, { "name": "Source", "type": "string", @@ -1294,6 +1300,12 @@ "format": "--skip-manifest-update", "help": "Skip updating the workload manifests. The workload manifests define what assets and versions need to be installed for each workload." }, + { + "name": "SkipSignCheck", + "type": "bool", + "format": "--skip-sign-check", + "help": "Skipping the nuget package signature verification." + }, { "name": "Source", "type": "string", @@ -1370,6 +1382,12 @@ "format": "--no-cache", "help": "Prevents caching of packages and http requests." }, + { + "name": "SkipSignCheck", + "type": "bool", + "format": "--skip-sign-check", + "help": "Skipping the nuget package signature verification." + }, { "name": "Source", "type": "string", @@ -1434,6 +1452,12 @@ "format": "--no-cache", "help": "Prevents caching of packages and http requests." }, + { + "name": "SkipSignCheck", + "type": "bool", + "format": "--skip-sign-check", + "help": "Skipping the nuget package signature verification." + }, { "name": "Source", "type": "string", From b081057dd69add2992b4cc7a729e045b48ca672d Mon Sep 17 00:00:00 2001 From: Matthias Koch Date: Thu, 21 Mar 2024 08:26:50 +0100 Subject: [PATCH 18/56] Update CONTRIBUTING.md --- CONTRIBUTING.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 561e2cc95..dfa69c59d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -54,6 +54,7 @@ Evaluate whether your topic is going to be a valid issue: - Have you checked the [FAQ](https://nuke.build/faq/)? - Is your issue more of a question? Ask on [GitHub discussions](https://github.com/nuke-build/nuke/discussions), [Slack](https://nuke.build/slack), or [Discord](https://nuke.build/discord)! - Have you checked existing/closed issues? Is your version behind? +- Have you read the relevant [changelog notes](https://github.com/nuke-build/nuke/blob/develop/CHANGELOG.md)? - Have you verified it's not an external tool issue? Invoke the command manually! - Don't file issues for tool wrappers. Send a pull request instead! - Refrain from debating the governance or state of the project out of your own interests (see [consumer expectations](#consumer-expectations) & [sustainability contributions](#sustainability-contributions)) From 540c5aac79321ee708bee3fa6e1242651ab840f9 Mon Sep 17 00:00:00 2001 From: Matthias Koch Date: Sun, 31 Mar 2024 04:10:42 +0200 Subject: [PATCH 19/56] feat(utilities): implement AbsolutePath copy/move --- source/Nuke.Common/IO/FileSystemTasks.cs | 9 + .../IO/FileSystemDependentTest.cs | 2 +- .../Nuke.Utilities.Tests/IO/MoveCopyTest.cs | 135 +++++++++++ .../Collections/Enumerable.WhereNotNull.cs | 9 + .../IO/AbsolutePath.MoveCopy.cs | 226 ++++++++++++++++-- 5 files changed, 359 insertions(+), 22 deletions(-) create mode 100644 source/Nuke.Utilities.Tests/IO/MoveCopyTest.cs diff --git a/source/Nuke.Common/IO/FileSystemTasks.cs b/source/Nuke.Common/IO/FileSystemTasks.cs index 48e9c24d4..a2062784f 100644 --- a/source/Nuke.Common/IO/FileSystemTasks.cs +++ b/source/Nuke.Common/IO/FileSystemTasks.cs @@ -188,6 +188,7 @@ public static void DeleteFile(string file) File.Delete(file); } + [Obsolete($"Use {nameof(AbsolutePath)}.{nameof(AbsolutePathExtensions.Copy)}")] public static void CopyFile(AbsolutePath source, AbsolutePath target, FileExistsPolicy policy = FileExistsPolicy.Fail, bool createDirectories = true) { if (!ShouldCopyFile(source, target, policy)) @@ -200,6 +201,7 @@ public static void CopyFile(AbsolutePath source, AbsolutePath target, FileExists File.Copy(source, target, overwrite: true); } + [Obsolete($"Use {nameof(AbsolutePath)}.{nameof(AbsolutePathExtensions.CopyToDirectory)}")] public static void CopyFileToDirectory( AbsolutePath source, AbsolutePath targetDirectory, @@ -209,6 +211,7 @@ public static void CopyFileToDirectory( CopyFile(source, Path.Combine(targetDirectory, Path.GetFileName(source).NotNull()), policy, createDirectories); } + [Obsolete($"Use {nameof(AbsolutePath)}.{nameof(AbsolutePathExtensions.Move)}")] public static void MoveFile(AbsolutePath source, AbsolutePath target, FileExistsPolicy policy = FileExistsPolicy.Fail, bool createDirectories = true) { if (!ShouldCopyFile(source, target, policy)) @@ -224,6 +227,7 @@ public static void MoveFile(AbsolutePath source, AbsolutePath target, FileExists File.Move(source, target); } + [Obsolete($"Use {nameof(AbsolutePath)}.{nameof(AbsolutePathExtensions.MoveToDirectory)}")] public static void MoveFileToDirectory( AbsolutePath source, AbsolutePath targetDirectory, @@ -233,6 +237,7 @@ public static void MoveFileToDirectory( MoveFile(source, Path.Combine(targetDirectory, Path.GetFileName(source).NotNull()), policy, createDirectories); } + [Obsolete($"Use {nameof(AbsolutePath)}.{nameof(AbsolutePathExtensions.Rename)}")] public static void RenameFile(AbsolutePath file, string newName, FileExistsPolicy policy = FileExistsPolicy.Fail) { if (Path.GetFileName(file) == newName) @@ -241,6 +246,7 @@ public static void RenameFile(AbsolutePath file, string newName, FileExistsPolic MoveFile(file, Path.Combine(Path.GetDirectoryName(file).NotNull(), newName), policy); } + [Obsolete($"Use {nameof(AbsolutePath)}.{nameof(AbsolutePathExtensions.Move)}")] public static void MoveDirectory( AbsolutePath source, AbsolutePath target, @@ -264,6 +270,7 @@ public static void MoveDirectory( } } + [Obsolete($"Use {nameof(AbsolutePath)}.{nameof(AbsolutePathExtensions.MoveToDirectory)}")] public static void MoveDirectoryToDirectory( AbsolutePath source, AbsolutePath targetDirectory, @@ -273,6 +280,7 @@ public static void MoveDirectoryToDirectory( MoveDirectory(source, Path.Combine(targetDirectory, new DirectoryInfo(source).Name), directoryPolicy, filePolicy); } + [Obsolete($"Use {nameof(AbsolutePath)}.{nameof(AbsolutePathExtensions.Rename)}")] public static void RenameDirectory( string directory, string newName, @@ -282,6 +290,7 @@ public static void RenameDirectory( MoveDirectory(directory, Path.Combine(Path.GetDirectoryName(directory).NotNull(), newName), directoryPolicy, filePolicy); } + [Obsolete($"Use {nameof(AbsolutePath)}.{nameof(AbsolutePathExtensions.Copy)}")] public static void CopyDirectoryRecursively( AbsolutePath source, AbsolutePath target, diff --git a/source/Nuke.Utilities.Tests/IO/FileSystemDependentTest.cs b/source/Nuke.Utilities.Tests/IO/FileSystemDependentTest.cs index 927d2dce1..8e721a507 100644 --- a/source/Nuke.Utilities.Tests/IO/FileSystemDependentTest.cs +++ b/source/Nuke.Utilities.Tests/IO/FileSystemDependentTest.cs @@ -32,7 +32,7 @@ protected FileSystemDependentTest(ITestOutputHelper testOutputHelper) ExecutionDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location).NotNull(); RootDirectory = Constants.TryGetRootDirectoryFrom(EnvironmentInfo.WorkingDirectory); TestProjectDirectory = ExecutionDirectory.FindParentOrSelf(x => x.ContainsFile("*.csproj")); - TestTempDirectory = ExecutionDirectory / "temp" / $"{GetType().Name}.{TestName}"; + TestTempDirectory = ExecutionDirectory / "temp" / $"{GetType().Name}.{TestName}"; TestTempDirectory.CreateOrCleanDirectory(); } diff --git a/source/Nuke.Utilities.Tests/IO/MoveCopyTest.cs b/source/Nuke.Utilities.Tests/IO/MoveCopyTest.cs new file mode 100644 index 000000000..85f1c74b2 --- /dev/null +++ b/source/Nuke.Utilities.Tests/IO/MoveCopyTest.cs @@ -0,0 +1,135 @@ +// Copyright 2024 Maintainers of NUKE. +// Distributed under the MIT License. +// https://github.com/nuke-build/nuke/blob/master/LICENSE + +using System; +using System.Linq; +using FluentAssertions; +using Nuke.Common.IO; +using Nuke.Common.Utilities.Collections; +using Xunit; +using Xunit.Abstractions; + +namespace Nuke.Common.Tests; + +public class MoveCopyTest : FileSystemDependentTest +{ + public MoveCopyTest(ITestOutputHelper testOutputHelper) : base(testOutputHelper) + { + AbsolutePathExtensions.DefaultEofLineBreak = false; + } + + [Fact] + public void TestCopyFile() + { + var source = TestTempDirectory / "source.txt"; + source.WriteAllText("foobar"); + + var target = TestTempDirectory / "target.txt"; + source.Copy(target); + + target.FileExists().Should().BeTrue(); + + new Action(() => source.Copy(target)) + .Should().Throw().WithMessage("* already exists"); + + new Action(() => source.Copy(target, policy: ExistsPolicy.FileFail | ExistsPolicy.FileOverwrite)) + .Should().Throw().WithMessage("Multiple file policies *"); + + source.WriteAllText("fizzbuzz"); + source.Copy(target, policy: ExistsPolicy.FileOverwrite) + .Should().Be(target); + target.ReadAllText().Should().Be("fizzbuzz"); + } + + [Fact] + public void TestMoveFile() + { + var source1 = (TestTempDirectory / "source1.txt").TouchFile(); + var source2 = (TestTempDirectory / "source2.txt").TouchFile(); + var source3 = (TestTempDirectory / "source3.txt").TouchFile(); + + var target = TestTempDirectory / "target.txt"; + source2.Move(target); + + target.FileExists().Should().BeTrue(); + source2.FileExists().Should().BeFalse(); + + new Action(() => source1.Move(target, policy: ExistsPolicy.FileFail)) + .Should().Throw().WithMessage("* already exists"); + + source1.Move(target, policy: ExistsPolicy.FileSkip).Should().Be(source1); + source1.Move(target, policy: ExistsPolicy.FileOverwriteIfNewer).Should().Be(source1); + + source3.TouchFile(); + source3.Move(target, policy: ExistsPolicy.FileOverwriteIfNewer).Should().Be(target); + } + + [Fact] + public void TestCopyDirectory() + { + var source = TestTempDirectory / "source"; + var sourceFiles = new[] + { + source / "source1.txt", + source / "source2.txt", + source / "sub" / "source3.txt", + source / "sub" / "source4.txt", + }; + sourceFiles.ForEach(x => x.WriteAllText("source")); + + var target = TestTempDirectory / "target"; + source.Copy(target); + target.GetFiles(depth: int.MaxValue).Select(x => target.GetRelativePathTo(x).ToString()) + .Should().BeEquivalentTo(sourceFiles.Select(x => source.GetRelativePathTo(x).ToString())); + + target.CreateOrCleanDirectory(); + var target0 = (target / "source0.txt").TouchFile(); + var target3 = (target / "sub" / "source3.txt").WriteAllText("target"); + var target4 = (target / "sub" / "source4.txt").WriteAllText("target"); + (source / target.GetRelativePathTo(target4)).TouchFile(); + + new Action(() => source.Copy(target, ExistsPolicy.DirectoryFail)) + .Should().Throw().WithMessage("Policy disallows merging directories"); + target.GetFiles(depth: int.MaxValue).Should().HaveCount(3); + + source.Copy(target, ExistsPolicy.MergeAndSkip); + target0.FileExists().Should().BeTrue(); + target3.ReadAllText().Should().Be("target"); + target4.ReadAllText().Should().Be("target"); + + source.Copy(target, ExistsPolicy.MergeAndOverwriteIfNewer); + target3.ReadAllText().Should().Be("target"); + target4.ReadAllText().Should().Be("source"); + + source.Copy(target, ExistsPolicy.MergeAndOverwrite); + target3.ReadAllText().Should().Be("source"); + } + + [Fact] + public void TestMoveDirectory() + { + var source = TestTempDirectory / "source"; + var sourceFiles = new[] + { + source / "source1.txt", + source / "source2.txt", + source / "sub" / "source3.txt", + source / "sub" / "source4.txt", + }; + sourceFiles.ForEach(x => x.WriteAllText("source")); + + var target = TestTempDirectory / "target"; + (target / "source1.txt").TouchFile(); + (target / "sub" / "source3.txt").TouchFile(); + + new Action(() => source.Move(target)).Should().Throw(); + + source.Move(target, ExistsPolicy.MergeAndSkip); + source.GetFiles(depth: int.MaxValue).Should().HaveCount(2); + + source.Move(target, ExistsPolicy.MergeAndSkip, deleteRemainingFiles: true) + .Should().Be(target); + source.DirectoryExists().Should().BeFalse(); + } +} diff --git a/source/Nuke.Utilities/Collections/Enumerable.WhereNotNull.cs b/source/Nuke.Utilities/Collections/Enumerable.WhereNotNull.cs index 7e480da59..4ee4180ae 100644 --- a/source/Nuke.Utilities/Collections/Enumerable.WhereNotNull.cs +++ b/source/Nuke.Utilities/Collections/Enumerable.WhereNotNull.cs @@ -18,4 +18,13 @@ public static IEnumerable WhereNotNull(this IEnumerable enumerable) { return enumerable.Where(x => x != null); } + + /// + /// Filters the collection to elements that don't meet the condition. + /// + public static IEnumerable WhereNot(this IEnumerable enumerable, Func condition) + where T : class + { + return enumerable.Where(x => condition == null || !condition(x)); + } } diff --git a/source/Nuke.Utilities/IO/AbsolutePath.MoveCopy.cs b/source/Nuke.Utilities/IO/AbsolutePath.MoveCopy.cs index 7535a7a54..f7fb7c9f8 100644 --- a/source/Nuke.Utilities/IO/AbsolutePath.MoveCopy.cs +++ b/source/Nuke.Utilities/IO/AbsolutePath.MoveCopy.cs @@ -4,73 +4,257 @@ using System; using System.IO; +using System.Linq; +using Nuke.Common.Utilities.Collections; namespace Nuke.Common.IO; +[Flags] +public enum ExistsPolicy +{ + DirectoryFail = 1, + DirectoryMerge = 2, + FileFail = 4, + FileSkip = 8, + FileOverwrite = 16, + FileOverwriteIfNewer = 32, + + Fail = DirectoryFail | FileFail, + MergeAndSkip = DirectoryMerge | FileSkip, + MergeAndOverwrite = DirectoryMerge | FileOverwrite, + MergeAndOverwriteIfNewer = DirectoryMerge | FileOverwriteIfNewer +} + partial class AbsolutePathExtensions { /// /// Renames the file or directory. /// - public static AbsolutePath Rename(this AbsolutePath path, string newName) + public static AbsolutePath Rename( + this AbsolutePath source, + string newName, + ExistsPolicy policy = ExistsPolicy.Fail) { - return path.Move(path.Parent / newName); + return source.Move(source.Parent / newName, policy); } /// /// Renames the file or directory. /// - public static AbsolutePath Rename(this AbsolutePath path, Func newName) + public static AbsolutePath Rename( + this AbsolutePath source, + Func newName, + ExistsPolicy policy = ExistsPolicy.Fail) { - return path.Rename(newName.Invoke(path)); + return source.Rename(newName.Invoke(source), policy); } /// /// Renames the file without changing the extension. /// - public static AbsolutePath RenameWithoutExtension(this AbsolutePath path, string newName) + public static AbsolutePath RenameWithoutExtension( + this AbsolutePath source, + string newName, + ExistsPolicy policy = ExistsPolicy.Fail) { - Assert.True(path.FileExists()); - return path.Move(path.Parent / newName + path.Extension); + return source.Move(source.Parent / newName + source.Extension, policy); } /// /// Renames the file without changing the extension. /// - public static AbsolutePath RenameWithoutExtension(this AbsolutePath path, Func newName) + public static AbsolutePath RenameWithoutExtension( + this AbsolutePath source, + Func newName, + ExistsPolicy policy = ExistsPolicy.Fail) { - return path.RenameWithoutExtension(newName.Invoke(path)); + return source.RenameWithoutExtension(newName.Invoke(source), policy); } /// /// Moves the file or directory to another directory. /// - public static AbsolutePath MoveToDirectory(this AbsolutePath path, AbsolutePath directory) + public static AbsolutePath MoveToDirectory( + this AbsolutePath source, + AbsolutePath target, + ExistsPolicy policy = ExistsPolicy.Fail, + bool createDirectories = true) { - Assert.True(directory.Exists()); - return path.Move(directory / path.Name); + return source.Move(target / source.Name, policy, createDirectories); + } + + /// + /// Copies the file or directory to another directory. + /// + public static AbsolutePath CopyToDirectory( + this AbsolutePath source, + AbsolutePath target, + ExistsPolicy policy = ExistsPolicy.Fail, + Func excludeDirectory = null, + Func excludeFile = null, + bool createDirectories = true) + { + return source.Copy(target / source.Name, policy, excludeDirectory, excludeFile, createDirectories); } /// /// Moves the file or directory. /// - public static AbsolutePath Move(this AbsolutePath path, Func newPath) + public static AbsolutePath Move( + this AbsolutePath source, + Func newPath, + ExistsPolicy policy = ExistsPolicy.Fail, + bool createDirectories = true) { - return path.Move(newPath.Invoke(path)); + return source.Move(newPath.Invoke(source), policy, createDirectories); } /// /// Moves the file or directory. /// - public static AbsolutePath Move(this AbsolutePath path, AbsolutePath newPath) + public static AbsolutePath Move( + this AbsolutePath source, + AbsolutePath target, + ExistsPolicy policy = ExistsPolicy.Fail, + bool createDirectories = true, + bool deleteRemainingFiles = false) + { + Assert.True(source.DirectoryExists() || source.FileExists()); + + if (source.DirectoryExists()) + return MoveDirectory(source, target, policy, createDirectories, deleteRemainingFiles); + + if (source.FileExists()) + return MoveFile(source, target, policy, createDirectories); + + throw new Exception("Unreachable"); + } + + /// + /// Copies the file or directory. + /// + public static AbsolutePath Copy( + this AbsolutePath source, + AbsolutePath target, + ExistsPolicy policy = ExistsPolicy.Fail, + Func excludeDirectory = null, + Func excludeFile = null, + bool createDirectories = true) + { + Assert.True(source.DirectoryExists() || source.FileExists()); + + if (source.DirectoryExists()) + return CopyDirectory(source, target, policy, excludeDirectory, excludeFile, createDirectories); + + if (source.FileExists()) + return CopyFile(source, target, policy, createDirectories); + + throw new Exception("Unreachable"); + } + + private static AbsolutePath MoveFile( + this AbsolutePath source, + AbsolutePath target, + ExistsPolicy policy = ExistsPolicy.Fail, + bool createDirectories = true) + { + return HandleFile(source, target, policy, createDirectories, () => + { + target.DeleteFile(); + File.Move(source, target); + }); + } + + private static AbsolutePath CopyFile( + this AbsolutePath source, + AbsolutePath target, + ExistsPolicy policy = ExistsPolicy.Fail, + bool createDirectories = true) + { + return HandleFile(source, target, policy, createDirectories, () => + { + File.Copy(source, target, overwrite: true); + }); + } + + private static AbsolutePath HandleFile( + AbsolutePath source, + AbsolutePath target, + ExistsPolicy policy, + bool createDirectories, + Action action) + { + if (File.Exists(target) && !Permitted()) + return source; + + if (createDirectories) + target.Parent.CreateDirectory(); + + action.Invoke(); + return target; + + bool Permitted() + { + var filePolicies = ExistsPolicy.FileFail | ExistsPolicy.FileSkip | ExistsPolicy.FileOverwrite | ExistsPolicy.FileOverwriteIfNewer; + return (policy & filePolicies) switch + { + ExistsPolicy.FileFail => throw new Exception($"File '{target}' already exists"), + ExistsPolicy.FileSkip => false, + ExistsPolicy.FileOverwrite => true, + ExistsPolicy.FileOverwriteIfNewer => File.GetLastWriteTimeUtc(target) < File.GetLastWriteTimeUtc(source), + _ => throw new ArgumentOutOfRangeException(nameof(policy), policy, message: "Multiple file policies set") + }; + } + } + + private static AbsolutePath MoveDirectory( + this AbsolutePath source, + AbsolutePath target, + ExistsPolicy policy = ExistsPolicy.Fail, + bool createDirectories = true, + bool deleteRemainingFiles = false) + { + return HandleDirectory(source, target, policy, createDirectories, () => + { + source.GetDirectories().ForEach(x => x.MoveDirectory(target / source.GetRelativePathTo(x), policy)); + source.GetFiles().ForEach(x => x.MoveFile(target / source.GetRelativePathTo(x), policy)); + + if (!source.ToDirectoryInfo().EnumerateFileSystemInfos().Any() || deleteRemainingFiles) + source.DeleteDirectory(); + }); + } + + private static AbsolutePath CopyDirectory( + this AbsolutePath source, + AbsolutePath target, + ExistsPolicy policy = ExistsPolicy.Fail, + Func excludeDirectory = null, + Func excludeFile = null, + bool createDirectories = true) + { + return HandleDirectory(source, target, policy, createDirectories, () => + { + source.GetDirectories().WhereNot(excludeDirectory).ForEach(x => x.CopyDirectory(target / source.GetRelativePathTo(x), policy, excludeDirectory, excludeFile)); + source.GetFiles().WhereNot(excludeFile).ForEach(x => x.CopyFile(target / source.GetRelativePathTo(x), policy)); + }); + } + + private static AbsolutePath HandleDirectory( + AbsolutePath source, + AbsolutePath target, + ExistsPolicy policy, + bool createDirectories, + Action action) { - Assert.True(path.DirectoryExists() || path.FileExists()); + Assert.DirectoryExists(source); + Assert.False(source.Contains(target), $"Target directory '{target}' must not be in source directory '{source}'"); + Assert.True(!Directory.Exists(target) || (policy.HasFlag(ExistsPolicy.DirectoryMerge) && !policy.HasFlag(ExistsPolicy.DirectoryFail)), + "Policy disallows merging directories"); - if (path.DirectoryExists()) - Directory.Move(path, newPath); - else if (path.FileExists()) - File.Move(path, newPath); + if (createDirectories) + target.CreateDirectory(); - return path; + action.Invoke(); + return target; } } From 86fc7ca2a81cd4934497c12e61e1b5422fcd1779 Mon Sep 17 00:00:00 2001 From: Matthias Koch Date: Sun, 31 Mar 2024 04:18:21 +0200 Subject: [PATCH 20/56] chore: update FileSystemTasks usages --- build/Build.GlobalSolution.cs | 11 ++++------- source/Nuke.Common/Tools/ReSharper/ReSharperTasks.cs | 8 +++----- source/Nuke.Common/Utilities/TemplateUtility.cs | 10 ++-------- 3 files changed, 9 insertions(+), 20 deletions(-) diff --git a/build/Build.GlobalSolution.cs b/build/Build.GlobalSolution.cs index c601c8838..4e2107570 100644 --- a/build/Build.GlobalSolution.cs +++ b/build/Build.GlobalSolution.cs @@ -15,7 +15,6 @@ using Nuke.Common.Utilities; using Nuke.Utilities.Text.Yaml; using static Nuke.Common.ControlFlow; -using static Nuke.Common.IO.FileSystemTasks; using static Nuke.Common.ProjectModel.SolutionModelTasks; using static Nuke.Common.Tools.Git.GitTasks; @@ -67,18 +66,16 @@ IEnumerable ExternalRepositories if ((RootDirectory / $"{Solution.FileName}.DotSettings").FileExists()) { - CopyFile( - source: RootDirectory / $"{Solution.FileName}.DotSettings", + (RootDirectory / $"{Solution.FileName}.DotSettings").Copy( target: RootDirectory / $"{global.FileName}.DotSettings", - FileExistsPolicy.Overwrite); + policy: ExistsPolicy.FileOverwrite); } if ((RootDirectory / $"{Solution.FileName}.DotSettings.user").FileExists()) { - CopyFile( - source: RootDirectory / $"{Solution.FileName}.DotSettings.user", + (RootDirectory / $"{Solution.FileName}.DotSettings.user").Copy( target: RootDirectory / $"{global.FileName}.DotSettings.user", - FileExistsPolicy.Overwrite); + policy: ExistsPolicy.FileOverwrite); } }); } diff --git a/source/Nuke.Common/Tools/ReSharper/ReSharperTasks.cs b/source/Nuke.Common/Tools/ReSharper/ReSharperTasks.cs index 67b246bf3..23f8375b8 100644 --- a/source/Nuke.Common/Tools/ReSharper/ReSharperTasks.cs +++ b/source/Nuke.Common/Tools/ReSharper/ReSharperTasks.cs @@ -26,11 +26,9 @@ private static void PreProcess(ref T toolSettings) where T : ReSharperSetting var wave = GetWave(toolSettings).NotNull("wave != null"); var shadowDirectory = GetShadowDirectory(toolSettings, wave); - FileSystemTasks.CopyDirectoryRecursively( - Path.GetDirectoryName(toolSettings.ProcessToolPath).NotNull(), - shadowDirectory, - DirectoryExistsPolicy.Merge, - FileExistsPolicy.OverwriteIfNewer); + ((AbsolutePath)toolSettings.ProcessToolPath.NotNull()).Copy( + target: shadowDirectory, + policy: ExistsPolicy.MergeAndOverwriteIfNewer); toolSettings.Plugins .Select(x => (Plugin: x.Key, Version: x.Value == ReSharperPluginLatest ? null : x.Value)) diff --git a/source/Nuke.Common/Utilities/TemplateUtility.cs b/source/Nuke.Common/Utilities/TemplateUtility.cs index f8fc14758..7dc604d5c 100644 --- a/source/Nuke.Common/Utilities/TemplateUtility.cs +++ b/source/Nuke.Common/Utilities/TemplateUtility.cs @@ -88,20 +88,14 @@ private static void FillTemplateDirectoryRecursivelyInternal( FillTemplateFile(file, tokens); if (ShouldMove(file)) - FileSystemTasks.RenameFile(file, file.Name.Replace(tokens), FileExistsPolicy.OverwriteIfNewer); + file.Rename(file.Name.Replace(tokens), ExistsPolicy.FileOverwriteIfNewer); } directory.GetDirectories() .ForEach(x => FillTemplateDirectoryRecursivelyInternal(x, tokens, excludeDirectory, excludeFile)); if (ShouldMove(directory)) - { - FileSystemTasks.RenameDirectory( - directory, - directory.Name.Replace(tokens), - DirectoryExistsPolicy.Merge, - FileExistsPolicy.OverwriteIfNewer); - } + directory.Rename(directory.Name.Replace(tokens), ExistsPolicy.MergeAndOverwriteIfNewer); } public static void FillTemplateFile( From f7cb58b9ff332e88ad0de20ee985287edc871be2 Mon Sep 17 00:00:00 2001 From: Matthias Koch Date: Thu, 13 Jun 2024 01:16:25 +0200 Subject: [PATCH 21/56] build: update dependencies --- source/Directory.Build.props | 14 +++++++------- source/Nuke.Build.Shared/Nuke.Build.Shared.csproj | 2 +- source/Nuke.Build.Tests/SchemaUtilityTest.cs | 1 - source/Nuke.Build/Nuke.Build.csproj | 6 +++--- .../CI/ConfigurationGenerationTest.cs | 1 - source/Nuke.Common.Tests/ChangelogTasksTest.cs | 1 - source/Nuke.Common/Nuke.Common.csproj | 10 +++++----- source/Nuke.Components/ISignPackages.cs | 4 ++-- .../Nuke.GlobalTool.Tests/CakeConversionTests.cs | 1 - .../Nuke.GlobalTool.Tests.csproj | 2 +- .../UpdateSolutionFileContentTests.cs | 1 - source/Nuke.GlobalTool/Nuke.GlobalTool.csproj | 8 ++++---- source/Nuke.MSBuildTasks/Nuke.MSBuildTasks.csproj | 6 +++--- source/Nuke.ProjectModel.Tests/ProjectModelTest.cs | 2 +- source/Nuke.ProjectModel/Nuke.ProjectModel.csproj | 2 +- .../Nuke.SourceGenerators.Tests.csproj | 6 +++--- .../StronglyTypedSolutionGeneratorTest.cs | 1 - .../Nuke.Tooling.Generator.csproj | 4 ++-- source/Nuke.Tooling/Nuke.Tooling.csproj | 4 ++-- .../Nuke.Utilities.Text.Yaml.csproj | 2 +- 20 files changed, 36 insertions(+), 42 deletions(-) diff --git a/source/Directory.Build.props b/source/Directory.Build.props index 11a271277..c67af9847 100644 --- a/source/Directory.Build.props +++ b/source/Directory.Build.props @@ -40,15 +40,15 @@ - + - - - - + + + + - - + + diff --git a/source/Nuke.Build.Shared/Nuke.Build.Shared.csproj b/source/Nuke.Build.Shared/Nuke.Build.Shared.csproj index 12264e3bb..360fe16cb 100644 --- a/source/Nuke.Build.Shared/Nuke.Build.Shared.csproj +++ b/source/Nuke.Build.Shared/Nuke.Build.Shared.csproj @@ -9,7 +9,7 @@ - + diff --git a/source/Nuke.Build.Tests/SchemaUtilityTest.cs b/source/Nuke.Build.Tests/SchemaUtilityTest.cs index 8befcc066..cb29d2472 100644 --- a/source/Nuke.Build.Tests/SchemaUtilityTest.cs +++ b/source/Nuke.Build.Tests/SchemaUtilityTest.cs @@ -13,7 +13,6 @@ namespace Nuke.Common.Tests; -[UsesVerify] public class SchemaUtilityTest { [Fact] diff --git a/source/Nuke.Build/Nuke.Build.csproj b/source/Nuke.Build/Nuke.Build.csproj index e5cc4b115..f30534e9c 100644 --- a/source/Nuke.Build/Nuke.Build.csproj +++ b/source/Nuke.Build/Nuke.Build.csproj @@ -17,11 +17,11 @@ - + - + - + diff --git a/source/Nuke.Common.Tests/CI/ConfigurationGenerationTest.cs b/source/Nuke.Common.Tests/CI/ConfigurationGenerationTest.cs index 8d3ffbbca..77d15ef7a 100644 --- a/source/Nuke.Common.Tests/CI/ConfigurationGenerationTest.cs +++ b/source/Nuke.Common.Tests/CI/ConfigurationGenerationTest.cs @@ -21,7 +21,6 @@ namespace Nuke.Common.Tests.CI; -[UsesVerify] public class ConfigurationGenerationTest { [Theory] diff --git a/source/Nuke.Common.Tests/ChangelogTasksTest.cs b/source/Nuke.Common.Tests/ChangelogTasksTest.cs index d6632f85a..46c7eb2e5 100644 --- a/source/Nuke.Common.Tests/ChangelogTasksTest.cs +++ b/source/Nuke.Common.Tests/ChangelogTasksTest.cs @@ -17,7 +17,6 @@ namespace Nuke.Common.Tests; -[UsesVerify] public class ChangelogTasksTest { private static AbsolutePath RootDirectory => Constants.TryGetRootDirectoryFrom(EnvironmentInfo.WorkingDirectory).NotNull(); diff --git a/source/Nuke.Common/Nuke.Common.csproj b/source/Nuke.Common/Nuke.Common.csproj index 0a45af6b9..006c19995 100644 --- a/source/Nuke.Common/Nuke.Common.csproj +++ b/source/Nuke.Common/Nuke.Common.csproj @@ -23,11 +23,11 @@ - - - - - + + + + + diff --git a/source/Nuke.Components/ISignPackages.cs b/source/Nuke.Components/ISignPackages.cs index 94e85dafc..c0d288579 100644 --- a/source/Nuke.Components/ISignPackages.cs +++ b/source/Nuke.Components/ISignPackages.cs @@ -79,7 +79,7 @@ public interface ISignPackages : INukeBuild .Executes(async () => { SignPathRequestDirectory.CreateOrCleanDirectory(); - SignPathPackages.ForEach(x => CopyFileToDirectory(x, SignPathRequestDirectory)); + SignPathPackages.ForEach(x => x.CopyToDirectory(SignPathRequestDirectory)); SignPathRequestDirectory.ZipTo(SignPathRequestArchive); AppVeyor.PushArtifact(SignPathRequestArchive); @@ -114,7 +114,7 @@ await DownloadSignedArtifactFromUrl( x => Path.GetFileName(x), x => Path.GetFileName(x), (x, y) => (SignedPackage: x, UnsignedPackage: y)) - .ForEach(x => CopyFile(x.SignedPackage, x.UnsignedPackage, FileExistsPolicy.Overwrite)); + .ForEach(x => x.SignedPackage.Copy(x.UnsignedPackage, ExistsPolicy.FileOverwrite)); } }); } diff --git a/source/Nuke.GlobalTool.Tests/CakeConversionTests.cs b/source/Nuke.GlobalTool.Tests/CakeConversionTests.cs index 662693a89..a9a56d9c5 100644 --- a/source/Nuke.GlobalTool.Tests/CakeConversionTests.cs +++ b/source/Nuke.GlobalTool.Tests/CakeConversionTests.cs @@ -14,7 +14,6 @@ namespace Nuke.GlobalTool.Tests; -[UsesVerify] public class CakeConversionTests { private static AbsolutePath RootDirectory => Constants.TryGetRootDirectoryFrom(EnvironmentInfo.WorkingDirectory); diff --git a/source/Nuke.GlobalTool.Tests/Nuke.GlobalTool.Tests.csproj b/source/Nuke.GlobalTool.Tests/Nuke.GlobalTool.Tests.csproj index 3bedbf6c9..e1f8b45f4 100644 --- a/source/Nuke.GlobalTool.Tests/Nuke.GlobalTool.Tests.csproj +++ b/source/Nuke.GlobalTool.Tests/Nuke.GlobalTool.Tests.csproj @@ -1,7 +1,7 @@  - net6.0 + net8.0 diff --git a/source/Nuke.GlobalTool.Tests/UpdateSolutionFileContentTests.cs b/source/Nuke.GlobalTool.Tests/UpdateSolutionFileContentTests.cs index 44219354a..fd0b985dd 100644 --- a/source/Nuke.GlobalTool.Tests/UpdateSolutionFileContentTests.cs +++ b/source/Nuke.GlobalTool.Tests/UpdateSolutionFileContentTests.cs @@ -11,7 +11,6 @@ namespace Nuke.GlobalTool.Tests; -[UsesVerify] public class UpdateSolutionFileContentTests { [Theory] diff --git a/source/Nuke.GlobalTool/Nuke.GlobalTool.csproj b/source/Nuke.GlobalTool/Nuke.GlobalTool.csproj index 9eb34e78b..0ecfb735b 100644 --- a/source/Nuke.GlobalTool/Nuke.GlobalTool.csproj +++ b/source/Nuke.GlobalTool/Nuke.GlobalTool.csproj @@ -2,7 +2,7 @@ Exe - net6.0 + net8.0 LatestMajor true nuke @@ -15,9 +15,9 @@ - - - + + + diff --git a/source/Nuke.MSBuildTasks/Nuke.MSBuildTasks.csproj b/source/Nuke.MSBuildTasks/Nuke.MSBuildTasks.csproj index 57c0b11f8..09e9ae94c 100644 --- a/source/Nuke.MSBuildTasks/Nuke.MSBuildTasks.csproj +++ b/source/Nuke.MSBuildTasks/Nuke.MSBuildTasks.csproj @@ -11,13 +11,13 @@ - + - - + + diff --git a/source/Nuke.ProjectModel.Tests/ProjectModelTest.cs b/source/Nuke.ProjectModel.Tests/ProjectModelTest.cs index 11b67ba1b..f50dbda4a 100644 --- a/source/Nuke.ProjectModel.Tests/ProjectModelTest.cs +++ b/source/Nuke.ProjectModel.Tests/ProjectModelTest.cs @@ -28,7 +28,7 @@ public void ProjectTest() project.GetTargetFrameworks().Should().Equal("net6.0", "net7.0", "net8.0"); project.HasPackageReference("Microsoft.Build.Locator").Should().BeTrue(); - project.GetPackageReferenceVersion("Microsoft.Build.Locator").Should().Be("1.6.10"); + project.GetPackageReferenceVersion("Microsoft.Build.Locator").Should().Be("1.7.8"); } [Fact] diff --git a/source/Nuke.ProjectModel/Nuke.ProjectModel.csproj b/source/Nuke.ProjectModel/Nuke.ProjectModel.csproj index cf7b4233b..d3875675f 100644 --- a/source/Nuke.ProjectModel/Nuke.ProjectModel.csproj +++ b/source/Nuke.ProjectModel/Nuke.ProjectModel.csproj @@ -11,7 +11,7 @@ - + diff --git a/source/Nuke.SourceGenerators.Tests/Nuke.SourceGenerators.Tests.csproj b/source/Nuke.SourceGenerators.Tests/Nuke.SourceGenerators.Tests.csproj index be392715b..906167b4e 100644 --- a/source/Nuke.SourceGenerators.Tests/Nuke.SourceGenerators.Tests.csproj +++ b/source/Nuke.SourceGenerators.Tests/Nuke.SourceGenerators.Tests.csproj @@ -12,10 +12,10 @@ - - + + - + diff --git a/source/Nuke.SourceGenerators.Tests/StronglyTypedSolutionGeneratorTest.cs b/source/Nuke.SourceGenerators.Tests/StronglyTypedSolutionGeneratorTest.cs index 8a494b83a..35117882f 100644 --- a/source/Nuke.SourceGenerators.Tests/StronglyTypedSolutionGeneratorTest.cs +++ b/source/Nuke.SourceGenerators.Tests/StronglyTypedSolutionGeneratorTest.cs @@ -15,7 +15,6 @@ namespace Nuke.SourceGenerators.Tests; -[UsesVerify] public class StronglyTypedSolutionGeneratorTest { [Fact] diff --git a/source/Nuke.Tooling.Generator/Nuke.Tooling.Generator.csproj b/source/Nuke.Tooling.Generator/Nuke.Tooling.Generator.csproj index c4f4f730f..713acf1db 100644 --- a/source/Nuke.Tooling.Generator/Nuke.Tooling.Generator.csproj +++ b/source/Nuke.Tooling.Generator/Nuke.Tooling.Generator.csproj @@ -6,10 +6,10 @@ - + - + diff --git a/source/Nuke.Tooling/Nuke.Tooling.csproj b/source/Nuke.Tooling/Nuke.Tooling.csproj index bc0de0ef9..002f32571 100644 --- a/source/Nuke.Tooling/Nuke.Tooling.csproj +++ b/source/Nuke.Tooling/Nuke.Tooling.csproj @@ -10,8 +10,8 @@ - - + + diff --git a/source/Nuke.Utilities.Text.Yaml/Nuke.Utilities.Text.Yaml.csproj b/source/Nuke.Utilities.Text.Yaml/Nuke.Utilities.Text.Yaml.csproj index bc6efbcc0..1cd42cb3d 100644 --- a/source/Nuke.Utilities.Text.Yaml/Nuke.Utilities.Text.Yaml.csproj +++ b/source/Nuke.Utilities.Text.Yaml/Nuke.Utilities.Text.Yaml.csproj @@ -9,7 +9,7 @@ - + From 18efbd9836eff6d514bf975e2da07f605fa5c5e9 Mon Sep 17 00:00:00 2001 From: Matthias Koch Date: Thu, 13 Jun 2024 01:30:47 +0200 Subject: [PATCH 22/56] fix(tooling): unquoting of multiple quoted arguments --- source/Nuke.Tooling.Tests/ArgumentStringHandlerTest.cs | 1 + source/Nuke.Tooling/ArgumentStringHandler.cs | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/source/Nuke.Tooling.Tests/ArgumentStringHandlerTest.cs b/source/Nuke.Tooling.Tests/ArgumentStringHandlerTest.cs index be61ff664..394cee0a5 100644 --- a/source/Nuke.Tooling.Tests/ArgumentStringHandlerTest.cs +++ b/source/Nuke.Tooling.Tests/ArgumentStringHandlerTest.cs @@ -83,6 +83,7 @@ public void TestUnquote() ArgsToString($"{"start end"}").Should().Be("start end"); ArgsToString($"start {"spaced end"}").Should().Be("start \"spaced end\""); ArgsToString($"{"spaced start"} end").Should().Be("\"spaced start\" end"); + ArgsToString($"{"spaced start"} {"spaced end"}").Should().Be("\"spaced start\" \"spaced end\""); } [Fact] diff --git a/source/Nuke.Tooling/ArgumentStringHandler.cs b/source/Nuke.Tooling/ArgumentStringHandler.cs index c85f86fc0..19f134f0e 100644 --- a/source/Nuke.Tooling/ArgumentStringHandler.cs +++ b/source/Nuke.Tooling/ArgumentStringHandler.cs @@ -80,7 +80,10 @@ public void AppendFormatted(IEnumerable paths, int alignmen public string ToStringAndClear() { - return _builder.ToStringAndClear().TrimMatchingDoubleQuotes(); + var value = _builder.ToStringAndClear(); + return value.IndexOf(value: '"', startIndex: 1) == value.Length - 1 + ? value.TrimMatchingDoubleQuotes() + : value; } public Func GetFilter() From 0c1e1604d3cd6df4fb7c61b89b0c1b34ded394c6 Mon Sep 17 00:00:00 2001 From: Matthias Koch Date: Thu, 13 Jun 2024 02:47:59 +0200 Subject: [PATCH 23/56] docs: add note about PackageDownload in global builds --- docs/04-sharing/01-global-builds.md | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/docs/04-sharing/01-global-builds.md b/docs/04-sharing/01-global-builds.md index 332cdc5ca..959a43b11 100644 --- a/docs/04-sharing/01-global-builds.md +++ b/docs/04-sharing/01-global-builds.md @@ -23,7 +23,22 @@ As a first step, you need to extend the build project file with the [necessary i ``` -Afterwards, the project can be packaged and deployed as usual: +:::warning +Note that `PackageDownload` can only be used in the .NET global tool project directly, since they [do not work transitively](https://github.com/NuGet/Home/wiki/%5BSpec%5D-PackageDownload-support#package-declaration). Alternatively, you can reference tools the old way via `PackageReference` and set the `ExcludeAssets` property: + +```xml + + + + + + + +``` + +::: + +Afterward, the project can be packaged and deployed as usual: ```powershell # terminal-command From 8df380db6491e441f11a746b654ce52a7893b0cd Mon Sep 17 00:00:00 2001 From: Matthias Koch Date: Thu, 13 Jun 2024 23:07:08 +0200 Subject: [PATCH 24/56] feat(common): use regex pattern for LatestGitHubReleaseAttribute --- build/Build.ReleaseImage.cs | 2 +- .../LatestGitHubReleaseAttribute.cs | 24 +++++++++++++++++-- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/build/Build.ReleaseImage.cs b/build/Build.ReleaseImage.cs index 703dc60f7..02ea6ae6d 100644 --- a/build/Build.ReleaseImage.cs +++ b/build/Build.ReleaseImage.cs @@ -20,7 +20,7 @@ partial class Build { - [LatestGitHubRelease("JetBrains/JetBrainsMono", TrimPrefix = true)] + [LatestGitHubRelease("JetBrains/JetBrainsMono")] readonly string JetBrainsMonoVersion; string[] FontDownloadUrls => diff --git a/source/Nuke.Common/Attributes/LatestGitHubReleaseAttribute.cs b/source/Nuke.Common/Attributes/LatestGitHubReleaseAttribute.cs index bd4d2b219..66dd5d9b7 100644 --- a/source/Nuke.Common/Attributes/LatestGitHubReleaseAttribute.cs +++ b/source/Nuke.Common/Attributes/LatestGitHubReleaseAttribute.cs @@ -5,9 +5,12 @@ using System; using System.Linq; using System.Reflection; +using System.Text.RegularExpressions; using JetBrains.Annotations; +using NuGet.Versioning; using Nuke.Common.Git; using Nuke.Common.Tools.GitHub; +using Nuke.Common.Utilities; using Nuke.Common.ValueInjection; namespace Nuke.Common.Tooling; @@ -23,11 +26,28 @@ public LatestGitHubReleaseAttribute(string identifier) } public bool IncludePrerelease { get; set; } - public bool TrimPrefix { get; set; } + public bool UseTagName { get; set; } + + [RegexPattern] + public string Pattern { get; set; } = @"v?(?\d+\.\d+(?:\.\d+)?(?:\.\d+)?(?:-\w+)?)"; public override object GetValue(MemberInfo member, object instance) { var repository = GitRepository.FromUrl($"https://github.com/{_identifier}"); - return repository.GetLatestRelease(IncludePrerelease, TrimPrefix).GetAwaiter().GetResult(); + var releases = GitHubTasks.GitHubClient.Repository.Release + .GetAll(repository.GetGitHubOwner(), repository.GetGitHubName()).GetAwaiter().GetResult(); + var versions = releases + .Select(x => Regex.Match((!UseTagName ? x.Name : x.TagName).NotNullOrWhiteSpace(), Pattern)) + .Select(x => x.Groups["version"].Value) + .Select(NuGetVersion.Parse) + .OrderByDescending(x => x); + + if (member.GetMemberType() == typeof(NuGetVersion[])) + return versions.ToArray(); + + var latestVersion = versions.FirstOrDefault(x => !x.IsPrerelease || IncludePrerelease); + return member.GetMemberType() == typeof(NuGetVersion) + ? latestVersion + : latestVersion?.ToString(); } } From eddef5ec4def4e65e529e3cc6ba382ccf56631b4 Mon Sep 17 00:00:00 2001 From: Marko Lahma Date: Wed, 3 Jul 2024 19:29:39 +0300 Subject: [PATCH 25/56] feat(cicd): add filter and progress to GitHubActionsAttribute (#1298) --- ...tribute=GitHubActionsAttribute.verified.txt | 12 +++++++++--- ...tribute=GitHubActionsAttribute.verified.txt | 6 +++--- .../CI/ConfigurationGenerationTest.cs | 2 ++ .../Configuration/GitHubActionsCheckoutStep.cs | 10 ++++++++-- .../CI/GitHubActions/GitHubActionsAttribute.cs | 18 +++++++++++++++++- 5 files changed, 39 insertions(+), 9 deletions(-) diff --git a/source/Nuke.Common.Tests/CI/ConfigurationGenerationTest.Test_testName=detailed-triggers_attribute=GitHubActionsAttribute.verified.txt b/source/Nuke.Common.Tests/CI/ConfigurationGenerationTest.Test_testName=detailed-triggers_attribute=GitHubActionsAttribute.verified.txt index baa10b88e..cba457564 100644 --- a/source/Nuke.Common.Tests/CI/ConfigurationGenerationTest.Test_testName=detailed-triggers_attribute=GitHubActionsAttribute.verified.txt +++ b/source/Nuke.Common.Tests/CI/ConfigurationGenerationTest.Test_testName=detailed-triggers_attribute=GitHubActionsAttribute.verified.txt @@ -53,11 +53,13 @@ jobs: group: ${{ github.workflow }} @ ${{ github.event.pull_request.head.label || github.head_ref || github.run_id }} cancel-in-progress: true steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: submodules: recursive lfs: true fetch-depth: 2 + progress: false + filter: tree:0 - name: 'Cache: .nuke/temp, ~/.nuget/packages' uses: actions/cache@v4 with: @@ -96,11 +98,13 @@ jobs: group: ${{ github.workflow }} @ ${{ github.event.pull_request.head.label || github.head_ref || github.run_id }} cancel-in-progress: true steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: submodules: recursive lfs: true fetch-depth: 2 + progress: false + filter: tree:0 - name: 'Cache: .nuke/temp, ~/.nuget/packages' uses: actions/cache@v4 with: @@ -139,11 +143,13 @@ jobs: group: ${{ github.workflow }} @ ${{ github.event.pull_request.head.label || github.head_ref || github.run_id }} cancel-in-progress: true steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: submodules: recursive lfs: true fetch-depth: 2 + progress: false + filter: tree:0 - name: 'Cache: .nuke/temp, ~/.nuget/packages' uses: actions/cache@v4 with: diff --git a/source/Nuke.Common.Tests/CI/ConfigurationGenerationTest.Test_testName=simple-triggers_attribute=GitHubActionsAttribute.verified.txt b/source/Nuke.Common.Tests/CI/ConfigurationGenerationTest.Test_testName=simple-triggers_attribute=GitHubActionsAttribute.verified.txt index 740323d94..81771b54a 100644 --- a/source/Nuke.Common.Tests/CI/ConfigurationGenerationTest.Test_testName=simple-triggers_attribute=GitHubActionsAttribute.verified.txt +++ b/source/Nuke.Common.Tests/CI/ConfigurationGenerationTest.Test_testName=simple-triggers_attribute=GitHubActionsAttribute.verified.txt @@ -27,7 +27,7 @@ jobs: name: macos-latest runs-on: macos-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: 'Cache: .nuke/temp, ~/.nuget/packages' uses: actions/cache@v4 with: @@ -59,7 +59,7 @@ jobs: name: ubuntu-latest runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: 'Cache: .nuke/temp, ~/.nuget/packages' uses: actions/cache@v4 with: @@ -91,7 +91,7 @@ jobs: name: windows-latest runs-on: windows-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: 'Cache: .nuke/temp, ~/.nuget/packages' uses: actions/cache@v4 with: diff --git a/source/Nuke.Common.Tests/CI/ConfigurationGenerationTest.cs b/source/Nuke.Common.Tests/CI/ConfigurationGenerationTest.cs index 77d15ef7a..e9fd9704f 100644 --- a/source/Nuke.Common.Tests/CI/ConfigurationGenerationTest.cs +++ b/source/Nuke.Common.Tests/CI/ConfigurationGenerationTest.cs @@ -156,6 +156,8 @@ public class TestBuild : NukeBuild Submodules = GitHubActionsSubmodules.Recursive, Lfs = true, FetchDepth = 2, + Progress = false, + Filter = "tree:0", TimeoutMinutes = 30, JobConcurrencyCancelInProgress = true } diff --git a/source/Nuke.Common/CI/GitHubActions/Configuration/GitHubActionsCheckoutStep.cs b/source/Nuke.Common/CI/GitHubActions/Configuration/GitHubActionsCheckoutStep.cs index 213acf17d..269c08e30 100644 --- a/source/Nuke.Common/CI/GitHubActions/Configuration/GitHubActionsCheckoutStep.cs +++ b/source/Nuke.Common/CI/GitHubActions/Configuration/GitHubActionsCheckoutStep.cs @@ -15,12 +15,14 @@ public class GitHubActionsCheckoutStep : GitHubActionsStep public GitHubActionsSubmodules? Submodules { get; set; } public bool? Lfs { get; set; } public uint? FetchDepth { get; set; } + public bool? Progress { get; set; } + public string Filter { get; set; } public override void Write(CustomFileWriter writer) { - writer.WriteLine("- uses: actions/checkout@v3"); + writer.WriteLine("- uses: actions/checkout@v4"); - if (Submodules.HasValue || Lfs.HasValue || FetchDepth.HasValue) + if (Submodules.HasValue || Lfs.HasValue || FetchDepth.HasValue || Progress.HasValue || !Filter.IsNullOrWhiteSpace()) { using (writer.Indent()) { @@ -33,6 +35,10 @@ public override void Write(CustomFileWriter writer) writer.WriteLine($"lfs: {Lfs.ToString().ToLowerInvariant()}"); if (FetchDepth.HasValue) writer.WriteLine($"fetch-depth: {FetchDepth}"); + if (Progress.HasValue) + writer.WriteLine($"progress: {Progress.ToString().ToLowerInvariant()}"); + if (!Filter.IsNullOrWhiteSpace()) + writer.WriteLine($"filter: {Filter}"); } } } diff --git a/source/Nuke.Common/CI/GitHubActions/GitHubActionsAttribute.cs b/source/Nuke.Common/CI/GitHubActions/GitHubActionsAttribute.cs index 497702c69..90c0a8ef5 100644 --- a/source/Nuke.Common/CI/GitHubActions/GitHubActionsAttribute.cs +++ b/source/Nuke.Common/CI/GitHubActions/GitHubActionsAttribute.cs @@ -28,6 +28,8 @@ public class GitHubActionsAttribute : ConfigurationAttributeBase private GitHubActionsSubmodules? _submodules; private bool? _lfs; private uint? _fetchDepth; + private bool? _progress; + private string _filter; public GitHubActionsAttribute( string name, @@ -98,6 +100,18 @@ public uint FetchDepth get => throw new NotSupportedException(); } + public bool Progress + { + set => _progress = value; + get => throw new NotSupportedException(); + } + + public string Filter + { + set => _filter = value; + get => throw new NotSupportedException(); + } + public override CustomFileWriter CreateWriter(StreamWriter streamWriter) { return new CustomFileWriter(streamWriter, indentationFactor: 2, commentPrefix: "#"); @@ -142,7 +156,9 @@ private IEnumerable GetSteps(GitHubActionsImage image, IReadO { Submodules = _submodules, Lfs = _lfs, - FetchDepth = _fetchDepth + FetchDepth = _fetchDepth, + Progress = _progress, + Filter = _filter }; if (CacheKeyFiles.Any()) From 82ebfc036d6eb2e599c52c2250528ba44e109fe8 Mon Sep 17 00:00:00 2001 From: Marko Lahma Date: Wed, 3 Jul 2024 19:31:58 +0300 Subject: [PATCH 26/56] feat(cicd): add ConcurrencyGroup and ConcurrencyCancelInProgress to GitHubActionsAttribute (#1299) --- ...ribute=GitHubActionsAttribute.verified.txt | 10 +++++--- .../CI/ConfigurationGenerationTest.cs | 4 +++- .../GitHubActionsConfiguration.cs | 24 +++++++++++++++++++ .../GitHubActions/GitHubActionsAttribute.cs | 5 ++++ 4 files changed, 39 insertions(+), 4 deletions(-) diff --git a/source/Nuke.Common.Tests/CI/ConfigurationGenerationTest.Test_testName=detailed-triggers_attribute=GitHubActionsAttribute.verified.txt b/source/Nuke.Common.Tests/CI/ConfigurationGenerationTest.Test_testName=detailed-triggers_attribute=GitHubActionsAttribute.verified.txt index cba457564..b134fb2bf 100644 --- a/source/Nuke.Common.Tests/CI/ConfigurationGenerationTest.Test_testName=detailed-triggers_attribute=GitHubActionsAttribute.verified.txt +++ b/source/Nuke.Common.Tests/CI/ConfigurationGenerationTest.Test_testName=detailed-triggers_attribute=GitHubActionsAttribute.verified.txt @@ -44,13 +44,17 @@ on: schedule: - cron: '* 0 * * *' +concurrency: + group: ${{ github.workflow }} @ ${{ github.event.pull_request.head.label || github.head_ref || github.run_id }} + cancel-in-progress: true + jobs: macos-latest: name: macos-latest runs-on: macos-latest timeout-minutes: 30 concurrency: - group: ${{ github.workflow }} @ ${{ github.event.pull_request.head.label || github.head_ref || github.run_id }} + group: custom-job-group cancel-in-progress: true steps: - uses: actions/checkout@v4 @@ -95,7 +99,7 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 30 concurrency: - group: ${{ github.workflow }} @ ${{ github.event.pull_request.head.label || github.head_ref || github.run_id }} + group: custom-job-group cancel-in-progress: true steps: - uses: actions/checkout@v4 @@ -140,7 +144,7 @@ jobs: runs-on: windows-latest timeout-minutes: 30 concurrency: - group: ${{ github.workflow }} @ ${{ github.event.pull_request.head.label || github.head_ref || github.run_id }} + group: custom-job-group cancel-in-progress: true steps: - uses: actions/checkout@v4 diff --git a/source/Nuke.Common.Tests/CI/ConfigurationGenerationTest.cs b/source/Nuke.Common.Tests/CI/ConfigurationGenerationTest.cs index e9fd9704f..43776b80d 100644 --- a/source/Nuke.Common.Tests/CI/ConfigurationGenerationTest.cs +++ b/source/Nuke.Common.Tests/CI/ConfigurationGenerationTest.cs @@ -159,7 +159,9 @@ public class TestBuild : NukeBuild Progress = false, Filter = "tree:0", TimeoutMinutes = 30, - JobConcurrencyCancelInProgress = true + ConcurrencyCancelInProgress = true, + JobConcurrencyCancelInProgress = true, + JobConcurrencyGroup = "custom-job-group" } ); diff --git a/source/Nuke.Common/CI/GitHubActions/Configuration/GitHubActionsConfiguration.cs b/source/Nuke.Common/CI/GitHubActions/Configuration/GitHubActionsConfiguration.cs index bd1425827..72359ed6c 100644 --- a/source/Nuke.Common/CI/GitHubActions/Configuration/GitHubActionsConfiguration.cs +++ b/source/Nuke.Common/CI/GitHubActions/Configuration/GitHubActionsConfiguration.cs @@ -18,6 +18,8 @@ public class GitHubActionsConfiguration : ConfigurationEntity public GitHubActionsTrigger[] ShortTriggers { get; set; } public GitHubActionsDetailedTrigger[] DetailedTriggers { get; set; } public (GitHubActionsPermissions Type, string Permission)[] Permissions { get; set; } + public string ConcurrencyGroup { get; set; } + public bool ConcurrencyCancelInProgress { get; set; } public GitHubActionsJob[] Jobs { get; set; } public override void Write(CustomFileWriter writer) @@ -46,6 +48,28 @@ public override void Write(CustomFileWriter writer) } } + if (!ConcurrencyGroup.IsNullOrWhiteSpace() || ConcurrencyCancelInProgress) + { + writer.WriteLine(); + writer.WriteLine("concurrency:"); + using (writer.Indent()) + { + var group = ConcurrencyGroup; + if (group.IsNullOrWhiteSpace()) + { + // create a default value that only cancels in-progress runs of the same workflow + // we don't fall back to github.ref which would disable multiple runs in main/master which is usually what is wanted + group = "${{ github.workflow }} @ ${{ github.event.pull_request.head.label || github.head_ref || github.run_id }}"; + } + + writer.WriteLine($"group: {group}"); + if (ConcurrencyCancelInProgress) + { + writer.WriteLine("cancel-in-progress: true"); + } + } + } + writer.WriteLine(); writer.WriteLine("jobs:"); diff --git a/source/Nuke.Common/CI/GitHubActions/GitHubActionsAttribute.cs b/source/Nuke.Common/CI/GitHubActions/GitHubActionsAttribute.cs index 90c0a8ef5..8aef0f6fd 100644 --- a/source/Nuke.Common/CI/GitHubActions/GitHubActionsAttribute.cs +++ b/source/Nuke.Common/CI/GitHubActions/GitHubActionsAttribute.cs @@ -77,6 +77,9 @@ public GitHubActionsAttribute( public int TimeoutMinutes { get; set; } + public string ConcurrencyGroup { get; set; } + public bool ConcurrencyCancelInProgress { get; set; } + public string JobConcurrencyGroup { get; set; } public bool JobConcurrencyCancelInProgress { get; set; } @@ -126,6 +129,8 @@ public override ConfigurationEntity GetConfiguration(IReadOnlyCollection (x, "write")) .Concat(ReadPermissions.Select(x => (x, "read"))).ToArray(), + ConcurrencyGroup = ConcurrencyGroup, + ConcurrencyCancelInProgress = ConcurrencyCancelInProgress, Jobs = _images.Select(x => GetJobs(x, relevantTargets)).ToArray() }; From 5d6b5746d9772c4b462bf7630e7ebfcacb2f69f1 Mon Sep 17 00:00:00 2001 From: Marko Lahma Date: Wed, 3 Jul 2024 19:33:16 +0300 Subject: [PATCH 27/56] fix(cicd): add ubuntu-24.04 image for GitHubActions (#1381) --- source/Nuke.Common/CI/GitHubActions/GitHubActionsImage.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/source/Nuke.Common/CI/GitHubActions/GitHubActionsImage.cs b/source/Nuke.Common/CI/GitHubActions/GitHubActionsImage.cs index 03ae3cc74..bb4e6f278 100644 --- a/source/Nuke.Common/CI/GitHubActions/GitHubActionsImage.cs +++ b/source/Nuke.Common/CI/GitHubActions/GitHubActionsImage.cs @@ -17,6 +17,7 @@ public enum GitHubActionsImage { [EnumValue("windows-2022")] WindowsServer2022, [EnumValue("windows-2019")] WindowsServer2019, + [EnumValue("ubuntu-24.04")] Ubuntu2404, [EnumValue("ubuntu-22.04")] Ubuntu2204, [EnumValue("ubuntu-20.04")] Ubuntu2004, [EnumValue("ubuntu-18.04")] Ubuntu1804, From 6947b540c019abb72f09de5d17b5ab041a2178d1 Mon Sep 17 00:00:00 2001 From: Emmanuel Ferdman Date: Wed, 3 Jul 2024 19:34:20 +0300 Subject: [PATCH 28/56] docs: fix links to files (#1366) --- docs/01-getting-started/07-telemetry.md | 4 ++-- docs/06-global-tool/02-secrets.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/01-getting-started/07-telemetry.md b/docs/01-getting-started/07-telemetry.md index a04a9df4c..6a7eadec3 100644 --- a/docs/01-getting-started/07-telemetry.md +++ b/docs/01-getting-started/07-telemetry.md @@ -33,7 +33,7 @@ Once you confirm the notice, NUKE will either: ## Scope -As a global tool and library, NUKE has [multiple events](https://github.com/nuke-build/nuke/blob/master/source/Nuke.Common/Execution/Telemetry.Events.cs) where telemetry is collected: +As a global tool and library, NUKE has [multiple events](https://github.com/nuke-build/nuke/blob/master/source/Nuke.Build/Telemetry/Telemetry.Events.cs) where telemetry is collected: - `BuildStarted` – when a build was started - `TargetSucceeded` – when a target succeeded (only `Restore`, `Compile`, `Test`) @@ -46,7 +46,7 @@ Data for `BuildStarted` and `TargetSucceeded` is only collected when `IsServerBu ## Data Points -The [telemetry data points](https://github.com/nuke-build/nuke/blob/master/source/Nuke.Common/Execution/Telemetry.Properties.cs) do not collect personal data, such as usernames or email addresses. The data is sent securely to Microsoft servers using [Azure Monitor](https://azure.microsoft.com/services/monitor/) technology, held under restricted access, and published under strict security controls from secure [Azure Storage](https://azure.microsoft.com/services/storage/) systems. +The [telemetry data points](https://github.com/nuke-build/nuke/blob/master/source/Nuke.Build/Telemetry/Telemetry.Properties.cs) do not collect personal data, such as usernames or email addresses. The data is sent securely to Microsoft servers using [Azure Monitor](https://azure.microsoft.com/services/monitor/) technology, held under restricted access, and published under strict security controls from secure [Azure Storage](https://azure.microsoft.com/services/storage/) systems. Protecting your privacy is important to us. If you suspect the telemetry is collecting sensitive data or the data is being insecurely or inappropriately handled, file an issue in the [nuke-build/nuke](https://github.com/nuke-build/nuke) repository or [email us](mailto:info@nuke.build?subject=Telemetry) for investigation. diff --git a/docs/06-global-tool/02-secrets.md b/docs/06-global-tool/02-secrets.md index e4ede5e80..c364e4aee 100644 --- a/docs/06-global-tool/02-secrets.md +++ b/docs/06-global-tool/02-secrets.md @@ -7,7 +7,7 @@ import AsciinemaPlayer from '@site/src/components/AsciinemaPlayer'; Historically, secret values like passwords or auth-tokens are often saved as environment variables on local machines or CI/CD servers. This imposes both, security issues because other processes can access these environment variables and inconveniences when a build must be executed locally for emergency reasons (server downtime). NUKE has an integrated encryption utility, which can be used to save and load secret values to and from [parameter files](../02-fundamentals/06-parameters.md#passing-values-through-parameter-files). :::danger -Our [custom encryption utility](https://github.com/nuke-build/nuke/blob/develop/source/Nuke.Common/Utilities/EncryptionUtility.cs) is provided "AS IS" without warranty of any kind. +Our [custom encryption utility](https://github.com/nuke-build/nuke/blob/develop/source/Nuke.Utilities/Security/EncryptionUtility.cs) is provided "AS IS" without warranty of any kind. The implementation uses your password, a static salt, 10.000 iterations, and SHA256 to generate a [key-derivation function](https://docs.microsoft.com/en-us/dotnet/api/system.security.cryptography.rfc2898derivebytes) ([RFC2898](https://datatracker.ietf.org/doc/html/rfc2898)), which is then used to create a crypto-stream to encrypt and decrypt values via [Advanced Encryption Standard (AES)](https://en.wikipedia.org/wiki/Advanced_Encryption_Standard). From 3400b014f7f10bc31f23adfcbf7e542340824dc9 Mon Sep 17 00:00:00 2001 From: Stefan de Vogelaere Date: Wed, 3 Jul 2024 18:45:18 +0200 Subject: [PATCH 29/56] feat(cicd): add EnvironmentName and EnvironmentUrl to GitHubActionsAttribute (#1389) --- ...ribute=GitHubActionsAttribute.verified.txt | 9 +++++++++ .../CI/ConfigurationGenerationTest.cs | 6 +++++- .../Configuration/GitHubActionsJob.cs | 19 +++++++++++++++++++ .../GitHubActions/GitHubActionsAttribute.cs | 5 +++++ 4 files changed, 38 insertions(+), 1 deletion(-) diff --git a/source/Nuke.Common.Tests/CI/ConfigurationGenerationTest.Test_testName=detailed-triggers_attribute=GitHubActionsAttribute.verified.txt b/source/Nuke.Common.Tests/CI/ConfigurationGenerationTest.Test_testName=detailed-triggers_attribute=GitHubActionsAttribute.verified.txt index b134fb2bf..697dd6e7c 100644 --- a/source/Nuke.Common.Tests/CI/ConfigurationGenerationTest.Test_testName=detailed-triggers_attribute=GitHubActionsAttribute.verified.txt +++ b/source/Nuke.Common.Tests/CI/ConfigurationGenerationTest.Test_testName=detailed-triggers_attribute=GitHubActionsAttribute.verified.txt @@ -56,6 +56,9 @@ jobs: concurrency: group: custom-job-group cancel-in-progress: true + environment: + name: environment-name + url: environment-url steps: - uses: actions/checkout@v4 with: @@ -101,6 +104,9 @@ jobs: concurrency: group: custom-job-group cancel-in-progress: true + environment: + name: environment-name + url: environment-url steps: - uses: actions/checkout@v4 with: @@ -146,6 +152,9 @@ jobs: concurrency: group: custom-job-group cancel-in-progress: true + environment: + name: environment-name + url: environment-url steps: - uses: actions/checkout@v4 with: diff --git a/source/Nuke.Common.Tests/CI/ConfigurationGenerationTest.cs b/source/Nuke.Common.Tests/CI/ConfigurationGenerationTest.cs index 43776b80d..c8f5c3146 100644 --- a/source/Nuke.Common.Tests/CI/ConfigurationGenerationTest.cs +++ b/source/Nuke.Common.Tests/CI/ConfigurationGenerationTest.cs @@ -8,6 +8,7 @@ using System.IO; using System.Linq; using System.Threading.Tasks; +using JetBrains.Annotations; using Nuke.Common.CI; using Nuke.Common.CI.AppVeyor; using Nuke.Common.CI.AzurePipelines; @@ -48,6 +49,7 @@ public static IEnumerable GetAttributes() return TestBuild.GetAttributes().Select(x => new object[] { x.TestName, x.Generator }); } + [UsedImplicitly(ImplicitUseTargetFlags.WithMembers)] [AppVeyorSecret("GitHubToken", "encrypted-yaml")] [TeamCityToken("GitHubToken", "74928d76-46e8-45cc-ad22-6438915ac070")] public class TestBuild : NukeBuild @@ -161,7 +163,9 @@ public class TestBuild : NukeBuild TimeoutMinutes = 30, ConcurrencyCancelInProgress = true, JobConcurrencyCancelInProgress = true, - JobConcurrencyGroup = "custom-job-group" + JobConcurrencyGroup = "custom-job-group", + EnvironmentName = "environment-name", + EnvironmentUrl = "environment-url" } ); diff --git a/source/Nuke.Common/CI/GitHubActions/Configuration/GitHubActionsJob.cs b/source/Nuke.Common/CI/GitHubActions/Configuration/GitHubActionsJob.cs index 61dc3e4e8..817b9ba29 100644 --- a/source/Nuke.Common/CI/GitHubActions/Configuration/GitHubActionsJob.cs +++ b/source/Nuke.Common/CI/GitHubActions/Configuration/GitHubActionsJob.cs @@ -18,6 +18,8 @@ public class GitHubActionsJob : ConfigurationEntity public GitHubActionsImage Image { get; set; } public int TimeoutMinutes { get; set; } public string ConcurrencyGroup { get; set; } + public string EnvironmentName { get; set; } + public string EnvironmentUrl { get; set; } public bool ConcurrencyCancelInProgress { get; set; } public GitHubActionsStep[] Steps { get; set; } @@ -56,6 +58,23 @@ public override void Write(CustomFileWriter writer) } } + if (!EnvironmentName.IsNullOrWhiteSpace()) + { + if (EnvironmentUrl.IsNullOrWhiteSpace()) + { + writer.WriteLine($"environment: {EnvironmentName}"); + } + else + { + writer.WriteLine("environment:"); + using (writer.Indent()) + { + writer.WriteLine($"name: {EnvironmentName}"); + writer.WriteLine($"url: {EnvironmentUrl}"); + } + } + } + writer.WriteLine("steps:"); using (writer.Indent()) { diff --git a/source/Nuke.Common/CI/GitHubActions/GitHubActionsAttribute.cs b/source/Nuke.Common/CI/GitHubActions/GitHubActionsAttribute.cs index 8aef0f6fd..2c1f1599e 100644 --- a/source/Nuke.Common/CI/GitHubActions/GitHubActionsAttribute.cs +++ b/source/Nuke.Common/CI/GitHubActions/GitHubActionsAttribute.cs @@ -76,6 +76,9 @@ public GitHubActionsAttribute( public string PublishCondition { get; set; } public int TimeoutMinutes { get; set; } + + public string EnvironmentName { get; set; } + public string EnvironmentUrl { get; set; } public string ConcurrencyGroup { get; set; } public bool ConcurrencyCancelInProgress { get; set; } @@ -147,6 +150,8 @@ protected virtual GitHubActionsJob GetJobs(GitHubActionsImage image, IReadOnlyCo return new GitHubActionsJob { Name = image.GetValue().Replace(".", "_"), + EnvironmentName = EnvironmentName, + EnvironmentUrl = EnvironmentUrl, Steps = GetSteps(image, relevantTargets).ToArray(), Image = image, TimeoutMinutes = TimeoutMinutes, From 05f1d6999bb247c66f226a476eeb61e069722b99 Mon Sep 17 00:00:00 2001 From: Matthias Koch Date: Wed, 3 Jul 2024 18:28:00 +0200 Subject: [PATCH 30/56] docs: update file-system operations and LatestGitHubReleaseAttribute --- docs/03-common/03-paths.md | 26 +++++++++++++++++++++++++- docs/03-common/06-versioning.md | 2 +- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/docs/03-common/03-paths.md b/docs/03-common/03-paths.md index 9b1ab19ad..ce2c36d23 100644 --- a/docs/03-common/03-paths.md +++ b/docs/03-common/03-paths.md @@ -42,7 +42,7 @@ var pathExists = (RootDirectory / "dirOrFile").Exists(); // checks for both ## Relative Paths -Occasionally, you may actually want relative paths, for instance to include them in manifest files that get shipped with your artifacts. In this case, you can make use of `RelativePath`, which uses the path separator dictated by the operating system, or one of types `WinRelativePath` or `UnixRelativePath`, which enforce using backslash or slash respectively: +Occasionally, you may actually want relative paths, for instance, to include them in manifest files that get shipped with your artifacts. In this case, you can make use of `RelativePath`, which uses the path separator dictated by the operating system, or one of types `WinRelativePath` or `UnixRelativePath`, which enforce using backslash or slash respectively: ```cs @@ -57,6 +57,30 @@ var indexUnixRelativePath2 = (UnixRelativePath)indexRelativeFile; All relative path types support using the division operator. +## File-system Operations + +Instances of the `AbsolutePath` type provide a wide range of file-system-related operations: + +```cs +// Read/write file content +file.ReadAllText(); +file.WriteAllLines(lines); + +// Touch a file / create a directory +file.TouchFile(); +directory.CreateDirectory(); + +// Rename a file or directory +file.RenameWithoutExtension($"archive-{DateTime.Now.Year}.tar"); +directory.Rename(x => $"{x.Name}-final"); // combine previous name + +// Move a file or directory +source.Move(target, ExistsPolicy.MergeAndSkip); + +// Copy a file or directory (recursively) to another directory +source.CopyToDirectory(target, ExistsPolicy.DirectoryMerge | ExistsPolicy.FileFail); +``` + ## Globbing Through the integrated [Glob](https://github.com/kthompson/glob) NuGet package, you can use [globbing patterns](https://en.wikipedia.org/wiki/Glob_(programming)) to collect files or directories from a base directory: diff --git a/docs/03-common/06-versioning.md b/docs/03-common/06-versioning.md index 042e233e0..2a581b63d 100644 --- a/docs/03-common/06-versioning.md +++ b/docs/03-common/06-versioning.md @@ -133,7 +133,7 @@ Target Print => _ => _ ```csharp title="Build.cs" [LatestGitHubRelease( identifier: "JetBrains/gradle-intellij-plugin", - TrimPrefix = true)] + Pattern = @"v?(?\d+\.\d+(?:\.\d+)?(?:\.\d+)?(?:-\w+)?)")] // default pattern readonly string GradlePluginVersion; Target Print => _ => _ From bb835b373b24245640881bffc5276e4ce40f571f Mon Sep 17 00:00:00 2001 From: Matthias Koch Date: Wed, 3 Jul 2024 23:46:14 +0200 Subject: [PATCH 31/56] build: disable EnforceExtendedAnalyzerRules --- source/Nuke.SourceGenerators/Nuke.SourceGenerators.csproj | 1 + 1 file changed, 1 insertion(+) diff --git a/source/Nuke.SourceGenerators/Nuke.SourceGenerators.csproj b/source/Nuke.SourceGenerators/Nuke.SourceGenerators.csproj index 53dedbbad..381f687d7 100644 --- a/source/Nuke.SourceGenerators/Nuke.SourceGenerators.csproj +++ b/source/Nuke.SourceGenerators/Nuke.SourceGenerators.csproj @@ -5,6 +5,7 @@ false false $(NoWarn);NU5128;CS0649 + false From 0059194b7f8efbc0edf3879625b79c8bb5775ced Mon Sep 17 00:00:00 2001 From: Matthias Koch Date: Wed, 3 Jul 2024 23:46:37 +0200 Subject: [PATCH 32/56] ci: update GitHub Action workflows --- .github/workflows/alpha-deployment.yml | 2 +- .github/workflows/macos-latest.yml | 2 +- .github/workflows/ubuntu-latest.yml | 2 +- .github/workflows/windows-latest.yml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/alpha-deployment.yml b/.github/workflows/alpha-deployment.yml index 69b7d54e5..3ea38c32c 100644 --- a/.github/workflows/alpha-deployment.yml +++ b/.github/workflows/alpha-deployment.yml @@ -26,7 +26,7 @@ jobs: name: ubuntu-latest runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 - name: 'Cache: .nuke/temp, ~/.nuget/packages' diff --git a/.github/workflows/macos-latest.yml b/.github/workflows/macos-latest.yml index 9db41a37b..248a66a28 100644 --- a/.github/workflows/macos-latest.yml +++ b/.github/workflows/macos-latest.yml @@ -30,7 +30,7 @@ jobs: name: macos-latest runs-on: macos-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 - name: 'Cache: .nuke/temp, ~/.nuget/packages' diff --git a/.github/workflows/ubuntu-latest.yml b/.github/workflows/ubuntu-latest.yml index 06b3edcd3..d5b513b19 100644 --- a/.github/workflows/ubuntu-latest.yml +++ b/.github/workflows/ubuntu-latest.yml @@ -30,7 +30,7 @@ jobs: name: ubuntu-latest runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 - name: 'Cache: .nuke/temp, ~/.nuget/packages' diff --git a/.github/workflows/windows-latest.yml b/.github/workflows/windows-latest.yml index b8b183eeb..03f6a7639 100644 --- a/.github/workflows/windows-latest.yml +++ b/.github/workflows/windows-latest.yml @@ -30,7 +30,7 @@ jobs: name: windows-latest runs-on: windows-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 - name: 'Cache: .nuke/temp, ~/.nuget/packages' From 750903d9d405b5d93f7a9ae04267890ed83fe50f Mon Sep 17 00:00:00 2001 From: Matthias Koch Date: Wed, 3 Jul 2024 23:46:48 +0200 Subject: [PATCH 33/56] build: clear NuGet package sources --- NuGet.config | 1 + 1 file changed, 1 insertion(+) diff --git a/NuGet.config b/NuGet.config index 323ae002b..50c5b9a63 100644 --- a/NuGet.config +++ b/NuGet.config @@ -4,6 +4,7 @@ + From dc740cebf69df31dd06da13be89806a010ccd027 Mon Sep 17 00:00:00 2001 From: Matthias Koch Date: Thu, 4 Jul 2024 00:03:55 +0200 Subject: [PATCH 34/56] chore: update CHANGELOG.md --- CHANGELOG.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index dca1e1956..7a40077a1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,16 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). ## [vNext] +- Added `AbsolutePath` extension methods for `AddUnixSymlink`, `Copy*`, `Move*`, `Rename*` +- Added `Pattern` in favor of property in `LatestGitHubReleaseAttribute` +- Added `ConcurrencyGroup`, `ConcurrencyCancelInProgress`, `EnvironmentName`, `EnvironmentUrl` in `GitHubActionsAttribute` +- Fixed unquoting of multiple quoted arguments in `ArgumentStringHandler` +- Fixed GitHubActions to use latest action versions +- Fixed `DotCoverTasks` and `EntityFrameworkTasks` tool path resolution +- Fixed missing members in `GitHubActionsImage` +- Fixed missing properties in `GitLab` +- Fixed missing parameters in `AzurePipelines.SetVariables` +- Fixed missing arguments in `DotNetTasks` ## [8.0.0] / 2024-01-18 - Changed string parameters to violate requirement when empty or whitespace From 01ae6111e55e325448e441999f983b6ff6f9d9d0 Mon Sep 17 00:00:00 2001 From: Matthias Koch Date: Thu, 4 Jul 2024 00:10:36 +0200 Subject: [PATCH 35/56] fix(cicd): GitLab nullable properties --- source/Nuke.Common/CI/GitLab/GitLab.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/Nuke.Common/CI/GitLab/GitLab.cs b/source/Nuke.Common/CI/GitLab/GitLab.cs index c8b6aae22..2c5a351c8 100644 --- a/source/Nuke.Common/CI/GitLab/GitLab.cs +++ b/source/Nuke.Common/CI/GitLab/GitLab.cs @@ -281,17 +281,17 @@ private string GetSectionId(string text) /// /// The Source chat channel that triggered the ChatOps command. /// - public string ChatChannel => EnvironmentInfo.GetVariable("CHAT_CHANNEL"); + [CanBeNull] public string ChatChannel => EnvironmentInfo.GetVariable("CHAT_CHANNEL"); /// /// The additional arguments passed with the ChatOps command. /// - public string ChatInput => EnvironmentInfo.GetVariable("CHAT_INPUT"); + [CanBeNull] public string ChatInput => EnvironmentInfo.GetVariable("CHAT_INPUT"); /// /// The chat service's user ID of the user who triggered the ChatOps command. /// - public string ChatUserId => EnvironmentInfo.GetVariable("CHAT_USER_ID"); + [CanBeNull] public string ChatUserId => EnvironmentInfo.GetVariable("CHAT_USER_ID"); /// /// The GitLab API v4 root URL. From 7326db8e80714084e847b5e5e843fe25b6c92a6f Mon Sep 17 00:00:00 2001 From: Matthias Koch Date: Tue, 22 Aug 2023 02:44:41 +0200 Subject: [PATCH 36/56] feat(execution): use NJsonSchema for build.schema.json --- .nuke/build.schema.json | 348 ++++++++---------- source/Nuke.Build.Shared/CompletionUtility.cs | 50 ++- ...tGetCompletionItemsFromSchema.verified.txt | 14 + ...CompletionItemsParameterBuild.verified.txt | 38 ++ ...GetCompletionItemsTargetBuild.verified.txt | 35 ++ .../Nuke.Build.Tests/CompletionUtilityTest.cs | 49 ++- ...mParameterAttributeAttribute.verified.json | 90 +++++ ...maUtilityTest.TestEmptyBuild.verified.json | 85 +++++ ...lityTest.TestGetBuildSchema.verified.json} | 86 +++-- ...ilityTest.TestParameterBuild.verified.json | 190 ++++++++++ ...aUtilityTest.TestTargetBuild.verified.json | 91 +++++ source/Nuke.Build.Tests/SchemaUtilityTest.cs | 128 +++++-- source/Nuke.Build.Tests/parameters.json | 5 + .../HandleShellCompletionAttribute.cs | 18 +- source/Nuke.Build/Nuke.Build.csproj | 1 + source/Nuke.Build/NukeBuild.Statics.cs | 2 +- source/Nuke.Build/NukeBuild.cs | 6 +- source/Nuke.Build/Utilities/SchemaUtility.cs | 205 +++++++---- 18 files changed, 1088 insertions(+), 353 deletions(-) create mode 100644 source/Nuke.Build.Tests/CompletionUtilityTest.TestGetCompletionItemsFromSchema.verified.txt create mode 100644 source/Nuke.Build.Tests/CompletionUtilityTest.TestGetCompletionItemsParameterBuild.verified.txt create mode 100644 source/Nuke.Build.Tests/CompletionUtilityTest.TestGetCompletionItemsTargetBuild.verified.txt create mode 100644 source/Nuke.Build.Tests/SchemaUtilityTest.TestCustomParameterAttributeAttribute.verified.json create mode 100644 source/Nuke.Build.Tests/SchemaUtilityTest.TestEmptyBuild.verified.json rename source/Nuke.Build.Tests/{SchemaUtilityTest.TestGetBuildSchema.verified.txt => SchemaUtilityTest.TestGetBuildSchema.verified.json} (71%) create mode 100644 source/Nuke.Build.Tests/SchemaUtilityTest.TestParameterBuild.verified.json create mode 100644 source/Nuke.Build.Tests/SchemaUtilityTest.TestTargetBuild.verified.json create mode 100644 source/Nuke.Build.Tests/parameters.json diff --git a/.nuke/build.schema.json b/.nuke/build.schema.json index b42ce3ca0..956ab15ae 100644 --- a/.nuke/build.schema.json +++ b/.nuke/build.schema.json @@ -1,76 +1,174 @@ { "$schema": "http://json-schema.org/draft-04/schema#", - "$ref": "#/definitions/build", - "title": "Build Schema", + "properties": { + "AutoStash": { + "type": "boolean" + }, + "CodecovToken": { + "type": "string", + "default": "Secrets must be entered via 'nuke :secrets [profile]'" + }, + "Configuration": { + "type": "string", + "enum": [ + "Debug", + "Release" + ] + }, + "DiscordWebhook": { + "type": "string", + "default": "Secrets must be entered via 'nuke :secrets [profile]'" + }, + "FeedzNuGetApiKey": { + "type": "string", + "default": "Secrets must be entered via 'nuke :secrets [profile]'" + }, + "GitHubReleaseGitHubToken": { + "type": "string", + "default": "Secrets must be entered via 'nuke :secrets [profile]'" + }, + "IgnoreFailedSources": { + "type": "boolean", + "description": "Ignore unreachable sources during Restore" + }, + "Major": { + "type": "boolean" + }, + "MastodonAccessToken": { + "type": "string", + "default": "Secrets must be entered via 'nuke :secrets [profile]'" + }, + "PublicNuGetApiKey": { + "type": "string", + "default": "Secrets must be entered via 'nuke :secrets [profile]'" + }, + "SignPathApiToken": { + "type": "string", + "default": "Secrets must be entered via 'nuke :secrets [profile]'" + }, + "SignPathOrganizationId": { + "type": "string" + }, + "SignPathPolicySlug": { + "type": "string" + }, + "SignPathProjectSlug": { + "type": "string" + }, + "SlackWebhook": { + "type": "string", + "default": "Secrets must be entered via 'nuke :secrets [profile]'" + }, + "Solution": { + "type": "string", + "description": "Path to a solution file that is automatically loaded" + }, + "TestDegreeOfParallelism": { + "type": "integer", + "format": "int32" + }, + "TwitterAccessToken": { + "type": "string", + "default": "Secrets must be entered via 'nuke :secrets [profile]'" + }, + "TwitterAccessTokenSecret": { + "type": "string", + "default": "Secrets must be entered via 'nuke :secrets [profile]'" + }, + "TwitterConsumerKey": { + "type": "string", + "default": "Secrets must be entered via 'nuke :secrets [profile]'" + }, + "TwitterConsumerSecret": { + "type": "string", + "default": "Secrets must be entered via 'nuke :secrets [profile]'" + }, + "UseHttps": { + "type": "boolean" + } + }, "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": [ + "Announce", + "AnnounceDiscord", + "AnnounceMastodon", + "AnnounceSlack", + "AnnounceTwitter", + "Changelog", + "CheckoutExternalRepositories", + "Clean", + "Compile", + "CreateGitHubRelease", + "DeletePackages", + "DownloadLicenses", + "GenerateGlobalSolution", + "GeneratePublicApi", + "GenerateTools", + "Hotfix", + "Install", + "InstallFonts", + "Milestone", + "Pack", + "Publish", + "References", + "Release", + "ReleaseImage", + "ReportCoverage", + "ReportDuplicates", + "ReportIssues", + "Restore", + "RunTargetInDockerImageTest", + "SignPackages", + "Test", + "UpdateContributors", + "UpdateStargazers" + ] + }, + "Verbosity": { + "type": "string", + "description": "", + "enum": [ + "Verbose", + "Normal", + "Minimal", + "Quiet" + ] + }, + "NukeBuild": { "properties": { - "AutoStash": { - "type": "boolean" - }, - "CodecovToken": { - "type": "string", - "default": "Secrets must be entered via 'nuke :secrets [profile]'" - }, - "Configuration": { - "type": "string", - "enum": [ - "Debug", - "Release" - ] - }, "Continue": { "type": "boolean", "description": "Indicates to continue a previously failed build attempt" }, - "DiscordWebhook": { - "type": "string", - "default": "Secrets must be entered via 'nuke :secrets [profile]'" - }, - "FeedzNuGetApiKey": { - "type": "string", - "default": "Secrets must be entered via 'nuke :secrets [profile]'" - }, - "GitHubReleaseGitHubToken": { - "type": "string", - "default": "Secrets must be entered via 'nuke :secrets [profile]'" - }, "Help": { "type": "boolean", "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" - ] - }, - "IgnoreFailedSources": { - "type": "boolean", - "description": "Ignore unreachable sources during Restore" - }, - "Major": { - "type": "boolean" - }, - "MastodonAccessToken": { - "type": "string", - "default": "Secrets must be entered via 'nuke :secrets [profile]'" + "$ref": "#/definitions/Host" }, "NoLogo": { "type": "boolean", @@ -91,152 +189,30 @@ "type": "string" } }, - "PublicNuGetApiKey": { - "type": "string", - "default": "Secrets must be entered via 'nuke :secrets [profile]'" - }, "Root": { "type": "string", "description": "Root directory during build execution" }, - "SignPathApiToken": { - "type": "string", - "default": "Secrets must be entered via 'nuke :secrets [profile]'" - }, - "SignPathOrganizationId": { - "type": "string" - }, - "SignPathPolicySlug": { - "type": "string" - }, - "SignPathProjectSlug": { - "type": "string" - }, "Skip": { "type": "array", "description": "List of targets to be skipped. Empty list skips all dependencies", "items": { - "type": "string", - "enum": [ - "Announce", - "AnnounceDiscord", - "AnnounceMastodon", - "AnnounceSlack", - "AnnounceTwitter", - "Changelog", - "CheckoutExternalRepositories", - "Clean", - "Compile", - "CreateGitHubRelease", - "DeletePackages", - "DownloadLicenses", - "GenerateGlobalSolution", - "GeneratePublicApi", - "GenerateTools", - "Hotfix", - "Install", - "InstallFonts", - "Milestone", - "Pack", - "Publish", - "References", - "Release", - "ReleaseImage", - "ReportCoverage", - "ReportDuplicates", - "ReportIssues", - "Restore", - "RunTargetInDockerImageTest", - "SignPackages", - "Test", - "UpdateContributors", - "UpdateStargazers" - ] + "$ref": "#/definitions/ExecutableTarget" } }, - "SlackWebhook": { - "type": "string", - "default": "Secrets must be entered via 'nuke :secrets [profile]'" - }, - "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": [ - "Announce", - "AnnounceDiscord", - "AnnounceMastodon", - "AnnounceSlack", - "AnnounceTwitter", - "Changelog", - "CheckoutExternalRepositories", - "Clean", - "Compile", - "CreateGitHubRelease", - "DeletePackages", - "DownloadLicenses", - "GenerateGlobalSolution", - "GeneratePublicApi", - "GenerateTools", - "Hotfix", - "Install", - "InstallFonts", - "Milestone", - "Pack", - "Publish", - "References", - "Release", - "ReleaseImage", - "ReportCoverage", - "ReportDuplicates", - "ReportIssues", - "Restore", - "RunTargetInDockerImageTest", - "SignPackages", - "Test", - "UpdateContributors", - "UpdateStargazers" - ] + "$ref": "#/definitions/ExecutableTarget" } }, - "TestDegreeOfParallelism": { - "type": "integer" - }, - "TwitterAccessToken": { - "type": "string", - "default": "Secrets must be entered via 'nuke :secrets [profile]'" - }, - "TwitterAccessTokenSecret": { - "type": "string", - "default": "Secrets must be entered via 'nuke :secrets [profile]'" - }, - "TwitterConsumerKey": { - "type": "string", - "default": "Secrets must be entered via 'nuke :secrets [profile]'" - }, - "TwitterConsumerSecret": { - "type": "string", - "default": "Secrets must be entered via 'nuke :secrets [profile]'" - }, - "UseHttps": { - "type": "boolean" - }, "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/source/Nuke.Build.Shared/CompletionUtility.cs b/source/Nuke.Build.Shared/CompletionUtility.cs index 327eb816b..edaaaca26 100644 --- a/source/Nuke.Build.Shared/CompletionUtility.cs +++ b/source/Nuke.Build.Shared/CompletionUtility.cs @@ -22,17 +22,47 @@ public static IReadOnlyDictionary GetItemsFromSchema(AbsoluteP public static IReadOnlyDictionary GetItemsFromSchema(JsonDocument schema, IEnumerable profileNames) { - string[] GetEnumValues(JsonElement property) - => property.TryGetProperty("enum", out var enumProperty) - ? enumProperty.EnumerateArray().Select(x => x.GetString()).ToArray() - : property.TryGetProperty("items", out var itemsProperty) - ? GetEnumValues(itemsProperty) - : null; - - var properties = schema.RootElement.GetProperty("definitions").GetProperty("build").GetProperty("properties") - .EnumerateObject().OfType(); - return properties.ToDictionary(x => x.Name, x => GetEnumValues(x.Value)) + var definitions = schema.RootElement.GetProperty("definitions").EnumerateObject().ToDictionary(x => x.Name, x => x); + + var parameterProperties = schema.RootElement.GetProperty("definitions").TryGetProperty("NukeBuild", out var nukebuildProperty) + ? nukebuildProperty.GetProperty("properties").EnumerateObject() + .Concat(schema.RootElement.TryGetProperty("properties", out var properties) ? properties.EnumerateObject() : []) + : definitions["build"].Value.GetProperty("properties").EnumerateObject(); + + return parameterProperties + .Select(x => (x.Name, Values: GetValues(x))) + .Where(x => x.Values != null) + .ToDictionary(x => x.Name, x => x.Values) .SetKeyValue(Constants.LoadedLocalProfilesParameterName, profileNames.ToArray()).AsReadOnly(); + + string[] GetValues(JsonProperty property) + { + if (property.Value.TryGetProperty("type", out var typeProperty)) + { + var types = typeProperty.ValueKind != JsonValueKind.Array + ? [typeProperty.GetString()] + : typeProperty.EnumerateArray().Select(x => x.GetString()).ToArray(); + if (types.ContainsAnyOrdinalIgnoreCase(["string", "boolean", "integer"])) + { + return property.Value.TryGetProperty("enum", out var enumProperty) + ? enumProperty.EnumerateArray().Select(x => x.GetString()).ToArray() + : []; + } + + if (types.Single() == "array") + return GetValues(property.Value.EnumerateObject().Single(x => x.Name == "items")); + + if (types.Single() == "object") + return null; + } + else if (property.Value.TryGetProperty("$ref", out var refProperty)) + { + var definition = definitions.GetValueOrDefault(refProperty.GetString().NotNull().Split('/').LastOrDefault()); + return GetValues(definition); + } + + throw new NotSupportedException(); + } } // ReSharper disable once CognitiveComplexity diff --git a/source/Nuke.Build.Tests/CompletionUtilityTest.TestGetCompletionItemsFromSchema.verified.txt b/source/Nuke.Build.Tests/CompletionUtilityTest.TestGetCompletionItemsFromSchema.verified.txt new file mode 100644 index 000000000..9387e8cae --- /dev/null +++ b/source/Nuke.Build.Tests/CompletionUtilityTest.TestGetCompletionItemsFromSchema.verified.txt @@ -0,0 +1,14 @@ +{ + Configuration: [ + Debug, + Release + ], + NoLogo: [], + Profile: [ + dev + ], + Target: [ + Restore, + Compile + ] +} \ No newline at end of file diff --git a/source/Nuke.Build.Tests/CompletionUtilityTest.TestGetCompletionItemsParameterBuild.verified.txt b/source/Nuke.Build.Tests/CompletionUtilityTest.TestGetCompletionItemsParameterBuild.verified.txt new file mode 100644 index 000000000..cfdb64000 --- /dev/null +++ b/source/Nuke.Build.Tests/CompletionUtilityTest.TestGetCompletionItemsParameterBuild.verified.txt @@ -0,0 +1,38 @@ +{ + BooleanParam: [], + ComponentInheritedParam: [], + Continue: [], + CustomEnumerationArrayParam: [ + Debug, + Release + ], + CustomEnumerationParam: [ + Debug, + Release + ], + Help: [], + Host: [ + Rider, + Terminal, + VisualStudio, + VSCode + ], + IntegerArrayParam: [], + NoLogo: [], + NullableBooleanParam: [], + Partition: [], + Plan: [], + Profile: [], + RegularParam: [], + Root: [], + SecretParam: [], + Skip: [], + StringArrayParam: [], + Target: [], + Verbosity: [ + Verbose, + Normal, + Minimal, + Quiet + ] +} \ No newline at end of file diff --git a/source/Nuke.Build.Tests/CompletionUtilityTest.TestGetCompletionItemsTargetBuild.verified.txt b/source/Nuke.Build.Tests/CompletionUtilityTest.TestGetCompletionItemsTargetBuild.verified.txt new file mode 100644 index 000000000..84f42e6f5 --- /dev/null +++ b/source/Nuke.Build.Tests/CompletionUtilityTest.TestGetCompletionItemsTargetBuild.verified.txt @@ -0,0 +1,35 @@ +{ + Continue: [], + Help: [], + Host: [ + Rider, + Terminal, + VisualStudio, + VSCode + ], + NoLogo: [], + Partition: [], + Plan: [], + Profile: [ + dev + ], + Root: [], + Skip: [ + ExplicitTarget, + ImplementedTarget, + InheritedTarget, + RegularTarget + ], + Target: [ + ExplicitTarget, + ImplementedTarget, + InheritedTarget, + RegularTarget + ], + Verbosity: [ + Verbose, + Normal, + Minimal, + Quiet + ] +} \ No newline at end of file diff --git a/source/Nuke.Build.Tests/CompletionUtilityTest.cs b/source/Nuke.Build.Tests/CompletionUtilityTest.cs index 440aaaa42..35ccab8e4 100644 --- a/source/Nuke.Build.Tests/CompletionUtilityTest.cs +++ b/source/Nuke.Build.Tests/CompletionUtilityTest.cs @@ -6,16 +6,48 @@ using System.Collections.Generic; using System.Linq; using System.Text.Json; +using System.Threading.Tasks; using FluentAssertions; +using Nuke.Common.IO; using Nuke.Common.Utilities; +using VerifyTests; +using VerifyXunit; using Xunit; namespace Nuke.Common.Tests; public class CompletionUtilityTest { + private readonly VerifySettings _verifySettings; + private static AbsolutePath RootDirectory => Constants.TryGetRootDirectoryFrom(EnvironmentInfo.WorkingDirectory).NotNull(); + private static AbsolutePath TestDirectory => RootDirectory / "source" / "Nuke.Build.Tests"; + + public CompletionUtilityTest() + { + _verifySettings = new VerifySettings(); + _verifySettings.DontIgnoreEmptyCollections(); + } + + [Fact] + public async Task TestGetCompletionItemsTargetBuild() + { + var file = TestDirectory / "SchemaUtilityTest.TestTargetBuild.verified.json"; + var schema = JsonDocument.Parse(file.ReadAllText()); + var items = CompletionUtility.GetItemsFromSchema(schema, new[] { "dev" }); + await Verifier.Verify(items, _verifySettings); + } + [Fact] - public void TestGetCompletionItemsFromSchema() + public async Task TestGetCompletionItemsParameterBuild() + { + var file = TestDirectory / "SchemaUtilityTest.TestParameterBuild.verified.json"; + var schema = JsonDocument.Parse(file.ReadAllText()); + var items = CompletionUtility.GetItemsFromSchema(schema, []); + await Verifier.Verify(items, _verifySettings); + } + + [Fact] + public async Task TestGetCompletionItemsFromSchema() { var schema = JsonDocument.Parse(""" { @@ -62,14 +94,7 @@ public void TestGetCompletionItemsFromSchema() """); var profileNames = new[] { "dev" }; var items = CompletionUtility.GetItemsFromSchema(schema, profileNames); - items.Should().BeEquivalentTo( - new Dictionary - { - ["NoLogo"] = null, - ["Configuration"] = new[] { "Debug", "Release" }, - ["Target"] = new[] { "Restore", "Compile" }, - [Constants.LoadedLocalProfilesParameterName] = profileNames - }); + await Verifier.Verify(items, _verifySettings); } [Theory] @@ -94,9 +119,9 @@ public void TestGetRelevantCompletionItems(string words, string[] expectedItems) var completionItems = new Dictionary { - { Constants.InvokedTargetsParameterName, new[] { "Compile", "GitHubPublish" } }, - { "ApiKey", null }, - { "NuGetSource", null } + { Constants.InvokedTargetsParameterName, ["Compile", "GitHubPublish"] }, + { "ApiKey", [] }, + { "NuGetSource", [] } }; CompletionUtility.GetRelevantItems(words, completionItems) .Should() diff --git a/source/Nuke.Build.Tests/SchemaUtilityTest.TestCustomParameterAttributeAttribute.verified.json b/source/Nuke.Build.Tests/SchemaUtilityTest.TestCustomParameterAttributeAttribute.verified.json new file mode 100644 index 000000000..61883c8cf --- /dev/null +++ b/source/Nuke.Build.Tests/SchemaUtilityTest.TestCustomParameterAttributeAttribute.verified.json @@ -0,0 +1,90 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "properties": { + "ComplexTypeParamWithAttribute": { + "type": "string" + } + }, + "definitions": { + "Host": { + "type": "string", + "enum": [ + "Rider", + "Terminal", + "VisualStudio", + "VSCode" + ] + }, + "ExecutableTarget": { + "type": "string" + }, + "Verbosity": { + "type": "string", + "description": "", + "enum": [ + "Verbose", + "Normal", + "Minimal", + "Quiet" + ] + }, + "NukeBuild": { + "properties": { + "Continue": { + "type": "boolean", + "description": "Indicates to continue a previously failed build attempt" + }, + "Help": { + "type": "boolean", + "description": "Shows the help text for this build assembly" + }, + "Host": { + "description": "Host for execution. Default is 'automatic'", + "$ref": "#/definitions/Host" + }, + "NoLogo": { + "type": "boolean", + "description": "Disables displaying the NUKE logo" + }, + "Partition": { + "type": "string", + "description": "Partition to use on CI" + }, + "Plan": { + "type": "boolean", + "description": "Shows the execution plan (HTML)" + }, + "Profile": { + "type": "array", + "description": "Defines the profiles to load", + "items": { + "type": "string" + } + }, + "Root": { + "type": "string", + "description": "Root directory during build execution" + }, + "Skip": { + "type": "array", + "description": "List of targets to be skipped. Empty list skips all dependencies", + "items": { + "$ref": "#/definitions/ExecutableTarget" + } + }, + "Target": { + "type": "array", + "description": "List of targets to be invoked. Default is '{default_target}'", + "items": { + "$ref": "#/definitions/ExecutableTarget" + } + }, + "Verbosity": { + "description": "Logging verbosity during build execution. Default is 'Normal'", + "$ref": "#/definitions/Verbosity" + } + } + } + }, + "$ref": "#/definitions/NukeBuild" +} \ No newline at end of file diff --git a/source/Nuke.Build.Tests/SchemaUtilityTest.TestEmptyBuild.verified.json b/source/Nuke.Build.Tests/SchemaUtilityTest.TestEmptyBuild.verified.json new file mode 100644 index 000000000..997001969 --- /dev/null +++ b/source/Nuke.Build.Tests/SchemaUtilityTest.TestEmptyBuild.verified.json @@ -0,0 +1,85 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "definitions": { + "Host": { + "type": "string", + "enum": [ + "Rider", + "Terminal", + "VisualStudio", + "VSCode" + ] + }, + "ExecutableTarget": { + "type": "string" + }, + "Verbosity": { + "type": "string", + "description": "", + "enum": [ + "Verbose", + "Normal", + "Minimal", + "Quiet" + ] + }, + "NukeBuild": { + "properties": { + "Continue": { + "type": "boolean", + "description": "Indicates to continue a previously failed build attempt" + }, + "Help": { + "type": "boolean", + "description": "Shows the help text for this build assembly" + }, + "Host": { + "description": "Host for execution. Default is 'automatic'", + "$ref": "#/definitions/Host" + }, + "NoLogo": { + "type": "boolean", + "description": "Disables displaying the NUKE logo" + }, + "Partition": { + "type": "string", + "description": "Partition to use on CI" + }, + "Plan": { + "type": "boolean", + "description": "Shows the execution plan (HTML)" + }, + "Profile": { + "type": "array", + "description": "Defines the profiles to load", + "items": { + "type": "string" + } + }, + "Root": { + "type": "string", + "description": "Root directory during build execution" + }, + "Skip": { + "type": "array", + "description": "List of targets to be skipped. Empty list skips all dependencies", + "items": { + "$ref": "#/definitions/ExecutableTarget" + } + }, + "Target": { + "type": "array", + "description": "List of targets to be invoked. Default is '{default_target}'", + "items": { + "$ref": "#/definitions/ExecutableTarget" + } + }, + "Verbosity": { + "description": "Logging verbosity during build execution. Default is 'Normal'", + "$ref": "#/definitions/Verbosity" + } + } + } + }, + "$ref": "#/definitions/NukeBuild" +} diff --git a/source/Nuke.Build.Tests/SchemaUtilityTest.TestGetBuildSchema.verified.txt b/source/Nuke.Build.Tests/SchemaUtilityTest.TestGetBuildSchema.verified.json similarity index 71% rename from source/Nuke.Build.Tests/SchemaUtilityTest.TestGetBuildSchema.verified.txt rename to source/Nuke.Build.Tests/SchemaUtilityTest.TestGetBuildSchema.verified.json index 1655c4007..31e7c1171 100644 --- a/source/Nuke.Build.Tests/SchemaUtilityTest.TestGetBuildSchema.verified.txt +++ b/source/Nuke.Build.Tests/SchemaUtilityTest.TestGetBuildSchema.verified.json @@ -6,40 +6,63 @@ "build": { "type": "object", "properties": { - "ComponentParam1": { + "BooleanParam": { + "type": "boolean" + }, + "ComplexTypeArrayParam": { + "type": "array", + "items": { + "type": "string" + } + }, + "ComplexTypeParam": { + "type": "string" + }, + "ComponentInheritedParam": { "type": "string" }, "Continue": { "type": "boolean", "description": "Indicates to continue a previously failed build attempt" }, + "CustomEnumerationArrayParam": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "Debug", + "Release" + ] + } + }, + "CustomEnumerationParam": { + "type": "string", + "enum": [ + "Debug", + "Release" + ] + }, "Help": { "type": "boolean", "description": "Shows the help text for this build assembly" }, "Host": { "type": "string", - "description": "Host for execution. Default is 'automatic'", - "enum": [ - "Rider", - "Terminal", - "VisualStudio", - "VSCode" - ] + "description": "Host for execution. Default is 'automatic'" + }, + "IntegerArrayParam": { + "type": "array", + "items": { + "type": "integer" + } }, "NoLogo": { "type": "boolean", "description": "Disables displaying the NUKE logo" }, - "NullableBool": { + "NullableBooleanParam": { "type": "boolean" }, - "NullableInteger": { - "type": "integer" - }, - "Param": { - "type": "string" - }, "Partition": { "type": "string", "description": "Partition to use on CI" @@ -55,11 +78,14 @@ "type": "string" } }, + "RegularParam": { + "type": "string" + }, "Root": { "type": "string", "description": "Root directory during build execution" }, - "Secret": { + "SecretParam": { "type": "string", "default": "Secrets must be entered via 'nuke :secrets [profile]'" }, @@ -67,36 +93,20 @@ "type": "array", "description": "List of targets to be skipped. Empty list skips all dependencies", "items": { - "type": "string", - "enum": [ - "Bar", - "Foo", - "Zoo" - ] + "type": "string" } }, - "Target": { + "StringArrayParam": { "type": "array", - "description": "List of targets to be invoked. Default is '{default_target}'", "items": { - "type": "string", - "enum": [ - "Bar", - "Foo", - "Zoo" - ] + "type": "string" } }, - "Verbosities": { + "Target": { "type": "array", + "description": "List of targets to be invoked. Default is '{default_target}'", "items": { - "type": "string", - "enum": [ - "Minimal", - "Normal", - "Quiet", - "Verbose" - ] + "type": "string" } }, "Verbosity": { diff --git a/source/Nuke.Build.Tests/SchemaUtilityTest.TestParameterBuild.verified.json b/source/Nuke.Build.Tests/SchemaUtilityTest.TestParameterBuild.verified.json new file mode 100644 index 000000000..124ede2f2 --- /dev/null +++ b/source/Nuke.Build.Tests/SchemaUtilityTest.TestParameterBuild.verified.json @@ -0,0 +1,190 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "properties": { + "BooleanParam": { + "type": "boolean" + }, + "ComplexTypeArrayParam": { + "type": "array", + "items": { + "$ref": "#/definitions/ComplexType" + } + }, + "ComplexTypeParam": { + "$ref": "#/definitions/ComplexType" + }, + "ComponentInheritedParam": { + "type": "string" + }, + "CustomEnumerationArrayParam": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "Debug", + "Release" + ] + } + }, + "CustomEnumerationParam": { + "type": "string", + "enum": [ + "Debug", + "Release" + ] + }, + "IntegerArrayParam": { + "type": "array", + "items": { + "type": "integer", + "format": "int32" + } + }, + "NullableBooleanParam": { + "type": [ + "boolean", + "null" + ] + }, + "RegularParam": { + "type": "string" + }, + "SecretParam": { + "type": "string", + "default": "Secrets must be entered via 'nuke :secrets [profile]'" + }, + "StringArrayParam": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "definitions": { + "ComplexType": { + "type": "object", + "properties": { + "String": { + "type": [ + "null", + "string" + ] + }, + "Number": { + "type": "integer", + "format": "int32" + }, + "Paths": { + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + } + }, + "SubObject": { + "oneOf": [ + { + "type": "null" + }, + { + "$ref": "#/definitions/ComplexSubType" + } + ] + } + } + }, + "ComplexSubType": { + "type": "object", + "properties": { + "Boolean": { + "type": [ + "boolean", + "null" + ] + } + } + }, + "Host": { + "type": "string", + "enum": [ + "Rider", + "Terminal", + "VisualStudio", + "VSCode" + ] + }, + "ExecutableTarget": { + "type": "string" + }, + "Verbosity": { + "type": "string", + "description": "", + "enum": [ + "Verbose", + "Normal", + "Minimal", + "Quiet" + ] + }, + "NukeBuild": { + "properties": { + "Continue": { + "type": "boolean", + "description": "Indicates to continue a previously failed build attempt" + }, + "Help": { + "type": "boolean", + "description": "Shows the help text for this build assembly" + }, + "Host": { + "description": "Host for execution. Default is 'automatic'", + "$ref": "#/definitions/Host" + }, + "NoLogo": { + "type": "boolean", + "description": "Disables displaying the NUKE logo" + }, + "Partition": { + "type": "string", + "description": "Partition to use on CI" + }, + "Plan": { + "type": "boolean", + "description": "Shows the execution plan (HTML)" + }, + "Profile": { + "type": "array", + "description": "Defines the profiles to load", + "items": { + "type": "string" + } + }, + "Root": { + "type": "string", + "description": "Root directory during build execution" + }, + "Skip": { + "type": "array", + "description": "List of targets to be skipped. Empty list skips all dependencies", + "items": { + "$ref": "#/definitions/ExecutableTarget" + } + }, + "Target": { + "type": "array", + "description": "List of targets to be invoked. Default is '{default_target}'", + "items": { + "$ref": "#/definitions/ExecutableTarget" + } + }, + "Verbosity": { + "description": "Logging verbosity during build execution. Default is 'Normal'", + "$ref": "#/definitions/Verbosity" + } + } + } + }, + "$ref": "#/definitions/NukeBuild" +} \ No newline at end of file diff --git a/source/Nuke.Build.Tests/SchemaUtilityTest.TestTargetBuild.verified.json b/source/Nuke.Build.Tests/SchemaUtilityTest.TestTargetBuild.verified.json new file mode 100644 index 000000000..25a38901b --- /dev/null +++ b/source/Nuke.Build.Tests/SchemaUtilityTest.TestTargetBuild.verified.json @@ -0,0 +1,91 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "definitions": { + "Host": { + "type": "string", + "enum": [ + "Rider", + "Terminal", + "VisualStudio", + "VSCode" + ] + }, + "ExecutableTarget": { + "type": "string", + "enum": [ + "ExplicitTarget", + "ImplementedTarget", + "InheritedTarget", + "RegularTarget" + ] + }, + "Verbosity": { + "type": "string", + "description": "", + "enum": [ + "Verbose", + "Normal", + "Minimal", + "Quiet" + ] + }, + "NukeBuild": { + "properties": { + "Continue": { + "type": "boolean", + "description": "Indicates to continue a previously failed build attempt" + }, + "Help": { + "type": "boolean", + "description": "Shows the help text for this build assembly" + }, + "Host": { + "description": "Host for execution. Default is 'automatic'", + "$ref": "#/definitions/Host" + }, + "NoLogo": { + "type": "boolean", + "description": "Disables displaying the NUKE logo" + }, + "Partition": { + "type": "string", + "description": "Partition to use on CI" + }, + "Plan": { + "type": "boolean", + "description": "Shows the execution plan (HTML)" + }, + "Profile": { + "type": "array", + "description": "Defines the profiles to load", + "items": { + "type": "string" + } + }, + "Root": { + "type": "string", + "description": "Root directory during build execution" + }, + "Skip": { + "type": "array", + "description": "List of targets to be skipped. Empty list skips all dependencies", + "items": { + "$ref": "#/definitions/ExecutableTarget" + } + }, + "Target": { + "type": "array", + "description": "List of targets to be invoked. Default is '{default_target}'", + "items": { + "$ref": "#/definitions/ExecutableTarget" + } + }, + "Verbosity": { + "description": "Logging verbosity during build execution. Default is 'Normal'", + "$ref": "#/definitions/Verbosity" + } + } + } + }, + "$ref": "#/definitions/NukeBuild" +} diff --git a/source/Nuke.Build.Tests/SchemaUtilityTest.cs b/source/Nuke.Build.Tests/SchemaUtilityTest.cs index cb29d2472..559c02e00 100644 --- a/source/Nuke.Build.Tests/SchemaUtilityTest.cs +++ b/source/Nuke.Build.Tests/SchemaUtilityTest.cs @@ -3,52 +3,128 @@ // https://github.com/nuke-build/nuke/blob/master/LICENSE using System; +using System.ComponentModel; using System.Linq; -using System.Text.Encodings.Web; -using System.Text.Json; using System.Threading.Tasks; using Nuke.Common.Execution; +using Nuke.Common.IO; +using Nuke.Common.Tooling; +using Nuke.Common.Utilities; using VerifyXunit; using Xunit; +#pragma warning disable CS0169 // Field is never used + namespace Nuke.Common.Tests; public class SchemaUtilityTest { [Fact] - public Task TestGetBuildSchema() + public Task TestEmptyBuild() + { + var jsonSchema = SchemaUtility.GetJsonString(new EmptyBuild()); + return Verifier.Verify(jsonSchema, "json"); + } + + [Fact] + public Task TestTargetBuild() + { + var jsonSchema = SchemaUtility.GetJsonString(new TargetBuild()); + return Verifier.Verify(jsonSchema, "json"); + } + + [Fact] + public Task TestParameterBuild() + { + var jsonSchema = SchemaUtility.GetJsonString(new ParameterBuild()); + return Verifier.Verify(jsonSchema, "json"); + } + + [Fact] + public Task TestCustomParameterAttributeAttribute() + { + var jsonSchema = SchemaUtility.GetJsonString(new CustomParameterAttributeBuild()); + return Verifier.Verify(jsonSchema, "json"); + } + + // ReSharper disable All +#pragma warning disable CS0414 // Field is assigned but its value is never used +#pragma warning disable CS0649 // Field is never assigned to, and will always have its default value + private class EmptyBuild : NukeBuild { - var schema = SchemaUtility.GetBuildSchema(new TestBuild()); - var options = new JsonSerializerOptions { WriteIndented = true, Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping }; - var json = JsonSerializer.Serialize(schema, options); - return Verifier.Verify(json); } -#pragma warning disable CS0649 - private class TestBuild : NukeBuild, ITestComponent + private class TargetBuild : NukeBuild, ITargetComponent { - [Parameter] public string Param; - [Parameter] public bool? NullableBool; - [Parameter] public int? NullableInteger; - [Parameter] public Verbosity[] Verbosities; - [Parameter] [Secret] public string Secret; - public string Param2 => ""; - string ITestComponent.Param3 => ""; + Target RegularTarget => _ => _; + public Target ImplementedTarget => _ => _; + Target ITargetComponent.ExplicitTarget => _ => _; + } - Target ITestComponent.Bar => _ => _; - public Target Zoo => _ => _; + private interface ITargetComponent : INukeBuild + { + Target InheritedTarget => _ => _; + Target ImplementedTarget => _ => _; + Target ExplicitTarget => _ => _; + } + + private class ParameterBuild : NukeBuild, IParameterComponent + { + [Parameter] readonly string RegularParam; + [Parameter] [Secret] readonly string SecretParam; + + [Parameter] readonly bool BooleanParam; + [Parameter] readonly bool? NullableBooleanParam; + + [Parameter] readonly string[] StringArrayParam; + [Parameter] readonly int[] IntegerArrayParam; + + [Parameter] readonly CustomEnumeration CustomEnumerationParam; + [Parameter] readonly CustomEnumeration[] CustomEnumerationArrayParam; + + [Parameter] readonly ComplexType ComplexTypeParam; + [Parameter] readonly ComplexType[] ComplexTypeArrayParam; } [ParameterPrefix("Component")] - private interface ITestComponent : INukeBuild + private interface IParameterComponent : INukeBuild { - [Parameter] string Param1 => TryGetValue(() => Param1); - [Parameter] string Param2 => TryGetValue(() => Param2); - [Parameter] string Param3 => TryGetValue(() => Param3); + [Parameter] string InheritedParam => TryGetValue(() => InheritedParam); + } - Target Foo => _ => _; - Target Bar => _ => _; - Target Zoo => _ => _; + private class ComplexType + { + public string String; + public int Number; + public AbsolutePath[] Paths; + public ComplexSubType SubObject; + } + + private class ComplexSubType + { + public bool? Boolean; } -#pragma warning restore CS0649 + + [TypeConverter(typeof(TypeConverter))] + private class CustomEnumeration : Enumeration + { + public static CustomEnumeration Debug = new() { Value = nameof(Debug) }; + public static CustomEnumeration Release = new() { Value = nameof(Release) }; + + public static implicit operator string(CustomEnumeration configuration) + { + return configuration.Value; + } + } + + private class CustomParameterAttributeBuild : NukeBuild + { + [CustomParameter] readonly ComplexType ComplexTypeParamWithAttribute; + } + + private class CustomParameterAttribute : ParameterAttribute; + +#pragma warning restore CS0649 // Field is never assigned to, and will always have its default value +#pragma warning restore CS0414 // Field is assigned but its value is never used + // ReSharper restore All } diff --git a/source/Nuke.Build.Tests/parameters.json b/source/Nuke.Build.Tests/parameters.json new file mode 100644 index 000000000..0b2ee0afb --- /dev/null +++ b/source/Nuke.Build.Tests/parameters.json @@ -0,0 +1,5 @@ +{ + "$schema": "./SchemaUtilityTest.TestTargetBuild.verified.json", + "Verbosity": "Minimal", + "Target": ["ExplicitTarget", "InheritedTarget"] +} diff --git a/source/Nuke.Build/Execution/Extensions/HandleShellCompletionAttribute.cs b/source/Nuke.Build/Execution/Extensions/HandleShellCompletionAttribute.cs index 152d031fe..0baf73f2f 100644 --- a/source/Nuke.Build/Execution/Extensions/HandleShellCompletionAttribute.cs +++ b/source/Nuke.Build/Execution/Extensions/HandleShellCompletionAttribute.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.Linq; using Nuke.Common.CI; +using Nuke.Common.IO; using Nuke.Common.Utilities; using static Nuke.Common.Constants; @@ -31,12 +32,23 @@ public void OnBuildCreated(IReadOnlyCollection executableTarge } else if (Build.BuildProjectFile != null) { - SchemaUtility.WriteBuildSchemaFile(Build); - SchemaUtility.WriteDefaultParametersFile(Build); + var buildSchema = SchemaUtility.GetJsonString(Build); + var buildSchemaFile = GetBuildSchemaFile(Build.RootDirectory); + buildSchemaFile.WriteAllText(buildSchema); + + var parametersFile = GetDefaultParametersFile(Build.RootDirectory); + if (!parametersFile.Exists()) + { + parametersFile.WriteAllText($$""" + { + "$schema": "./{{BuildSchemaFileName}}" + } + """); + } } else if (ParameterService.GetPositionalArgument(0) == ":complete") { - var schema = SchemaUtility.GetBuildSchema(Build); + var schema = SchemaUtility.GetJsonDocument(Build); var profileNames = GetProfileNames(Build.RootDirectory); var completionItems = CompletionUtility.GetItemsFromSchema(schema, profileNames); diff --git a/source/Nuke.Build/Nuke.Build.csproj b/source/Nuke.Build/Nuke.Build.csproj index f30534e9c..746e8dee7 100644 --- a/source/Nuke.Build/Nuke.Build.csproj +++ b/source/Nuke.Build/Nuke.Build.csproj @@ -19,6 +19,7 @@ + diff --git a/source/Nuke.Build/NukeBuild.Statics.cs b/source/Nuke.Build/NukeBuild.Statics.cs index 39157c7db..a400dd825 100644 --- a/source/Nuke.Build/NukeBuild.Statics.cs +++ b/source/Nuke.Build/NukeBuild.Statics.cs @@ -82,7 +82,7 @@ public static Verbosity Verbosity /// /// Gets the host for execution. Default is automatic. /// - [Parameter("Host for execution. Default is 'automatic'.", ValueProviderMember = nameof(HostNames))] + [Parameter("Host for execution. Default is 'automatic'.")] public static Host Host { get; set; } [Parameter("Defines the profiles to load.", Name = LoadedLocalProfilesParameterName)] diff --git a/source/Nuke.Build/NukeBuild.cs b/source/Nuke.Build/NukeBuild.cs index d4ca73bc3..6f9aa302d 100644 --- a/source/Nuke.Build/NukeBuild.cs +++ b/source/Nuke.Build/NukeBuild.cs @@ -87,8 +87,7 @@ protected static int Execute(params Expression>[] defaultTarg /// [Parameter("List of targets to be invoked. Default is '{default_target}'.", Name = InvokedTargetsParameterName, - Separator = TargetsSeparator, - ValueProviderMember = nameof(TargetNames))] + Separator = TargetsSeparator)] public IReadOnlyCollection InvokedTargets => ExecutionPlan.Where(x => x.Invoked).ToList(); /// @@ -96,8 +95,7 @@ protected static int Execute(params Expression>[] defaultTarg /// [Parameter("List of targets to be skipped. Empty list skips all dependencies.", Name = SkippedTargetsParameterName, - Separator = TargetsSeparator, - ValueProviderMember = nameof(TargetNames))] + Separator = TargetsSeparator)] public IReadOnlyCollection SkippedTargets => ExecutionPlan.Where(x => x.Status == ExecutionStatus.Skipped).ToList(); /// diff --git a/source/Nuke.Build/Utilities/SchemaUtility.cs b/source/Nuke.Build/Utilities/SchemaUtility.cs index 4d61f96d8..b5a7acbbf 100644 --- a/source/Nuke.Build/Utilities/SchemaUtility.cs +++ b/source/Nuke.Build/Utilities/SchemaUtility.cs @@ -5,9 +5,15 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Text.Encodings.Web; +using System.Reflection; using System.Text.Json; -using Nuke.Common.IO; +using Namotion.Reflection; +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; +using Newtonsoft.Json.Serialization; +using NJsonSchema; +using NJsonSchema.Generation; +using NuGet.Packaging; using Nuke.Common.Utilities; using Nuke.Common.ValueInjection; using static Nuke.Common.Constants; @@ -16,93 +22,146 @@ namespace Nuke.Common.Execution; public class SchemaUtility { - public static void WriteBuildSchemaFile(INukeBuild build) + private class SchemaGenerator : JsonSchemaGenerator { - var buildSchemaFile = GetBuildSchemaFile(build.RootDirectory); - var buildSchema = GetBuildSchema(build); - var options = new JsonSerializerOptions { WriteIndented = true, Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping }; - var json = JsonSerializer.Serialize(buildSchema, options); - buildSchemaFile.WriteAllText(json); - } + private class Resolver : DefaultContractResolver + { + protected override List GetSerializableMembers(Type objectType) + { + return objectType == typeof(ExecutableTarget) || objectType == typeof(Host) + ? new List() + : base.GetSerializableMembers(objectType); + } + } - // ReSharper disable once CognitiveComplexity - public static JsonDocument GetBuildSchema(INukeBuild build) - { - var parameters = ValueInjectionUtility - .GetParameterMembers(build.GetType(), includeUnlisted: true) - // .Where(x => x.DeclaringType != typeof(NukeBuild)) - .Select(x => - new + public static JsonSchema Generate(T build) where T : INukeBuild + { + return new SchemaGenerator( + build, + new JsonSchemaGeneratorSettings { - Name = ParameterService.GetParameterMemberName(x), - Description = ParameterService.GetParameterDescription(x), - MemberType = x.GetMemberType(), - ScalarType = x.GetMemberType().GetScalarType(), - EnumValues = ParameterService.GetParameterValueSet(x, build)?.Select(x => x.Text), - IsRequired = x.HasCustomAttribute(), - IsSecret = x.HasCustomAttribute() - }).ToList(); - - string GetJsonType(Type type) - => type.IsCollectionLike() - ? "array" - : type.GetScalarType() == typeof(int) - ? "integer" - : type.GetScalarType() == typeof(bool) - ? "boolean" - : "string"; - - var properties = new Dictionary(); - foreach (var parameter in parameters) + FlattenInheritanceHierarchy = true, + SerializerSettings = + new JsonSerializerSettings + { + ContractResolver = new Resolver(), + Converters = new JsonConverter[] { new StringEnumConverter() } + } + }).Generate(); + } + + private readonly INukeBuild _build; + + private SchemaGenerator(INukeBuild build, JsonSchemaGeneratorSettings settings) + : base(settings) + { + _build = build; + } + + private JsonSchema Generate() { - var property = new Dictionary(); - property["type"] = GetJsonType(parameter.MemberType); + var baseSchema = new JsonSchema(); + var userSchema = new JsonSchema(); + var schemaResolver = new JsonSchemaResolver(userSchema, Settings); + + var parameterMembers = ValueInjectionUtility.GetParameterMembers(_build.GetType(), includeUnlisted: true); + foreach (var parameterMember in parameterMembers) + { + var schema = parameterMember.DeclaringType == typeof(NukeBuild) ? baseSchema : userSchema; + var name = ParameterService.GetParameterMemberName(parameterMember); + var property = CreateProperty(parameterMember, schemaResolver); + schema.Properties[name] = property; + } + + // ValueInjectionUtility.GetParameterMembers(_build.GetType(), includeUnlisted: true) + // // .Where(x => x.Name.EqualsAnyOrdinalIgnoreCase( + // // nameof(NukeBuild.SkippedTargets), + // // nameof(NukeBuild.InvokedTargets), + // // nameof(NukeBuild.Verbosity) + // // )) + // .ToDictionary(ParameterService.GetParameterMemberName, x => CreateProperty(x, schemaResolver)) + // .ForEach(x => + // { + // baseSchema.Properties[x.Key] = x.Value; + // }); - if (parameter.Description != null) - property["description"] = parameter.Description; + userSchema.Reference = baseSchema; + userSchema.Definitions[nameof(NukeBuild)] = baseSchema; - if (parameter.IsSecret) - property["default"] = "Secrets must be entered via 'nuke :secrets [profile]'"; + // TODO: why can't this use value sets? + var targetNames = ExecutableTargetFactory.GetTargetProperties(_build.GetType()).Select(x => x.GetDisplayShortName()).OrderBy(x => x); + var executableTargetSchema = UpdatePropertySchema(nameof(ExecutableTarget), targetNames); + baseSchema.Properties[InvokedTargetsParameterName].Item = + baseSchema.Properties[SkippedTargetsParameterName].Item = new JsonSchema { Reference = executableTargetSchema }; - if (parameter.EnumValues != null && !parameter.MemberType.IsCollectionLike()) - property["enum"] = parameter.EnumValues; + var hostNames = Host.AvailableTypes.Select(x => x.Name).OrderBy(x => x); + var hostSchema = UpdatePropertySchema(nameof(NukeBuild.Host), hostNames); + baseSchema.Properties[nameof(NukeBuild.Host)].Reference = hostSchema; - if (parameter.MemberType.IsCollectionLike()) + RemoveXEnumValues(); + + return userSchema; + + JsonSchema UpdatePropertySchema(string name, IEnumerable values) { - var items = new Dictionary(); - items["type"] = GetJsonType(parameter.ScalarType); - if (parameter.EnumValues != null) - items["enum"] = parameter.EnumValues; - property["items"] = items; + var schema = userSchema.Definitions[name]; + schema.Type = JsonObjectType.String; + schema.AllowAdditionalProperties = true; + schema.Enumeration.AddRange(values); + return schema; } - properties[parameter.Name] = property; + void RemoveXEnumValues() + { + foreach (var definition in userSchema.Definitions.Values) + { + definition.EnumerationNames.Clear(); + definition.AllowAdditionalProperties = true; + } + } } - var build2 = new Dictionary { ["type"] = "object", ["properties"] = properties }; - var definitions = new Dictionary { ["build"] = build2 }; - var jsonDictionary = new Dictionary - { - ["$schema"] = "http://json-schema.org/draft-04/schema#", - ["$ref"] = "#/definitions/build", - ["title"] = "Build Schema", - ["definitions"] = definitions - }; - return JsonDocument.Parse(JsonSerializer.Serialize(jsonDictionary)); + private JsonSchemaProperty CreateProperty(MemberInfo parameterMember, JsonSchemaResolver schemaResolver) + { + var property = parameterMember.GetCustomAttribute().NotNull().GetType() == typeof(ParameterAttribute) + ? GenerateWithReference( + parameterMember.ToContextualAccessor().AccessorType, + schemaResolver) + : new JsonSchemaProperty { Type = JsonObjectType.String }; + + property.Description = ParameterService.GetParameterDescription(parameterMember); + property.Default = parameterMember.HasCustomAttribute() + ? "Secrets must be entered via 'nuke :secrets [profile]'" + : null; + + var values = ParameterService.GetParameterValueSet(parameterMember, _build) + ?.Select(x => (object)x.Text); + if (values != null && !parameterMember.GetMemberType().IsEnum) + { + property.Type = !parameterMember.GetMemberType().IsCollectionLike() + ? JsonObjectType.String + : JsonObjectType.Array; + var propertySchema = property.Reference ?? property; + if (property.Type == JsonObjectType.String) + propertySchema.Enumeration.AddRange(values); + else + propertySchema.Item.Enumeration.AddRange(values); + } + + if (Nullable.GetUnderlyingType(parameterMember.GetMemberType()) != null) + property.Type |= JsonObjectType.Null; + + return property; + } } - public static void WriteDefaultParametersFile(INukeBuild build) + public static string GetJsonString(INukeBuild build) { - var parametersFile = GetDefaultParametersFile(build.RootDirectory); - if (parametersFile.Exists()) - return; + return SchemaGenerator.Generate(build).ToJson(); + } - parametersFile.WriteAllLines( - new[] - { - "{", - $" \"$schema\": \"./{BuildSchemaFileName}\"", - "}" - }); + public static JsonDocument GetJsonDocument(INukeBuild build) + { + return JsonDocument.Parse(GetJsonString(build)); } } From 4acc722cef1ded0cd3fc4c53e692be7f09037ea8 Mon Sep 17 00:00:00 2001 From: Matthias Koch Date: Thu, 30 Jun 2022 23:53:29 +0200 Subject: [PATCH 37/56] feat(execution): deserialize full objects from parameters.json --- .nuke/build.schema.json | 33 ++++-- .nuke/parameters.json | 8 +- .teamcity/settings.kts | 18 +-- nuke-common.sln.DotSettings | 3 +- .../Nuke.Build.Tests/ParameterServiceTest.cs | 38 +++---- .../ArgumentsFromParametersFileAttribute.cs | 103 +++++++++--------- .../Nuke.Build/Execution/ParameterService.cs | 6 +- source/Nuke.Components/ISignPackages.cs | 23 ++-- 8 files changed, 119 insertions(+), 113 deletions(-) diff --git a/.nuke/build.schema.json b/.nuke/build.schema.json index 956ab15ae..719ef126d 100644 --- a/.nuke/build.schema.json +++ b/.nuke/build.schema.json @@ -46,14 +46,8 @@ "type": "string", "default": "Secrets must be entered via 'nuke :secrets [profile]'" }, - "SignPathOrganizationId": { - "type": "string" - }, - "SignPathPolicySlug": { - "type": "string" - }, - "SignPathProjectSlug": { - "type": "string" + "SignPathSettings": { + "$ref": "#/definitions/SignPathSettings" }, "SlackWebhook": { "type": "string", @@ -108,6 +102,29 @@ "VSCode" ] }, + "SignPathSettings": { + "type": "object", + "properties": { + "OrganizationId": { + "type": [ + "null", + "string" + ] + }, + "ProjectSlug": { + "type": [ + "null", + "string" + ] + }, + "PolicySlug": { + "type": [ + "null", + "string" + ] + } + } + }, "ExecutableTarget": { "type": "string", "enum": [ diff --git a/.nuke/parameters.json b/.nuke/parameters.json index 458f25181..0ca1a709e 100644 --- a/.nuke/parameters.json +++ b/.nuke/parameters.json @@ -1,7 +1,9 @@ { "$schema": "./build.schema.json", "Solution": "nuke-common.sln", - "SignPathOrganizationId": "0fdaf334-6910-41f4-83d2-e58e4cccb087", - "SignPathProjectSlug": "nuke", - "SignPathPolicySlug": "release-signing" + "SignPathSettings": { + "OrganizationId": "0fdaf334-6910-41f4-83d2-e58e4cccb087", + "ProjectSlug": "nuke", + "PolicySlug": "release-signing" + } } diff --git a/.teamcity/settings.kts b/.teamcity/settings.kts index 2288fd20a..62b866404 100644 --- a/.teamcity/settings.kts +++ b/.teamcity/settings.kts @@ -63,21 +63,9 @@ project { unchecked = "False", display = ParameterDisplay.NORMAL) text ( - "env.SignPathOrganizationId", - label = "SignPathOrganizationId", - value = "0fdaf334-6910-41f4-83d2-e58e4cccb087", - allowEmpty = true, - display = ParameterDisplay.NORMAL) - text ( - "env.SignPathPolicySlug", - label = "SignPathPolicySlug", - value = "release-signing", - allowEmpty = true, - display = ParameterDisplay.NORMAL) - text ( - "env.SignPathProjectSlug", - label = "SignPathProjectSlug", - value = "nuke", + "env.SignPathSettings", + label = "SignPathSettings", + value = "", allowEmpty = true, display = ParameterDisplay.NORMAL) text ( diff --git a/nuke-common.sln.DotSettings b/nuke-common.sln.DotSettings index 08232f1f4..ece833ace 100644 --- a/nuke-common.sln.DotSettings +++ b/nuke-common.sln.DotSettings @@ -1,5 +1,5 @@  - Copyright $CURRENT_YEAR$ Maintainers of NUKE. + Copyright ${CurrentDate.Year} Maintainers of NUKE. Distributed under the MIT License. https://github.com/nuke-build/nuke/blob/master/LICENSE <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb_AaBb" /> @@ -17,4 +17,5 @@ https://github.com/nuke-build/nuke/blob/master/LICENSE 3 True 1 + True diff --git a/source/Nuke.Build.Tests/ParameterServiceTest.cs b/source/Nuke.Build.Tests/ParameterServiceTest.cs index 59f94c307..5ca5c5468 100644 --- a/source/Nuke.Build.Tests/ParameterServiceTest.cs +++ b/source/Nuke.Build.Tests/ParameterServiceTest.cs @@ -48,12 +48,11 @@ public void TestNotSupplied(Type destinationType, object expectedValue) public void TestEnvironmentVariables(string parameter, Type destinationType, object expectedValue) { var service = GetService( - new[] - { + [ "-arg1", "value1", "-switch1" - }, + ], new Dictionary { { "arg1", "value2" }, @@ -68,15 +67,14 @@ public void TestEnvironmentVariables(string parameter, Type destinationType, obj public void TestExpression() { var service = GetService( - new[] - { + [ "--string", "--set", "1", "2", "3", "--interface-param" - }); + ]); var build = new TestBuild(); @@ -98,12 +96,12 @@ public void TestValueSet() { var build = new TestBuild(); var verbosities = new[] - { - (nameof(Verbosity.Minimal), Verbosity.Minimal), - (nameof(Verbosity.Normal), Verbosity.Normal), - (nameof(Verbosity.Quiet), Verbosity.Quiet), - (nameof(Verbosity.Verbose), Verbosity.Verbose), - }; + { + (nameof(Verbosity.Minimal), Verbosity.Minimal), + (nameof(Verbosity.Normal), Verbosity.Normal), + (nameof(Verbosity.Quiet), Verbosity.Quiet), + (nameof(Verbosity.Verbose), Verbosity.Verbose), + }; ParameterService.GetParameterValueSet(GetMemberInfo(() => NukeBuild.Verbosity), instance: null) .Should().BeEquivalentTo(verbosities); ParameterService.GetParameterValueSet(GetMemberInfo(() => build.Verbosities), instance: null) @@ -118,13 +116,13 @@ public void TestPrecedence() var environmentVariables = new Dictionary { ["string"] = "environmentVariables" }; var commandLineArguments = new ArgumentParser("--string commandLine"); - var parameterFileArguments = new ArgumentParser("--string parameterFile"); + var parameterFileArguments = new Func((_, _) => "parameterFile"); var commitMessageArguments = new ArgumentParser("--string commitMessage"); var service = new ParameterService(() => emptyArguments, () => emptyEnvironmentVariables) - { - ArgumentsFromFilesService = parameterFileArguments - }; + { + ArgumentsFromFilesService = parameterFileArguments + }; service.GetParameter("string", typeof(string), separator: null).Should().Be("parameterFile"); service = new ParameterService(() => emptyArguments, () => environmentVariables) { ArgumentsFromFilesService = parameterFileArguments }; @@ -134,10 +132,10 @@ public void TestPrecedence() service.GetParameter("string", typeof(string), separator: null).Should().Be("commandLine"); service = new ParameterService(() => emptyArguments, () => emptyEnvironmentVariables) - { - ArgumentsFromFilesService = parameterFileArguments, - ArgumentsFromCommitMessageService = commitMessageArguments - }; + { + ArgumentsFromFilesService = parameterFileArguments, + ArgumentsFromCommitMessageService = commitMessageArguments + }; service.GetParameter("string", typeof(string), separator: null).Should().Be("commitMessage"); } diff --git a/source/Nuke.Build/Execution/Extensions/ArgumentsFromParametersFileAttribute.cs b/source/Nuke.Build/Execution/Extensions/ArgumentsFromParametersFileAttribute.cs index 1a2b1c97d..2baaff2dc 100644 --- a/source/Nuke.Build/Execution/Extensions/ArgumentsFromParametersFileAttribute.cs +++ b/source/Nuke.Build/Execution/Extensions/ArgumentsFromParametersFileAttribute.cs @@ -13,33 +13,51 @@ using Nuke.Common.Utilities; using Nuke.Common.Utilities.Collections; using Nuke.Common.ValueInjection; -using Serilog; namespace Nuke.Common.Execution; -internal class ArgumentsFromParametersFileAttribute : BuildExtensionAttributeBase, IOnBuildCreated +[PublicAPI] +public class ArgumentsFromParametersFileAttribute : BuildExtensionAttributeBase, IOnBuildCreated { public void OnBuildCreated(IReadOnlyCollection executableTargets) { // TODO: probably remove - if (!Directory.Exists(Constants.GetNukeDirectory(Build.RootDirectory))) + if (!Constants.GetNukeDirectory(NukeBuild.RootDirectory).DirectoryExists()) return; + + // IEnumerable ConvertToArguments(string profile, string name, string[] values) + // { + // var member = parameterMembers.SingleOrDefault(x => ParameterService.GetParameterMemberName(x).EqualsOrdinalIgnoreCase(name)); + // var scalarType = member?.GetMemberType().GetScalarType(); + // var mustDecrypt = (member?.HasCustomAttribute() ?? false) && !BuildServerConfigurationGeneration.IsActive; + // var decryptedValues = values.Select(x => mustDecrypt ? DecryptValue(profile, name, x) : x); + // var convertedValues = decryptedValues.Select(x => ConvertValue(scalarType, x)).ToList(); + // Log.Verbose("Passing value for {Member} ({Value})", + // member?.GetDisplayName() ?? "", + // !mustDecrypt ? convertedValues.JoinComma() : "secret"); + // return new[] { $"--{ParameterService.GetParameterDashedName(name)}" }.Concat(convertedValues); + // } + // + + // + // // TODO: Abstract AbsolutePath/Solution/Project etc. + // string ConvertValue(Type scalarType, string value) + // => scalarType == typeof(AbsolutePath) || + // typeof(Solution).IsAssignableFrom(scalarType) || + // scalarType == typeof(Project) + // ? EnvironmentInfo.WorkingDirectory.GetUnixRelativePathTo(NukeBuild.RootDirectory / value) + // : value; + var parameterMembers = ValueInjectionUtility.GetParameterMembers(Build.GetType(), includeUnlisted: true); - var passwords = new Dictionary(); + var jobjectsAndProfiles = new[] { (File: Constants.GetDefaultParametersFile(NukeBuild.RootDirectory), Profile: Constants.DefaultProfileName) } + .Where(x => File.Exists(x.File)) + .Concat(NukeBuild.LoadedLocalProfiles.Select(x => (File: Constants.GetParametersProfileFile(NukeBuild.RootDirectory, x), Profile: x))) + .ForEachLazy(x => Assert.FileExists(x.File)) + .Select(x => (JObject: JObject.Parse(File.ReadAllText(x.File)), x.Profile)) + .Reverse(); - IEnumerable ConvertToArguments(string profile, string name, string[] values) - { - var member = parameterMembers.SingleOrDefault(x => ParameterService.GetParameterMemberName(x).EqualsOrdinalIgnoreCase(name)); - var scalarType = member?.GetMemberType().GetScalarType(); - var mustDecrypt = (member?.HasCustomAttribute() ?? false) && !BuildServerConfigurationGeneration.IsActive; - var decryptedValues = values.Select(x => mustDecrypt ? DecryptValue(profile, name, x) : x); - var convertedValues = decryptedValues.Select(x => ConvertValue(scalarType, x)).ToList(); - Log.Verbose("Passing value for {Member} ({Value})", - member?.GetDisplayName() ?? "", - !mustDecrypt ? convertedValues.JoinComma() : "secret"); - return new[] { $"--{ParameterService.GetParameterDashedName(name)}" }.Concat(convertedValues); - } + var passwords = new Dictionary(); string DecryptValue(string profile, string name, string value) => EncryptionUtility.Decrypt( @@ -47,45 +65,24 @@ string DecryptValue(string profile, string name, string value) passwords[profile] = passwords.GetValueOrDefault(profile) ?? CredentialStore.GetPassword(profile, Build.RootDirectory), name); - // TODO: Abstract AbsolutePath/Solution/Project etc. - string ConvertValue([CanBeNull] Type scalarType, string value) - => typeof(IAbsolutePathHolder).IsAssignableFrom(scalarType) && - !PathConstruction.HasPathRoot(value) - ? EnvironmentInfo.WorkingDirectory.GetUnixRelativePathTo(Build.RootDirectory / value) - : value; - - var arguments = GetParameters().SelectMany(x => ConvertToArguments(x.Profile, x.Name, x.Values)).ToArray(); - ParameterService.Instance.ArgumentsFromFilesService = new ArgumentParser(arguments); - } + ParameterService.Instance.ArgumentsFromFilesService = (parameter, destinationType) => + { + var (property, profile) = jobjectsAndProfiles.Select(x => (Property: x.JObject.Property(parameter), x.Profile)) + .Where(x => x.Property != null) + .FirstOrDefault(); + if (property == null) + return null; - private IEnumerable<(string Profile, string Name, string[] Values)> GetParameters() - { - IEnumerable GetValues(JProperty property) - // TODO: if property is object || property is array && array contains objects => base64 - => property.Value is JArray array - ? array.Values() - : property.Values(); + var member = parameterMembers.SingleOrDefault(x => ParameterService.GetParameterMemberName(x).EqualsOrdinalIgnoreCase(parameter)); + var scalarType = member?.GetMemberType().GetScalarType(); + if (typeof(IAbsolutePathHolder).IsAssignableFrom(scalarType)) + return property.Value.ToObject().Apply(x => !PathConstruction.HasPathRoot(x) ? NukeBuild.RootDirectory / x : (AbsolutePath)x); - IEnumerable<(string Name, string[] Values)> Load(AbsolutePath file) - { - try - { - var jobject = JObject.Parse(file.ReadAllText()); - // TODO: use NukeBuild instance to match members and walk through structure to replace secrets and absolute-paths - return jobject.Properties() - .Where(x => x.Name != "$schema") - .Select(x => (x.Name, GetValues(x).ToArray())); - } - catch (Exception exception) - { - throw new Exception($"Failed parsing parameters file '{file}'.", exception); - } - } + if ((member?.HasCustomAttribute() ?? false) && + !BuildServerConfigurationGeneration.IsActive) + return DecryptValue(profile, parameter, property.Value.ToObject()); - return new[] { (File: Constants.GetDefaultParametersFile(Build.RootDirectory), Profile: Constants.DefaultProfileName) } - .Where(x => x.File.Exists()) - .Concat(Build.LoadedLocalProfiles.Select(x => (File: Constants.GetParametersProfileFile(Build.RootDirectory, x), Profile: x))) - .ForEachLazy(x => Assert.FileExists(x.File)) - .SelectMany(x => Load(x.File), (x, r) => (x.Profile, r.Name, r.Values)); + return property.Value.ToObject(destinationType); + }; } } diff --git a/source/Nuke.Build/Execution/ParameterService.cs b/source/Nuke.Build/Execution/ParameterService.cs index b62071cc6..66bb1c718 100644 --- a/source/Nuke.Build/Execution/ParameterService.cs +++ b/source/Nuke.Build/Execution/ParameterService.cs @@ -17,7 +17,8 @@ namespace Nuke.Common; internal partial class ParameterService { - internal ArgumentParser ArgumentsFromFilesService; + // internal ArgumentParser ArgumentsFromFilesService; + internal Func ArgumentsFromFilesService; internal ArgumentParser ArgumentsFromCommitMessageService; private readonly Func _argumentParserProvider; @@ -154,7 +155,8 @@ object TryFromEnvironmentVariables() => // TODO: nuke ? object TryFromProfileArguments() => - ArgumentsFromFilesService?.GetNamedArgument(parameterName, destinationType, separator); + // ArgumentsFromFilesService?.GetNamedArgument(parameterName, destinationType, separator); + ArgumentsFromFilesService?.Invoke(parameterName, destinationType); object TryFromCommitMessageArguments() => ArgumentsFromCommitMessageService?.GetNamedArgument(parameterName, destinationType, separator); diff --git a/source/Nuke.Components/ISignPackages.cs b/source/Nuke.Components/ISignPackages.cs index c0d288579..54a17a250 100644 --- a/source/Nuke.Components/ISignPackages.cs +++ b/source/Nuke.Components/ISignPackages.cs @@ -52,16 +52,19 @@ public interface ISignPackages : INukeBuild { public const string SignPath = nameof(SignPath); + public record SignPathSettings( + string OrganizationId, + string ProjectSlug, + string PolicySlug); + + [Parameter] SignPathSettings Settings => TryGetValue(() => Settings); [Parameter] [Secret] string ApiToken => TryGetValue(() => ApiToken); - [Parameter] string OrganizationId => TryGetValue(() => OrganizationId); - [Parameter] string ProjectSlug => TryGetValue(() => ProjectSlug); - [Parameter] string PolicySlug => TryGetValue(() => PolicySlug); AbsolutePath SignPathTemporaryDirectory => TemporaryDirectory / "signpath"; AbsolutePath SignPathRequestDirectory => SignPathTemporaryDirectory / "signing-request"; AbsolutePath SignPathResponseDirectory => SignPathTemporaryDirectory / "signing-response"; - AbsolutePath SignPathRequestArchive => Path.ChangeExtension(SignPathRequestDirectory, ".zip"); - AbsolutePath SignPathResponseArchive => Path.ChangeExtension(SignPathResponseDirectory, ".zip"); + AbsolutePath SignPathRequestArchive => SignPathRequestDirectory.WithExtension(".zip"); + AbsolutePath SignPathResponseArchive => SignPathResponseDirectory.WithExtension(".zip"); IEnumerable SignPathPackages { get; } bool SignPathReplacePackages => true; @@ -72,10 +75,8 @@ public interface ISignPackages : INukeBuild .TryDependsOn() .TryDependentFor() .OnlyWhenStatic(() => AppVeyor != null) + .Requires(() => Settings) .Requires(() => ApiToken) - .Requires(() => OrganizationId) - .Requires(() => ProjectSlug) - .Requires(() => PolicySlug) .Executes(async () => { SignPathRequestDirectory.CreateOrCleanDirectory(); @@ -86,9 +87,9 @@ public interface ISignPackages : INukeBuild var signingRequestUrl = await GetSigningRequestUrlViaAppVeyor( ApiToken, - OrganizationId, - ProjectSlug, - PolicySlug); + Settings.OrganizationId, + Settings.ProjectSlug, + Settings.PolicySlug); ReportSummary(_ => _ .AddPair("Approve/Deny Request", signingRequestUrl.Replace("api/v1", "Web"))); From f44f76568c0d66d92d67d709566e318e5adb563c Mon Sep 17 00:00:00 2001 From: Matthias Koch Date: Thu, 4 Jul 2024 01:03:16 +0200 Subject: [PATCH 38/56] build: use central package management --- Directory.Packages.props | 84 +++++++++++++++++++ build/_build.csproj | 1 + source/Directory.Build.props | 20 ++--- .../Nuke.Build.Shared.csproj | 2 +- source/Nuke.Build/Nuke.Build.csproj | 14 ++-- source/Nuke.Common/Nuke.Common.csproj | 10 +-- source/Nuke.GlobalTool/Nuke.GlobalTool.csproj | 8 +- .../Nuke.MSBuildTasks.csproj | 6 +- .../ProjectModelTest.cs | 7 +- .../Nuke.ProjectModel.csproj | 27 ++---- source/Nuke.ProjectModel/Project.Misc.cs | 5 +- .../Nuke.SourceGenerators.Tests.csproj | 8 +- .../Nuke.SourceGenerators.csproj | 6 +- .../Nuke.Tooling.Generator.csproj | 10 +-- source/Nuke.Tooling/Nuke.Tooling.csproj | 6 +- .../Nuke.Utilities.IO.Compression.csproj | 2 +- .../Nuke.Utilities.IO.Globbing.csproj | 2 +- .../Nuke.Utilities.Net.csproj | 4 +- .../Nuke.Utilities.Text.Json.csproj | 2 +- .../Nuke.Utilities.Text.Yaml.csproj | 2 +- source/Nuke.Utilities/Nuke.Utilities.csproj | 2 +- 21 files changed, 150 insertions(+), 78 deletions(-) create mode 100644 Directory.Packages.props diff --git a/Directory.Packages.props b/Directory.Packages.props new file mode 100644 index 000000000..00c9ff6d0 --- /dev/null +++ b/Directory.Packages.props @@ -0,0 +1,84 @@ + + + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build/_build.csproj b/build/_build.csproj index b62c736dc..8de4e02f5 100644 --- a/build/_build.csproj +++ b/build/_build.csproj @@ -10,6 +10,7 @@ CS0649;CS0169 .\.. 1 + false diff --git a/source/Directory.Build.props b/source/Directory.Build.props index c67af9847..3461e7ae7 100644 --- a/source/Directory.Build.props +++ b/source/Directory.Build.props @@ -36,19 +36,19 @@ - + - - - - - - - - - + + + + + + + + + diff --git a/source/Nuke.Build.Shared/Nuke.Build.Shared.csproj b/source/Nuke.Build.Shared/Nuke.Build.Shared.csproj index 360fe16cb..5925ae70e 100644 --- a/source/Nuke.Build.Shared/Nuke.Build.Shared.csproj +++ b/source/Nuke.Build.Shared/Nuke.Build.Shared.csproj @@ -9,7 +9,7 @@ - + diff --git a/source/Nuke.Build/Nuke.Build.csproj b/source/Nuke.Build/Nuke.Build.csproj index 746e8dee7..94c5801ed 100644 --- a/source/Nuke.Build/Nuke.Build.csproj +++ b/source/Nuke.Build/Nuke.Build.csproj @@ -17,13 +17,13 @@ - - - - - - - + + + + + + + diff --git a/source/Nuke.Common/Nuke.Common.csproj b/source/Nuke.Common/Nuke.Common.csproj index 006c19995..0ab89aea1 100644 --- a/source/Nuke.Common/Nuke.Common.csproj +++ b/source/Nuke.Common/Nuke.Common.csproj @@ -23,11 +23,11 @@ - - - - - + + + + + diff --git a/source/Nuke.GlobalTool/Nuke.GlobalTool.csproj b/source/Nuke.GlobalTool/Nuke.GlobalTool.csproj index 0ecfb735b..a47a42bc8 100644 --- a/source/Nuke.GlobalTool/Nuke.GlobalTool.csproj +++ b/source/Nuke.GlobalTool/Nuke.GlobalTool.csproj @@ -14,10 +14,10 @@ - - - - + + + + diff --git a/source/Nuke.MSBuildTasks/Nuke.MSBuildTasks.csproj b/source/Nuke.MSBuildTasks/Nuke.MSBuildTasks.csproj index 09e9ae94c..e2e4b0b6b 100644 --- a/source/Nuke.MSBuildTasks/Nuke.MSBuildTasks.csproj +++ b/source/Nuke.MSBuildTasks/Nuke.MSBuildTasks.csproj @@ -11,13 +11,13 @@ - + - - + + diff --git a/source/Nuke.ProjectModel.Tests/ProjectModelTest.cs b/source/Nuke.ProjectModel.Tests/ProjectModelTest.cs index f50dbda4a..3d77a8f89 100644 --- a/source/Nuke.ProjectModel.Tests/ProjectModelTest.cs +++ b/source/Nuke.ProjectModel.Tests/ProjectModelTest.cs @@ -29,6 +29,7 @@ public void ProjectTest() project.GetTargetFrameworks().Should().Equal("net6.0", "net7.0", "net8.0"); project.HasPackageReference("Microsoft.Build.Locator").Should().BeTrue(); project.GetPackageReferenceVersion("Microsoft.Build.Locator").Should().Be("1.7.8"); + project.GetPackageReferenceVersion("Microsoft.Build").Should().Be("17.10.4"); } [Fact] @@ -37,10 +38,10 @@ public void MSBuildProjectTest() var solution = SolutionModelTasks.ParseSolution(SolutionFile); var project = solution.Projects.Single(x => x.Name == "Nuke.ProjectModel"); - var msbuildProject = project.GetMSBuildProject(targetFramework: "net6.0"); + var msbuildProject = project.GetMSBuildProject(targetFramework: "net8.0"); - var package = msbuildProject.GetItems("PackageReference").FirstOrDefault(x => x.EvaluatedInclude == "Microsoft.Build"); + var package = msbuildProject.GetItems("PackageVersion").FirstOrDefault(x => x.EvaluatedInclude == "Microsoft.Build"); package.Should().NotBeNull(); - package.GetMetadataValue("Version").Should().Be("16.9.0"); + package.GetMetadataValue("Version").Should().Be("17.10.4"); } } diff --git a/source/Nuke.ProjectModel/Nuke.ProjectModel.csproj b/source/Nuke.ProjectModel/Nuke.ProjectModel.csproj index d3875675f..0d21f36d4 100644 --- a/source/Nuke.ProjectModel/Nuke.ProjectModel.csproj +++ b/source/Nuke.ProjectModel/Nuke.ProjectModel.csproj @@ -11,28 +11,11 @@ - - - - - - - - - - - - - - - - - - - - - - + + + + + diff --git a/source/Nuke.ProjectModel/Project.Misc.cs b/source/Nuke.ProjectModel/Project.Misc.cs index 0d15be4f4..f402fc7fe 100644 --- a/source/Nuke.ProjectModel/Project.Misc.cs +++ b/source/Nuke.ProjectModel/Project.Misc.cs @@ -58,7 +58,10 @@ public static bool HasPackageReference(this Project project, string packageId) /// public static string GetPackageReferenceVersion(this Project project, string packageId) { - return project.GetItemMetadataSingleOrDefault("PackageReference", packageId, "Version"); + var version = project.GetItemMetadataSingleOrDefault("PackageReference", packageId, "Version"); + return version == string.Empty + ? project.GetItemMetadataSingleOrDefault("PackageVersion", packageId, "Version") + : null; } [CanBeNull] diff --git a/source/Nuke.SourceGenerators.Tests/Nuke.SourceGenerators.Tests.csproj b/source/Nuke.SourceGenerators.Tests/Nuke.SourceGenerators.Tests.csproj index 906167b4e..65a4b6cb0 100644 --- a/source/Nuke.SourceGenerators.Tests/Nuke.SourceGenerators.Tests.csproj +++ b/source/Nuke.SourceGenerators.Tests/Nuke.SourceGenerators.Tests.csproj @@ -12,10 +12,10 @@ - - - - + + + + diff --git a/source/Nuke.SourceGenerators/Nuke.SourceGenerators.csproj b/source/Nuke.SourceGenerators/Nuke.SourceGenerators.csproj index 381f687d7..3d4e219a5 100644 --- a/source/Nuke.SourceGenerators/Nuke.SourceGenerators.csproj +++ b/source/Nuke.SourceGenerators/Nuke.SourceGenerators.csproj @@ -19,9 +19,9 @@ - - - + + + diff --git a/source/Nuke.Tooling.Generator/Nuke.Tooling.Generator.csproj b/source/Nuke.Tooling.Generator/Nuke.Tooling.Generator.csproj index 713acf1db..089faf871 100644 --- a/source/Nuke.Tooling.Generator/Nuke.Tooling.Generator.csproj +++ b/source/Nuke.Tooling.Generator/Nuke.Tooling.Generator.csproj @@ -6,11 +6,11 @@ - - - - - + + + + + diff --git a/source/Nuke.Tooling/Nuke.Tooling.csproj b/source/Nuke.Tooling/Nuke.Tooling.csproj index 002f32571..e6e3083d2 100644 --- a/source/Nuke.Tooling/Nuke.Tooling.csproj +++ b/source/Nuke.Tooling/Nuke.Tooling.csproj @@ -9,9 +9,9 @@ - - - + + + diff --git a/source/Nuke.Utilities.IO.Compression/Nuke.Utilities.IO.Compression.csproj b/source/Nuke.Utilities.IO.Compression/Nuke.Utilities.IO.Compression.csproj index 7cb2fc6a5..7fe82a8c6 100644 --- a/source/Nuke.Utilities.IO.Compression/Nuke.Utilities.IO.Compression.csproj +++ b/source/Nuke.Utilities.IO.Compression/Nuke.Utilities.IO.Compression.csproj @@ -9,7 +9,7 @@ - + diff --git a/source/Nuke.Utilities.IO.Globbing/Nuke.Utilities.IO.Globbing.csproj b/source/Nuke.Utilities.IO.Globbing/Nuke.Utilities.IO.Globbing.csproj index 26639f272..a43acbc68 100644 --- a/source/Nuke.Utilities.IO.Globbing/Nuke.Utilities.IO.Globbing.csproj +++ b/source/Nuke.Utilities.IO.Globbing/Nuke.Utilities.IO.Globbing.csproj @@ -9,7 +9,7 @@ - + diff --git a/source/Nuke.Utilities.Net/Nuke.Utilities.Net.csproj b/source/Nuke.Utilities.Net/Nuke.Utilities.Net.csproj index 39d63aba3..6f3aeb095 100644 --- a/source/Nuke.Utilities.Net/Nuke.Utilities.Net.csproj +++ b/source/Nuke.Utilities.Net/Nuke.Utilities.Net.csproj @@ -9,8 +9,8 @@ - - + + diff --git a/source/Nuke.Utilities.Text.Json/Nuke.Utilities.Text.Json.csproj b/source/Nuke.Utilities.Text.Json/Nuke.Utilities.Text.Json.csproj index c13a6dd63..938d355f1 100644 --- a/source/Nuke.Utilities.Text.Json/Nuke.Utilities.Text.Json.csproj +++ b/source/Nuke.Utilities.Text.Json/Nuke.Utilities.Text.Json.csproj @@ -9,7 +9,7 @@ - + diff --git a/source/Nuke.Utilities.Text.Yaml/Nuke.Utilities.Text.Yaml.csproj b/source/Nuke.Utilities.Text.Yaml/Nuke.Utilities.Text.Yaml.csproj index 1cd42cb3d..aefd1f0b9 100644 --- a/source/Nuke.Utilities.Text.Yaml/Nuke.Utilities.Text.Yaml.csproj +++ b/source/Nuke.Utilities.Text.Yaml/Nuke.Utilities.Text.Yaml.csproj @@ -9,7 +9,7 @@ - + diff --git a/source/Nuke.Utilities/Nuke.Utilities.csproj b/source/Nuke.Utilities/Nuke.Utilities.csproj index 1b9bf611e..c4ed59fc1 100644 --- a/source/Nuke.Utilities/Nuke.Utilities.csproj +++ b/source/Nuke.Utilities/Nuke.Utilities.csproj @@ -5,7 +5,7 @@ - + From 6aacfd847b6fa0768e0d5aa4345525a49497414d Mon Sep 17 00:00:00 2001 From: Matthias Koch Date: Thu, 4 Jul 2024 07:32:09 +0200 Subject: [PATCH 39/56] docs: fix minver package --- docs/03-common/06-versioning.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/03-common/06-versioning.md b/docs/03-common/06-versioning.md index 2a581b63d..f726d0079 100644 --- a/docs/03-common/06-versioning.md +++ b/docs/03-common/06-versioning.md @@ -86,7 +86,7 @@ Please refer to the [MinVer documentation](https://github.com/adamralph/minver#u ```powershell title="Tool Installation" # terminal-command -nuke :add-package MinVer +nuke :add-package minver-cli ``` ```csharp title="Build.cs" From 941c59d2ba8df44c1fafb3a51f4cf1bf6eb88376 Mon Sep 17 00:00:00 2001 From: Matthias Koch Date: Tue, 9 Jul 2024 02:44:43 +0200 Subject: [PATCH 40/56] fix(setup): simplify schema reference --- .nuke/parameters.json | 2 +- source/Nuke.GlobalTool/Program.Setup.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.nuke/parameters.json b/.nuke/parameters.json index 0ca1a709e..589f2e3fb 100644 --- a/.nuke/parameters.json +++ b/.nuke/parameters.json @@ -1,5 +1,5 @@ { - "$schema": "./build.schema.json", + "$schema": "build.schema.json", "Solution": "nuke-common.sln", "SignPathSettings": { "OrganizationId": "0fdaf334-6910-41f4-83d2-e58e4cccb087", diff --git a/source/Nuke.GlobalTool/Program.Setup.cs b/source/Nuke.GlobalTool/Program.Setup.cs index 4804be675..9700f1a37 100644 --- a/source/Nuke.GlobalTool/Program.Setup.cs +++ b/source/Nuke.GlobalTool/Program.Setup.cs @@ -245,7 +245,7 @@ void MakeExecutable(AbsolutePath scriptFile) private static void WriteConfigurationFile(AbsolutePath rootDirectory, [CanBeNull] AbsolutePath solutionFile) { var parametersFile = GetDefaultParametersFile(rootDirectory); - var dictionary = new Dictionary { ["$schema"] = $"./{BuildSchemaFileName}" }; + var dictionary = new Dictionary { ["$schema"] = BuildSchemaFileName }; if (solutionFile != null) dictionary["Solution"] = rootDirectory.GetUnixRelativePathTo(solutionFile).ToString(); parametersFile.WriteJson(dictionary); From d49d0840a09ffcc06548ad07a48dc4b11f4802f7 Mon Sep 17 00:00:00 2001 From: y-karnitskaya Date: Tue, 9 Jul 2024 02:49:59 +0200 Subject: [PATCH 41/56] feat(solution): allow preprocessor directives (#1392) --- source/Nuke.SolutionModel/SolutionSerializer.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/source/Nuke.SolutionModel/SolutionSerializer.cs b/source/Nuke.SolutionModel/SolutionSerializer.cs index 88080787d..d191a4784 100644 --- a/source/Nuke.SolutionModel/SolutionSerializer.cs +++ b/source/Nuke.SolutionModel/SolutionSerializer.cs @@ -88,6 +88,7 @@ private static Dictionary GetGlobalSection(this string[] lines, .SkipWhile(x => !Regex.IsMatch(x, $@"^\s*GlobalSection\({name}\) = \w+$")) .Skip(count: 1) .TakeWhile(x => !Regex.IsMatch(x, @"^\s*EndGlobalSection$")) + .Where(x => !x.StartsWith("#")) .ToList(); return sectionLines.Count == 0 From eca315b22a1705a9daae812aabfefab389c0fbb9 Mon Sep 17 00:00:00 2001 From: Taylor Buchanan Date: Mon, 8 Jul 2024 19:55:07 -0500 Subject: [PATCH 42/56] fix(tools): tool path for CodecovTasks (#1357) --- source/Nuke.Common/Tools/Codecov/Codecov.json | 2 +- .../Nuke.Common/Tools/Codecov/CodecovTasks.cs | 21 ++++++++++++++----- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/source/Nuke.Common/Tools/Codecov/Codecov.json b/source/Nuke.Common/Tools/Codecov/Codecov.json index 08b9b6cb0..2f70d769d 100644 --- a/source/Nuke.Common/Tools/Codecov/Codecov.json +++ b/source/Nuke.Common/Tools/Codecov/Codecov.json @@ -6,7 +6,7 @@ "name": "Codecov", "officialUrl": "https://about.codecov.io/", "help": "Code coverage is a measurement used to express which lines of code were executed by a test suite. We use three primary terms to describe each line executed.
  • hit - indicates that the source code was executed by the test suite.
  • partial - indicates that the source code was not fully executed by the test suite; there are remaining branches that were not executed.
  • miss - indicates that the source code was not executed by the test suite.
Coverage is the ratio of hits / (sum of hit + partial + miss). A code base that has 5 lines executed by tests out of 12 total lines will receive a coverage ratio of 41% (rounding down).Phrased simply, code coverage provides a visual measurement of what source code is being executed by a test suite. This information indicates to the software developer where they should write new tests in an effort to achieve higher coverage.Testing source code helps to prevent bugs and syntax errors by executing each line with a known variable and cross-checking it with an expected output.", - "nugetPackageId": "Codecov.Tool", + "nugetPackageId": "CodecovUploader", "customExecutable": true, "tasks": [ { diff --git a/source/Nuke.Common/Tools/Codecov/CodecovTasks.cs b/source/Nuke.Common/Tools/Codecov/CodecovTasks.cs index b63f68263..1ca823c87 100644 --- a/source/Nuke.Common/Tools/Codecov/CodecovTasks.cs +++ b/source/Nuke.Common/Tools/Codecov/CodecovTasks.cs @@ -2,6 +2,7 @@ // Distributed under the MIT License. // https://github.com/nuke-build/nuke/blob/master/LICENSE +using System; using Nuke.Common.Tooling; namespace Nuke.Common.Tools.Codecov; @@ -10,17 +11,27 @@ partial class CodecovSettings { private string GetProcessToolPath() { - return CodecovTasks.GetToolPath(Framework); + return CodecovTasks.GetToolPath(); } } partial class CodecovTasks { - internal static string GetToolPath(string framework = null) + internal static string GetToolPath() { return NuGetToolPathResolver.GetPackageExecutable( - packageId: "Codecov.Tool", - packageExecutable: "codecov.dll", - framework: framework); + packageId: "CodecovUploader", + packageExecutable: GetPackageExecutable()); + } + + private static string GetPackageExecutable() + { + return EnvironmentInfo.Platform switch + { + PlatformFamily.Windows => "codecov.exe", + PlatformFamily.OSX => "codecov-macos", + PlatformFamily.Linux => "codecov-linux", + _ => throw new ArgumentOutOfRangeException() + }; } } From 69c6a9d7b93ace6d56a156f02d2aeb459e769f5c Mon Sep 17 00:00:00 2001 From: ITaluone <44049228+ITaluone@users.noreply.github.com> Date: Tue, 9 Jul 2024 02:59:55 +0200 Subject: [PATCH 43/56] fix(tools): add missing arguments in DotNetTasks (#1354) --- source/Nuke.Common/Tools/DotNet/DotNet.json | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/source/Nuke.Common/Tools/DotNet/DotNet.json b/source/Nuke.Common/Tools/DotNet/DotNet.json index e59216b7c..6b94c37d6 100644 --- a/source/Nuke.Common/Tools/DotNet/DotNet.json +++ b/source/Nuke.Common/Tools/DotNet/DotNet.json @@ -690,6 +690,12 @@ "format": "{value}", "help": "The project to publish, which defaults to the current directory if not specified." }, + { + "name": "Architecture", + "type": "string", + "format": "--arch {value}", + "help": "Specifies the target architecture. This is a shorthand syntax for setting the Runtime Identifier (RID), where the provided value is combined with the default RID. For example, on a win-x64 machine, specifying --arch x86 sets the RID to win-x86. If you use this option, don't use the -r|--runtime option. Available since .NET 6 Preview 7." + }, { "name": "Configuration", "type": "string", @@ -726,6 +732,12 @@ "format": "--output {value}", "help": "Specifies the path for the output directory. If not specified, it defaults to ./bin/[configuration]/[framework]/ for a framework-dependent deployment or ./bin/[configuration]/[framework]/[runtime] for a self-contained deployment.If a relative path is provided, the output directory generated is relative to the project file location, not to the current working directory." }, + { + "name": "OperatingSystem", + "type": "string", + "format": "--os {value}", + "help": "Specifies the target operating system (OS). This is a shorthand syntax for setting the Runtime Identifier (RID), where the provided value is combined with the default RID. For example, on a win-x64 machine, specifying --os linux sets the RID to linux-x64. If you use this option, don't use the -r|--runtime option. Available since .NET 6." + }, { "name": "SelfContained", "type": "bool", @@ -755,6 +767,13 @@ "type": "bool", "format": "--nologo", "help": "Doesn't display the startup banner or the copyright message. Available since .NET Core 3.0 SDK." + }, + { + "name": "Targets", + "type": "List", + "format": "/t:{value}", + "separator": ";", + "help": "

Build the specified targets in the project. Specify each target separately, or use a semicolon or comma to separate multiple targets, as the following example shows:
/target:Resources;Compile

If you specify any targets by using this switch, they are run instead of any targets in the DefaultTargets attribute in the project file. For more information, see Target Build Order and How to: Specify Which Target to Build First.

A target is a group of tasks. For more information, see Targets.

" } ] } From 3ea0bb510129234a70b7f2227414bf06401f6f9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Manuel=20Nieto?= Date: Tue, 9 Jul 2024 03:06:06 +0200 Subject: [PATCH 44/56] feat(tools): add DotnetPackagingTasks (#1372) --- .../DotnetPackaging/DotnetPackaging.json | 264 ++++++++++++++++++ 1 file changed, 264 insertions(+) create mode 100644 source/Nuke.Common/Tools/DotnetPackaging/DotnetPackaging.json diff --git a/source/Nuke.Common/Tools/DotnetPackaging/DotnetPackaging.json b/source/Nuke.Common/Tools/DotnetPackaging/DotnetPackaging.json new file mode 100644 index 000000000..6bcad28ce --- /dev/null +++ b/source/Nuke.Common/Tools/DotnetPackaging/DotnetPackaging.json @@ -0,0 +1,264 @@ +{ + "$schema": "https://raw.githubusercontent.com/nuke-build/nuke/master/source/Nuke.Tooling.Generator/schema.json", + "references": [ + "https://github.com/SuperJMN/DotnetPackaging/tree/master/src/DotnetPackaging.Console" + ], + "name": "DotnetPackaging", + "officialUrl": "https://github.com/superjmn/dotnetpackaging", + "help": "DotnetPackaging is able to package your application into various formats, including Deb and AppImage.", + "nugetPackageId": "DotnetPackaging.Console", + "packageExecutable": "DotnetPackaging.Console.dll", + "tasks": [ + { + "help": "Creates a Debian package from the specified directory.", + "postfix": "Deb", + "definiteArgument": "deb", + "settingsClass": { + "properties": [ + { + "name": "Directory", + "type": "string", + "format": "--directory={value}", + "help": "The input directory from which to create the package." + }, + { + "name": "Metadata", + "type": "string", + "format": "--metadata={value}", + "help": "The metadata file to include in the package." + }, + { + "name": "Output", + "type": "string", + "format": "--output={value}", + "help": "The output DEB file to create." + } + ] + } + }, + { + "help": "Creates an AppImage package.", + "postfix": "AppImage", + "definiteArgument": "appimage", + "settingsClass": { + "properties": [ + { + "name": "Directory", + "type": "string", + "format": "--directory={value}", + "help": "The input directory from which to create the AppImage." + }, + { + "name": "Output", + "type": "string", + "format": "--output={value}", + "help": "The output AppImage file to create." + }, + { + "name": "ApplicationName", + "type": "string", + "format": "--application-name={value}", + "help": "The name of the application for the AppImage." + }, + { + "name": "MainCategory", + "type": "DotnetPackagingMainCategory", + "format": "--main-category {value}", + "help": "Main category of the application." + }, + { + "name": "AdditionalCategories", + "type": "List", + "format": "--additional-categories {value}", + "help": "Additional categories for the application." + }, + { + "name": "Icon", + "type": "string", + "format": "--icon {value}", + "help": "The icon path for the application. When not provided, the tool looks up for an image called AppImage.png." + }, + { + "name": "Homepage", + "type": "string", + "format": "--homepage {value}", + "help": "Home page of the application." + }, + { + "name": "License", + "type": "string", + "format": "--license {value}", + "help": "License of the application." + }, + { + "name": "Version", + "type": "string", + "format": "--version {value}", + "help": "Version of the application." + }, + { + "name": "ScreenshotUrls", + "type": "List", + "format": "--screenshot-urls {value}", + "help": "URLs of screenshots of the application." + }, + { + "name": "Summary", + "type": "string", + "format": "--summary {value}", + "help": "Short description of the application." + }, + { + "name": "AppId", + "type": "string", + "format": "--appId {value}", + "help": "Application ID, usually a reverse DNS name like com.SomeCompany.SomeApplication." + } + ] + } + } + ], + "enumerations": [ + { + "name": "DotnetPackagingMainCategory", + "values": [ + "AudioVideo", + "Audio", + "Video", + "Development", + "Education", + "Game", + "Graphics", + "Network", + "Office", + "Settings", + "Utility" + ] + }, + { + "name": "DotnetPackagingAdditionalCategory", + "values": [ + "Building", + "Debugger", + "IDE", + "GUIDesigner", + "Profiling", + "RevisionControl", + "Translation", + "Calendar", + "ContactManagement", + "Database", + "Dictionary", + "Chart", + "Email", + "Finance", + "FlowChart", + "PDA", + "ProjectManagement", + "Presentation", + "Spreadsheet", + "WordProcessor", + "TwoDGraphics", + "VectorGraphics", + "RasterGraphics", + "ThreeDGraphics", + "Scanning", + "OCR", + "Photography", + "Publishing", + "Viewer", + "TextTools", + "DesktopSettings", + "HardwareSettings", + "Printing", + "PackageManager", + "Dialup", + "InstantMessaging", + "Chat", + "IRCClient", + "FileTransfer", + "HamRadio", + "News", + "P2P", + "RemoteAccess", + "Telephony", + "TelephonyTools", + "VideoConference", + "WebBrowser", + "WebDevelopment", + "Midi", + "Mixer", + "Sequencer", + "Tuner", + "TV", + "AudioVideoEditing", + "Player", + "Recorder", + "DiscBurning", + "ActionGame", + "AdventureGame", + "ArcadeGame", + "BoardGame", + "BlocksGame", + "CardGame", + "KidsGame", + "LogicGame", + "RolePlaying", + "Simulation", + "SportsGame", + "StrategyGame", + "Art", + "Construction", + "Music", + "Languages", + "Science", + "ArtificialIntelligence", + "Astronomy", + "Biology", + "Chemistry", + "ComputerScience", + "DataVisualization", + "Economy", + "Electricity", + "Geography", + "Geology", + "Geoscience", + "History", + "ImageProcessing", + "Literature", + "Math", + "NumericalAnalysis", + "MedicalSoftware", + "Physics", + "Robotics", + "Sports", + "ParallelComputing", + "Amusement", + "Archiving", + "Compression", + "Electronics", + "Emulator", + "Engineering", + "FileTools", + "FileManager", + "TerminalEmulator", + "Filesystem", + "Monitor", + "Security", + "Accessibility", + "Calculator", + "Clock", + "TextEditor", + "Documentation", + "Core", + "KDE", + "GNOME", + "GTK", + "Qt", + "Motif", + "Java", + "ConsoleOnly" + ] + } + ] +} From e4e415e9c52fd06db8da3ee6756ef2c055b32310 Mon Sep 17 00:00:00 2001 From: ebugusey Date: Fri, 12 Jul 2024 02:06:30 +0400 Subject: [PATCH 45/56] fix(tooling): use logger from settings in parallel execution (#1263) --- source/Nuke.Tooling/Configure.cs | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/source/Nuke.Tooling/Configure.cs b/source/Nuke.Tooling/Configure.cs index 52fc3d1f5..f3b92c135 100644 --- a/source/Nuke.Tooling/Configure.cs +++ b/source/Nuke.Tooling/Configure.cs @@ -106,10 +106,17 @@ private static IReadOnlyCollection Invoke( invocations .Where(x => x.Settings.ProcessLogOutput ?? ProcessTasks.DefaultLogOutput) .SelectMany(x => - x.Exception is not ProcessException processException - ? outputSelector(x.Result) - : processException.Process.Output) - .ForEach(x => logger(x.Type, x.Text)); + { + var (settings, result, exception) = x; + var output = exception switch + { + ProcessException processException => processException.Process.Output, + _ => outputSelector(result), + }; + + return output.Select(x => (Logger: logger ?? settings.ProcessLogger, Line: x)); + }) + .ForEach(x => x.Logger(x.Line.Type, x.Line.Text)); } } } From e638e6ac9556a678da237eb909b38c22d155abee Mon Sep 17 00:00:00 2001 From: Matthias Koch Date: Fri, 12 Jul 2024 00:57:30 +0200 Subject: [PATCH 46/56] fix(tooling): duplicate NuGet package file --- source/Nuke.Tooling/NuGetPackageResolver.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/source/Nuke.Tooling/NuGetPackageResolver.cs b/source/Nuke.Tooling/NuGetPackageResolver.cs index 48bd7aed7..9e40b42e3 100644 --- a/source/Nuke.Tooling/NuGetPackageResolver.cs +++ b/source/Nuke.Tooling/NuGetPackageResolver.cs @@ -211,6 +211,7 @@ public static InstalledPackage GetGlobalInstalledPackage( // packages can contain false positives due to present/missing version specification .Where(x => x.Id.EqualsOrdinalIgnoreCase(packageId)) .Where(x => !x.Version.IsPrerelease || !includePrereleases.HasValue || includePrereleases.Value) + .Distinct(x => x.Directory) .OrderByDescending(x => x.Version) .ToList(); From 62a5f22808f08b5b68abef052d338f0e83f3b410 Mon Sep 17 00:00:00 2001 From: Matthias Koch Date: Sun, 14 Jul 2024 19:46:20 +0200 Subject: [PATCH 47/56] fix(execution): include original nuget packages in requirements --- .../Execution/ToolRequirementService.cs | 23 ++++++++++--------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/source/Nuke.Build/Execution/ToolRequirementService.cs b/source/Nuke.Build/Execution/ToolRequirementService.cs index b371b5dc7..7213bfa8a 100644 --- a/source/Nuke.Build/Execution/ToolRequirementService.cs +++ b/source/Nuke.Build/Execution/ToolRequirementService.cs @@ -19,19 +19,18 @@ public static void EnsureToolRequirements(INukeBuild build, IReadOnlyCollection< { var requirements = build.GetType().GetCustomAttributes().Select(x => x.GetRequirement()) .Concat(executionPlan.SelectMany(x => x.ToolRequirements)).ToList(); - var directory = build.TemporaryDirectory; - InstallNuGetPackages(requirements.OfType().ToList(), directory); - InstallNpmPackages(requirements.OfType().ToList(), directory); - InstallAptGetPackages(requirements.OfType().ToList(), directory); + InstallNuGetPackages(requirements.OfType().ToList(), build); + InstallNpmPackages(requirements.OfType().ToList(), build); + InstallAptGetPackages(requirements.OfType().ToList(), build); } - private static void InstallNuGetPackages(IReadOnlyCollection requirements, AbsolutePath directory) + private static void InstallNuGetPackages(IReadOnlyCollection requirements, INukeBuild build) { if (requirements.Count == 0) return; - var projectFile = directory / "nuget.csproj"; + var projectFile = build.TemporaryDirectory / "nuget.csproj"; NuGetToolPathResolver.NuGetPackagesConfigFile = projectFile; NuGetToolPathResolver.NuGetAssetsConfigFile = projectFile.Parent / "obj" / "project.assets.json"; @@ -45,8 +44,10 @@ private static void InstallNuGetPackages(IReadOnlyCollectionnet8.0 + + - {groupedPackages.Select(x => $""" """).JoinNewLine()} + {groupedPackages.Select(x => $""" """).JoinNewLine()} @@ -63,12 +64,12 @@ private static void InstallNuGetPackages(IReadOnlyCollection requirements, AbsolutePath directory) + private static void InstallNpmPackages(IReadOnlyCollection requirements, INukeBuild build) { if (requirements.Count == 0) return; - var packageJsonFile = directory / "package.json"; + var packageJsonFile = build.TemporaryDirectory / "package.json"; NpmToolPathResolver.NpmPackageJsonFile = packageJsonFile; var packages = requirements.OrderBy(x => x.PackageId).ToList(); @@ -92,7 +93,7 @@ private static void InstallNpmPackages(IReadOnlyCollection requirements, AbsolutePath directory) + private static void InstallAptGetPackages(IReadOnlyCollection requirements, INukeBuild build) { if (requirements.Count == 0) return; @@ -100,7 +101,7 @@ private static void InstallAptGetPackages(IReadOnlyCollection x.PackageId).ToList(); Assert.True(EnvironmentInfo.IsLinux, "AptGet is only available on Linux"); - var installScript = directory / "apt-get.sh"; + var installScript = build.TemporaryDirectory / "apt-get.sh"; var content = $""" apt-get update From 8583a04e9b4d15693fe73439ee25945424311342 Mon Sep 17 00:00:00 2001 From: Luiz Henrique Cassettari Date: Sun, 14 Jul 2024 14:55:08 -0300 Subject: [PATCH 48/56] fix(tooling): use AppContext to set EnableUnsafeBinaryFormatterSerialization (#1349) --- source/Directory.Build.props | 1 - source/Nuke.Common/Nuke.Common.props | 1 - source/Nuke.Tooling.Tests/NewInstanceTest.cs | 31 +++++++++++++++++++ .../Nuke.Tooling.Tests.csproj | 4 +-- .../SettingsEntity.NewInstance.cs | 13 +++++--- 5 files changed, 41 insertions(+), 9 deletions(-) create mode 100644 source/Nuke.Tooling.Tests/NewInstanceTest.cs diff --git a/source/Directory.Build.props b/source/Directory.Build.props index 3461e7ae7..83b3d91a7 100644 --- a/source/Directory.Build.props +++ b/source/Directory.Build.props @@ -8,7 +8,6 @@ embedded true true - true diff --git a/source/Nuke.Common/Nuke.Common.props b/source/Nuke.Common/Nuke.Common.props index 9827b4735..744f4e105 100644 --- a/source/Nuke.Common/Nuke.Common.props +++ b/source/Nuke.Common/Nuke.Common.props @@ -5,7 +5,6 @@ false $(MSBuildWarningsAsErrors);CS8785 $(NoWarn);SYSLIB0050;SYSLIB0051 - true diff --git a/source/Nuke.Tooling.Tests/NewInstanceTest.cs b/source/Nuke.Tooling.Tests/NewInstanceTest.cs new file mode 100644 index 000000000..def17bec9 --- /dev/null +++ b/source/Nuke.Tooling.Tests/NewInstanceTest.cs @@ -0,0 +1,31 @@ +// Copyright 2023 Maintainers of NUKE. +// Distributed under the MIT License. +// https://github.com/nuke-build/nuke/blob/master/LICENSE + +using FluentAssertions; +using Nuke.Common.Tooling; +using System; +using Xunit; + +namespace Nuke.Common.Tests; + +public class NewInstanceTest +{ + [Serializable] + public class SimpleEntity : ISettingsEntity + { + public int Integer { get; set; } + public string String { get; set; } + } + + [Fact] + public void TestSimpleEntity() + { + var entity = new SimpleEntity { Integer = 1, String = "test" }; + var newInstance = entity.NewInstance(); + + newInstance.Integer.Should().Be(entity.Integer); + newInstance.String.Should().Be(entity.String); + } + +} diff --git a/source/Nuke.Tooling.Tests/Nuke.Tooling.Tests.csproj b/source/Nuke.Tooling.Tests/Nuke.Tooling.Tests.csproj index d2222e881..2267c07f2 100644 --- a/source/Nuke.Tooling.Tests/Nuke.Tooling.Tests.csproj +++ b/source/Nuke.Tooling.Tests/Nuke.Tooling.Tests.csproj @@ -1,7 +1,7 @@ - + - net6.0 + net8.0 diff --git a/source/Nuke.Tooling/SettingsEntity.NewInstance.cs b/source/Nuke.Tooling/SettingsEntity.NewInstance.cs index 9b129fea6..54c7e05d5 100644 --- a/source/Nuke.Tooling/SettingsEntity.NewInstance.cs +++ b/source/Nuke.Tooling/SettingsEntity.NewInstance.cs @@ -1,4 +1,4 @@ -// Copyright 2023 Maintainers of NUKE. +// Copyright 2024 Maintainers of NUKE. // Distributed under the MIT License. // https://github.com/nuke-build/nuke/blob/master/LICENSE @@ -7,6 +7,7 @@ using System.Linq; using System.Runtime.Serialization.Formatters.Binary; using JetBrains.Annotations; + #pragma warning disable SYSLIB0011 namespace Nuke.Common.Tooling; @@ -17,18 +18,20 @@ public static partial class SettingsEntityExtensions public static T NewInstance(this T settingsEntity) where T : ISettingsEntity { + AppContext.SetSwitch("System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization", isEnabled: true); + var binaryFormatter = new BinaryFormatter(); using var memoryStream = new MemoryStream(); binaryFormatter.Serialize(memoryStream, settingsEntity); memoryStream.Seek(offset: 0, loc: SeekOrigin.Begin); - var newInstance = (T) binaryFormatter.Deserialize(memoryStream); + var newInstance = (T)binaryFormatter.Deserialize(memoryStream); if (newInstance is ToolSettings toolSettings) { - toolSettings.ProcessArgumentConfigurator = ((ToolSettings) (object) settingsEntity).ProcessArgumentConfigurator; - toolSettings.ProcessLogger = ((ToolSettings) (object) settingsEntity).ProcessLogger; - toolSettings.ProcessExitHandler = ((ToolSettings) (object) settingsEntity).ProcessExitHandler; + toolSettings.ProcessArgumentConfigurator = ((ToolSettings)(object)settingsEntity).ProcessArgumentConfigurator; + toolSettings.ProcessLogger = ((ToolSettings)(object)settingsEntity).ProcessLogger; + toolSettings.ProcessExitHandler = ((ToolSettings)(object)settingsEntity).ProcessExitHandler; } return newInstance; From 6ed9e4d9c7476444eb6b984591d1364b47723144 Mon Sep 17 00:00:00 2001 From: Matthias Koch Date: Sun, 14 Jul 2024 20:24:05 +0200 Subject: [PATCH 49/56] build: update System.Text.Json dependency --- Directory.Packages.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index 00c9ff6d0..aca4fe257 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -29,7 +29,7 @@ - + From e6df653d54eeccb634191851223420b5f2889896 Mon Sep 17 00:00:00 2001 From: Matthias Koch Date: Tue, 10 Sep 2024 00:40:07 +0200 Subject: [PATCH 50/56] fix(execution): strip hyphens from skipped target names (#1413) --- source/Nuke.Build/Execution/BuildExecutor.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/source/Nuke.Build/Execution/BuildExecutor.cs b/source/Nuke.Build/Execution/BuildExecutor.cs index 5d6b50e44..638c2cf0a 100644 --- a/source/Nuke.Build/Execution/BuildExecutor.cs +++ b/source/Nuke.Build/Execution/BuildExecutor.cs @@ -27,6 +27,7 @@ public static void Execute(NukeBuild build, [CanBeNull] IReadOnlyCollection x.Replace("-", string.Empty)).ToArray(); build.ExecutionPlan .Where(x => skippedTargets.Count == 0 || skippedTargets.Contains(x.Name, StringComparer.OrdinalIgnoreCase)) .ForEach(x => MarkTargetSkipped(build, x, reason: "via parameter")); From 71ee501afa8aa6eeef5d5d46687776a9743c0003 Mon Sep 17 00:00:00 2001 From: Matthias Koch Date: Tue, 10 Sep 2024 00:41:34 +0200 Subject: [PATCH 51/56] fix(execution): don't exclude invoked targets from skipping (#1414) --- source/Nuke.Build.Tests/BuildExecutorTest.cs | 11 +---------- source/Nuke.Build/Execution/BuildExecutor.cs | 2 +- 2 files changed, 2 insertions(+), 11 deletions(-) diff --git a/source/Nuke.Build.Tests/BuildExecutorTest.cs b/source/Nuke.Build.Tests/BuildExecutorTest.cs index 62f4fcf08..15f8f67fa 100644 --- a/source/Nuke.Build.Tests/BuildExecutorTest.cs +++ b/source/Nuke.Build.Tests/BuildExecutorTest.cs @@ -36,21 +36,12 @@ public void TestDefault() } [Fact] - public void TestParameterSkipped_AllWithoutInvoked() + public void TestParameterSkipped_All() { ExecuteBuild(skippedTargets: new ExecutableTarget[0]); AssertSkipped(A, B, C); } - [Fact] - public void TestParameterSkipped_AllWithInvoked() - { - C.Invoked = true; - ExecuteBuild(skippedTargets: new ExecutableTarget[0]); - AssertSucceeded(C); - AssertSkipped(A, B); - } - [Fact] public void TestParameterSkipped_Single() { diff --git a/source/Nuke.Build/Execution/BuildExecutor.cs b/source/Nuke.Build/Execution/BuildExecutor.cs index 638c2cf0a..085a7ece6 100644 --- a/source/Nuke.Build/Execution/BuildExecutor.cs +++ b/source/Nuke.Build/Execution/BuildExecutor.cs @@ -181,7 +181,7 @@ string Format(string condition) private static void MarkTargetSkipped(INukeBuild build, ExecutableTarget target, string reason = null) { - if (target.Invoked || target.Status != ExecutionStatus.Scheduled) + if (target.Status != ExecutionStatus.Scheduled) return; target.Status = ExecutionStatus.Skipped; From dbae75dea479a1754b4ded9f9e1cdd2e80a82a71 Mon Sep 17 00:00:00 2001 From: Matthias Koch Date: Tue, 10 Sep 2024 00:42:29 +0200 Subject: [PATCH 52/56] fix(execution): resolve empty environment variables as empty arrays (#1400) --- .../Nuke.Build.Tests/ParameterServiceTest.cs | 9 +++++++-- .../Nuke.Build/Execution/ParameterService.cs | 19 ++----------------- .../Reflection/ReflectionUtilityTest.cs | 9 ++++++--- .../ReflectionUtility.Conversion.cs | 4 +++- 4 files changed, 18 insertions(+), 23 deletions(-) diff --git a/source/Nuke.Build.Tests/ParameterServiceTest.cs b/source/Nuke.Build.Tests/ParameterServiceTest.cs index 5ca5c5468..546db9700 100644 --- a/source/Nuke.Build.Tests/ParameterServiceTest.cs +++ b/source/Nuke.Build.Tests/ParameterServiceTest.cs @@ -43,6 +43,9 @@ public void TestNotSupplied(Type destinationType, object expectedValue) [InlineData("arg2", typeof(string), "value3")] [InlineData("switch2", typeof(bool), true)] [InlineData("switch3", typeof(bool), false)] + [InlineData("array1", typeof(string[]), new[] { "element1", "element2" })] + [InlineData("array2", typeof(string[]), new string[0])] + [InlineData("array3", typeof(string[]), null)] [InlineData("notsupplied1", typeof(bool), false)] [InlineData("notsupplied2", typeof(int?), null)] public void TestEnvironmentVariables(string parameter, Type destinationType, object expectedValue) @@ -58,9 +61,11 @@ public void TestEnvironmentVariables(string parameter, Type destinationType, obj { "arg1", "value2" }, { "arg2", "value3" }, { "switch2", "true" }, - { "switch3", "false" } + { "switch3", "false" }, + { "array1", "element1+element2" }, + { "array2", "" }, }); - service.GetParameter(parameter, destinationType, separator: null).Should().Be(expectedValue); + service.GetParameter(parameter, destinationType, separator: '+').Should().BeEquivalentTo(expectedValue); } [Fact] diff --git a/source/Nuke.Build/Execution/ParameterService.cs b/source/Nuke.Build/Execution/ParameterService.cs index 66bb1c718..f293f6a6e 100644 --- a/source/Nuke.Build/Execution/ParameterService.cs +++ b/source/Nuke.Build/Execution/ParameterService.cs @@ -214,26 +214,11 @@ static string GetTrimmedName(string name) try { - return ConvertValues(variableName, separator.HasValue ? value.Split(separator.Value) : new[] { value }, destinationType); + return Convert(value, destinationType, separator); } catch (Exception ex) { - Assert.Fail(new[] { ex.Message, "Environment variable was:", value }.JoinNewLine()); - // ReSharper disable once HeuristicUnreachableCode - return null; - } - } - - [CanBeNull] - private object ConvertValues(string parameterName, IReadOnlyCollection values, Type destinationType) - { - try - { - return Convert(values, destinationType); - } - catch (Exception ex) - { - Assert.Fail(new[] { $"Resolving parameter '{parameterName}' failed.", ex.Message }.JoinNewLine()); + Assert.Fail(new[] { ex.Message, $"Resolving parameter '{variableName}' failed. Environment variable was:", value }.JoinNewLine()); // ReSharper disable once HeuristicUnreachableCode return null; } diff --git a/source/Nuke.Utilities.Tests/Reflection/ReflectionUtilityTest.cs b/source/Nuke.Utilities.Tests/Reflection/ReflectionUtilityTest.cs index e80d1fbac..b40e835ff 100644 --- a/source/Nuke.Utilities.Tests/Reflection/ReflectionUtilityTest.cs +++ b/source/Nuke.Utilities.Tests/Reflection/ReflectionUtilityTest.cs @@ -86,13 +86,16 @@ public void TestConversionCollections() .Should().BeOfType().Which .Should().BeEmpty(); + ReflectionUtility.Convert(string.Empty, typeof(string[]), separator: '+') + .Should().BeOfType().Which + .Should().BeEmpty(); + ReflectionUtility.Convert("A+B+C", typeof(string[]), separator: '+') .Should().BeOfType().Which - .Should().HaveCount(3); + .Should().Equal("A", "B", "C"); ReflectionUtility.Convert("1 2 3", typeof(int[]), separator: ' ') .Should().BeOfType().Which - .Should().HaveCount(3) - .And.Contain(2); + .Should().Equal(1, 2, 3); } } diff --git a/source/Nuke.Utilities/Reflection/ReflectionUtility.Conversion.cs b/source/Nuke.Utilities/Reflection/ReflectionUtility.Conversion.cs index ea1d21ae2..07c1a9dfb 100644 --- a/source/Nuke.Utilities/Reflection/ReflectionUtility.Conversion.cs +++ b/source/Nuke.Utilities/Reflection/ReflectionUtility.Conversion.cs @@ -44,7 +44,9 @@ public static object Convert(object value, Type destinationType) [CanBeNull] public static object Convert(string value, Type destinationType, char? separator) { - return Convert(separator.HasValue ? value.Split(separator.Value) : new[] { value }, destinationType); + var values = (separator.HasValue ? value.Split(separator.Value) : new[] { value }) + .Where(x => !x.IsNullOrWhiteSpace()).ToArray(); + return Convert(values, destinationType); } [CanBeNull] From ee93410c9f838181978ee15d8a62a3b055c36351 Mon Sep 17 00:00:00 2001 From: Matthias Koch Date: Tue, 10 Sep 2024 02:52:46 +0200 Subject: [PATCH 53/56] chore: update CHANGELOG.md --- CHANGELOG.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7a40077a1..b73124504 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,16 +5,28 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). ## [vNext] +- Added schema generation with references for `build.schema.json` +- Added deserialization of full objects from `parameters.json` - Added `AbsolutePath` extension methods for `AddUnixSymlink`, `Copy*`, `Move*`, `Rename*` +- Added support for preprocessor directives in solution parsing - Added `Pattern` in favor of property in `LatestGitHubReleaseAttribute` - Added `ConcurrencyGroup`, `ConcurrencyCancelInProgress`, `EnvironmentName`, `EnvironmentUrl` in `GitHubActionsAttribute` +- Added `DotnetPackagingTasks` +- Fixed invoked targets to not be excluded from skipping +- Fixed stripping of hyphens in skipped target names +- Fixed empty environment variables to be resolved as empty arrays +- Fixed `EnableUnsafeBinaryFormatterSerialization` to be set through `AppContext` - Fixed unquoting of multiple quoted arguments in `ArgumentStringHandler` +- Fixed using logger from settings in parallel execution +- Fixed handling of duplicated NuGet package files +- Fixed inclusion of original NuGet packages in requirements - Fixed GitHubActions to use latest action versions - Fixed `DotCoverTasks` and `EntityFrameworkTasks` tool path resolution - Fixed missing members in `GitHubActionsImage` - Fixed missing properties in `GitLab` - Fixed missing parameters in `AzurePipelines.SetVariables` - Fixed missing arguments in `DotNetTasks` +- Fixed tool path in `CodecovTasks` ## [8.0.0] / 2024-01-18 - Changed string parameters to violate requirement when empty or whitespace From 67fbf5110c8cc184ad340cc966eb1dff6c08a495 Mon Sep 17 00:00:00 2001 From: Matthias Koch Date: Tue, 10 Sep 2024 02:54:34 +0200 Subject: [PATCH 54/56] chore: regenerate tools --- .../Tools/Codecov/Codecov.Generated.cs | 2 +- .../Tools/DotNet/DotNet.Generated.cs | 414 ++++++++ .../DotnetPackaging.Generated.cs | 958 ++++++++++++++++++ .../EntityFramework.Generated.cs | 52 +- 4 files changed, 1399 insertions(+), 27 deletions(-) create mode 100644 source/Nuke.Common/Tools/DotnetPackaging/DotnetPackaging.Generated.cs diff --git a/source/Nuke.Common/Tools/Codecov/Codecov.Generated.cs b/source/Nuke.Common/Tools/Codecov/Codecov.Generated.cs index 34742c39b..4665ca61b 100644 --- a/source/Nuke.Common/Tools/Codecov/Codecov.Generated.cs +++ b/source/Nuke.Common/Tools/Codecov/Codecov.Generated.cs @@ -27,7 +27,7 @@ namespace Nuke.Common.Tools.Codecov; public partial class CodecovTasks : IRequireNuGetPackage { - public const string CodecovPackageId = "Codecov.Tool"; + public const string CodecovPackageId = "CodecovUploader"; /// /// Path to the Codecov executable. /// diff --git a/source/Nuke.Common/Tools/DotNet/DotNet.Generated.cs b/source/Nuke.Common/Tools/DotNet/DotNet.Generated.cs index 81b9b753b..dbd8f89cf 100644 --- a/source/Nuke.Common/Tools/DotNet/DotNet.Generated.cs +++ b/source/Nuke.Common/Tools/DotNet/DotNet.Generated.cs @@ -859,6 +859,7 @@ public static IReadOnlyCollection DotNetFormat(ConfigureThis is a CLI wrapper with fluent API that allows to modify the following arguments:

///
    ///
  • <project> via
  • + ///
  • --arch via
  • ///
  • --configuration via
  • ///
  • --disable-parallel via
  • ///
  • --force via
  • @@ -873,6 +874,7 @@ public static IReadOnlyCollection DotNetFormat(Configure--no-dependencies via ///
  • --no-restore via
  • ///
  • --nologo via
  • + ///
  • --os via
  • ///
  • --output via
  • ///
  • --packages via
  • ///
  • --runtime via
  • @@ -882,6 +884,7 @@ public static IReadOnlyCollection DotNetFormat(Configure--verbosity via ///
  • --version-suffix via
  • ///
  • /property via
  • + ///
  • /t via
  • ///
/// public static IReadOnlyCollection DotNetPublish(DotNetPublishSettings toolSettings = null) @@ -899,6 +902,7 @@ public static IReadOnlyCollection DotNetPublish(DotNetPublishSettings to ///

This is a CLI wrapper with fluent API that allows to modify the following arguments:

///
    ///
  • <project> via
  • + ///
  • --arch via
  • ///
  • --configuration via
  • ///
  • --disable-parallel via
  • ///
  • --force via
  • @@ -913,6 +917,7 @@ public static IReadOnlyCollection DotNetPublish(DotNetPublishSettings to ///
  • --no-dependencies via
  • ///
  • --no-restore via
  • ///
  • --nologo via
  • + ///
  • --os via
  • ///
  • --output via
  • ///
  • --packages via
  • ///
  • --runtime via
  • @@ -922,6 +927,7 @@ public static IReadOnlyCollection DotNetPublish(DotNetPublishSettings to ///
  • --verbosity via
  • ///
  • --version-suffix via
  • ///
  • /property via
  • + ///
  • /t via
  • ///
/// public static IReadOnlyCollection DotNetPublish(Configure configurator) @@ -936,6 +942,7 @@ public static IReadOnlyCollection DotNetPublish(ConfigureThis is a CLI wrapper with fluent API that allows to modify the following arguments:

///
    ///
  • <project> via
  • + ///
  • --arch via
  • ///
  • --configuration via
  • ///
  • --disable-parallel via
  • ///
  • --force via
  • @@ -950,6 +957,7 @@ public static IReadOnlyCollection DotNetPublish(Configure--no-dependencies via ///
  • --no-restore via
  • ///
  • --nologo via
  • + ///
  • --os via
  • ///
  • --output via
  • ///
  • --packages via
  • ///
  • --runtime via
  • @@ -959,6 +967,7 @@ public static IReadOnlyCollection DotNetPublish(Configure--verbosity via ///
  • --version-suffix via
  • ///
  • /property via
  • + ///
  • /t via
  • ///
/// public static IEnumerable<(DotNetPublishSettings Settings, IReadOnlyCollection Output)> DotNetPublish(CombinatorialConfigure configurator, int degreeOfParallelism = 1, bool completeOnFailure = false) @@ -1430,6 +1439,7 @@ public static IReadOnlyCollection DotNetToolUpdate(Configure--interactive via ///
  • --no-cache via
  • ///
  • --skip-manifest-update via
  • + ///
  • --skip-sign-check via
  • ///
  • --source via
  • ///
  • --temp-dir via
  • ///
  • --verbosity via
  • @@ -1457,6 +1467,7 @@ public static IReadOnlyCollection DotNetWorkloadInstall(DotNetWorkloadIn ///
  • --interactive via
  • ///
  • --no-cache via
  • ///
  • --skip-manifest-update via
  • + ///
  • --skip-sign-check via
  • ///
  • --source via
  • ///
  • --temp-dir via
  • ///
  • --verbosity via
  • @@ -1481,6 +1492,7 @@ public static IReadOnlyCollection DotNetWorkloadInstall(Configure--interactive via ///
  • --no-cache via
  • ///
  • --skip-manifest-update via
  • + ///
  • --skip-sign-check via
  • ///
  • --source via
  • ///
  • --temp-dir via
  • ///
  • --verbosity via
  • @@ -1550,6 +1562,7 @@ public static IReadOnlyCollection DotNetWorkloadUninstall(Configure--interactive via ///
  • --no-cache via
  • ///
  • --skip-manifest-update via
  • + ///
  • --skip-sign-check via
  • ///
  • --source via
  • ///
  • --temp-dir via
  • ///
  • --verbosity via
  • @@ -1577,6 +1590,7 @@ public static IReadOnlyCollection DotNetWorkloadRestore(DotNetWorkloadRe ///
  • --interactive via
  • ///
  • --no-cache via
  • ///
  • --skip-manifest-update via
  • + ///
  • --skip-sign-check via
  • ///
  • --source via
  • ///
  • --temp-dir via
  • ///
  • --verbosity via
  • @@ -1601,6 +1615,7 @@ public static IReadOnlyCollection DotNetWorkloadRestore(Configure--interactive via ///
  • --no-cache via
  • ///
  • --skip-manifest-update via
  • + ///
  • --skip-sign-check via
  • ///
  • --source via
  • ///
  • --temp-dir via
  • ///
  • --verbosity via
  • @@ -1625,6 +1640,7 @@ public static IReadOnlyCollection DotNetWorkloadRestore(Configure--include-previews via ///
  • --interactive via
  • ///
  • --no-cache via
  • + ///
  • --skip-sign-check via
  • ///
  • --source via
  • ///
  • --temp-dir via
  • ///
  • --verbosity via
  • @@ -1652,6 +1668,7 @@ public static IReadOnlyCollection DotNetWorkloadUpdate(DotNetWorkloadUpd ///
  • --include-previews via
  • ///
  • --interactive via
  • ///
  • --no-cache via
  • + ///
  • --skip-sign-check via
  • ///
  • --source via
  • ///
  • --temp-dir via
  • ///
  • --verbosity via
  • @@ -1676,6 +1693,7 @@ public static IReadOnlyCollection DotNetWorkloadUpdate(Configure--include-previews via ///
  • --interactive via
  • ///
  • --no-cache via
  • + ///
  • --skip-sign-check via
  • ///
  • --source via
  • ///
  • --temp-dir via
  • ///
  • --verbosity via
  • @@ -1698,6 +1716,7 @@ public static IReadOnlyCollection DotNetWorkloadUpdate(Configure--include-previews via ///
  • --interactive via
  • ///
  • --no-cache via
  • + ///
  • --skip-sign-check via
  • ///
  • --source via
  • ///
  • --temp-dir via
  • ///
  • --verbosity via
  • @@ -1723,6 +1742,7 @@ public static IReadOnlyCollection DotNetWorkloadRepair(DotNetWorkloadRep ///
  • --include-previews via
  • ///
  • --interactive via
  • ///
  • --no-cache via
  • + ///
  • --skip-sign-check via
  • ///
  • --source via
  • ///
  • --temp-dir via
  • ///
  • --verbosity via
  • @@ -1745,6 +1765,7 @@ public static IReadOnlyCollection DotNetWorkloadRepair(Configure--include-previews via ///
  • --interactive via
  • ///
  • --no-cache via
  • + ///
  • --skip-sign-check via
  • ///
  • --source via
  • ///
  • --temp-dir via
  • ///
  • --verbosity via
  • @@ -2761,6 +2782,10 @@ public partial class DotNetPublishSettings : ToolSettings /// public virtual string Project { get; internal set; } /// + /// Specifies the target architecture. This is a shorthand syntax for setting the Runtime Identifier (RID), where the provided value is combined with the default RID. For example, on a win-x64 machine, specifying --arch x86 sets the RID to win-x86. If you use this option, don't use the -r|--runtime option. Available since .NET 6 Preview 7. + /// + public virtual string Architecture { get; internal set; } + /// /// Defines the build configuration. The default value is Debug. /// public virtual string Configuration { get; internal set; } @@ -2785,6 +2810,10 @@ public partial class DotNetPublishSettings : ToolSettings /// public virtual string Output { get; internal set; } /// + /// Specifies the target operating system (OS). This is a shorthand syntax for setting the Runtime Identifier (RID), where the provided value is combined with the default RID. For example, on a win-x64 machine, specifying --os linux sets the RID to linux-x64. If you use this option, don't use the -r|--runtime option. Available since .NET 6. + /// + public virtual string OperatingSystem { get; internal set; } + /// /// Publishes the .NET Core runtime with your application so the runtime doesn't need to be installed on the target machine. If a runtime identifier is specified, its default value is true. For more information about the different deployment types, see .NET Core application deployment. /// public virtual bool? SelfContained { get; internal set; } @@ -2805,6 +2834,11 @@ public partial class DotNetPublishSettings : ToolSettings /// public virtual bool? NoLogo { get; internal set; } /// + ///

    Build the specified targets in the project. Specify each target separately, or use a semicolon or comma to separate multiple targets, as the following example shows:
    /target:Resources;Compile

    If you specify any targets by using this switch, they are run instead of any targets in the DefaultTargets attribute in the project file. For more information, see Target Build Order and How to: Specify Which Target to Build First.

    A target is a group of tasks. For more information, see Targets.

    + ///
    + public virtual IReadOnlyList Targets => TargetsInternal.AsReadOnly(); + internal List TargetsInternal { get; set; } = new List(); + /// /// Disables restoring multiple projects in parallel. /// public virtual bool? DisableParallel { get; internal set; } @@ -2859,17 +2893,20 @@ protected override Arguments ConfigureProcessArguments(Arguments arguments) arguments .Add("publish") .Add("{value}", Project) + .Add("--arch {value}", Architecture) .Add("--configuration {value}", Configuration) .Add("--framework {value}", Framework) .Add("--manifest {value}", Manifest) .Add("--no-restore", NoRestore) .Add("--no-build", NoBuild) .Add("--output {value}", Output) + .Add("--os {value}", OperatingSystem) .Add("--self-contained {value}", SelfContained) .Add("--runtime {value}", Runtime) .Add("--verbosity {value}", Verbosity) .Add("--version-suffix {value}", VersionSuffix) .Add("--nologo", NoLogo) + .Add("/t:{value}", Targets, separator: ';') .Add("--disable-parallel", DisableParallel) .Add("--force", Force) .Add("--ignore-failed-sources", IgnoreFailedSources) @@ -3361,6 +3398,10 @@ public partial class DotNetWorkloadInstallSettings : ToolSettings /// public virtual bool? SkipManifestUpdate { get; internal set; } /// + /// Skipping the nuget package signature verification. + /// + public virtual bool? SkipSignCheck { get; internal set; } + /// /// Specifies the URI of the NuGet package source to use. This setting overrides all of the sources specified in the nuget.config files. Multiple sources can be provided by specifying this option multiple times. /// public virtual string Source { get; internal set; } @@ -3384,6 +3425,7 @@ protected override Arguments ConfigureProcessArguments(Arguments arguments) .Add("--interactive", Interactive) .Add("--no-cache", NoCache) .Add("--skip-manifest-update", SkipManifestUpdate) + .Add("--skip-sign-check", SkipSignCheck) .Add("--source {value}", Source) .Add("--temp-dir {value}", TempDir) .Add("--verbosity {value}", Verbosity); @@ -3468,6 +3510,10 @@ public partial class DotNetWorkloadRestoreSettings : ToolSettings /// public virtual bool? SkipManifestUpdate { get; internal set; } /// + /// Skipping the nuget package signature verification. + /// + public virtual bool? SkipSignCheck { get; internal set; } + /// /// Specifies the URI of the NuGet package source to use. This setting overrides all of the sources specified in the nuget.config files. Multiple sources can be provided by specifying this option multiple times. /// public virtual string Source { get; internal set; } @@ -3491,6 +3537,7 @@ protected override Arguments ConfigureProcessArguments(Arguments arguments) .Add("--interactive", Interactive) .Add("--no-cache", NoCache) .Add("--skip-manifest-update", SkipManifestUpdate) + .Add("--skip-sign-check", SkipSignCheck) .Add("--source {value}", Source) .Add("--temp-dir {value}", TempDir) .Add("--verbosity {value}", Verbosity); @@ -3546,6 +3593,10 @@ public partial class DotNetWorkloadUpdateSettings : ToolSettings /// public virtual bool? NoCache { get; internal set; } /// + /// Skipping the nuget package signature verification. + /// + public virtual bool? SkipSignCheck { get; internal set; } + /// /// Specifies the URI of the NuGet package source to use. This setting overrides all of the sources specified in the nuget.config files. Multiple sources can be provided by specifying this option multiple times. /// public virtual string Source { get; internal set; } @@ -3569,6 +3620,7 @@ protected override Arguments ConfigureProcessArguments(Arguments arguments) .Add("--include-previews", IncludePreviews) .Add("--interactive", Interactive) .Add("--no-cache", NoCache) + .Add("--skip-sign-check", SkipSignCheck) .Add("--source {value}", Source) .Add("--temp-dir {value}", TempDir) .Add("--verbosity {value}", Verbosity); @@ -3616,6 +3668,10 @@ public partial class DotNetWorkloadRepairSettings : ToolSettings /// public virtual bool? NoCache { get; internal set; } /// + /// Skipping the nuget package signature verification. + /// + public virtual bool? SkipSignCheck { get; internal set; } + /// /// Specifies the URI of the NuGet package source to use. This setting overrides all of the sources specified in the nuget.config files. Multiple sources can be provided by specifying this option multiple times. /// public virtual string Source { get; internal set; } @@ -3637,6 +3693,7 @@ protected override Arguments ConfigureProcessArguments(Arguments arguments) .Add("--include-previews", IncludePreviews) .Add("--interactive", Interactive) .Add("--no-cache", NoCache) + .Add("--skip-sign-check", SkipSignCheck) .Add("--source {value}", Source) .Add("--temp-dir {value}", TempDir) .Add("--verbosity {value}", Verbosity); @@ -19814,6 +19871,30 @@ public static T ResetProject(this T toolSettings) where T : DotNetPublishSett return toolSettings; } #endregion + #region Architecture + /// + ///

    Sets

    + ///

    Specifies the target architecture. This is a shorthand syntax for setting the Runtime Identifier (RID), where the provided value is combined with the default RID. For example, on a win-x64 machine, specifying --arch x86 sets the RID to win-x86. If you use this option, don't use the -r|--runtime option. Available since .NET 6 Preview 7.

    + ///
    + [Pure] + public static T SetArchitecture(this T toolSettings, string architecture) where T : DotNetPublishSettings + { + toolSettings = toolSettings.NewInstance(); + toolSettings.Architecture = architecture; + return toolSettings; + } + /// + ///

    Resets

    + ///

    Specifies the target architecture. This is a shorthand syntax for setting the Runtime Identifier (RID), where the provided value is combined with the default RID. For example, on a win-x64 machine, specifying --arch x86 sets the RID to win-x86. If you use this option, don't use the -r|--runtime option. Available since .NET 6 Preview 7.

    + ///
    + [Pure] + public static T ResetArchitecture(this T toolSettings) where T : DotNetPublishSettings + { + toolSettings = toolSettings.NewInstance(); + toolSettings.Architecture = null; + return toolSettings; + } + #endregion #region Configuration /// ///

    Sets

    @@ -20024,6 +20105,30 @@ public static T ResetOutput(this T toolSettings) where T : DotNetPublishSetti return toolSettings; } #endregion + #region OperatingSystem + /// + ///

    Sets

    + ///

    Specifies the target operating system (OS). This is a shorthand syntax for setting the Runtime Identifier (RID), where the provided value is combined with the default RID. For example, on a win-x64 machine, specifying --os linux sets the RID to linux-x64. If you use this option, don't use the -r|--runtime option. Available since .NET 6.

    + ///
    + [Pure] + public static T SetOperatingSystem(this T toolSettings, string operatingSystem) where T : DotNetPublishSettings + { + toolSettings = toolSettings.NewInstance(); + toolSettings.OperatingSystem = operatingSystem; + return toolSettings; + } + /// + ///

    Resets

    + ///

    Specifies the target operating system (OS). This is a shorthand syntax for setting the Runtime Identifier (RID), where the provided value is combined with the default RID. For example, on a win-x64 machine, specifying --os linux sets the RID to linux-x64. If you use this option, don't use the -r|--runtime option. Available since .NET 6.

    + ///
    + [Pure] + public static T ResetOperatingSystem(this T toolSettings) where T : DotNetPublishSettings + { + toolSettings = toolSettings.NewInstance(); + toolSettings.OperatingSystem = null; + return toolSettings; + } + #endregion #region SelfContained /// ///

    Sets

    @@ -20210,6 +20315,87 @@ public static T ToggleNoLogo(this T toolSettings) where T : DotNetPublishSett return toolSettings; } #endregion + #region Targets + /// + ///

    Sets to a new list

    + ///

    Build the specified targets in the project. Specify each target separately, or use a semicolon or comma to separate multiple targets, as the following example shows:
    /target:Resources;Compile

    If you specify any targets by using this switch, they are run instead of any targets in the DefaultTargets attribute in the project file. For more information, see Target Build Order and How to: Specify Which Target to Build First.

    A target is a group of tasks. For more information, see Targets.

    + ///
    + [Pure] + public static T SetTargets(this T toolSettings, params string[] targets) where T : DotNetPublishSettings + { + toolSettings = toolSettings.NewInstance(); + toolSettings.TargetsInternal = targets.ToList(); + return toolSettings; + } + /// + ///

    Sets to a new list

    + ///

    Build the specified targets in the project. Specify each target separately, or use a semicolon or comma to separate multiple targets, as the following example shows:
    /target:Resources;Compile

    If you specify any targets by using this switch, they are run instead of any targets in the DefaultTargets attribute in the project file. For more information, see Target Build Order and How to: Specify Which Target to Build First.

    A target is a group of tasks. For more information, see Targets.

    + ///
    + [Pure] + public static T SetTargets(this T toolSettings, IEnumerable targets) where T : DotNetPublishSettings + { + toolSettings = toolSettings.NewInstance(); + toolSettings.TargetsInternal = targets.ToList(); + return toolSettings; + } + /// + ///

    Adds values to

    + ///

    Build the specified targets in the project. Specify each target separately, or use a semicolon or comma to separate multiple targets, as the following example shows:
    /target:Resources;Compile

    If you specify any targets by using this switch, they are run instead of any targets in the DefaultTargets attribute in the project file. For more information, see Target Build Order and How to: Specify Which Target to Build First.

    A target is a group of tasks. For more information, see Targets.

    + ///
    + [Pure] + public static T AddTargets(this T toolSettings, params string[] targets) where T : DotNetPublishSettings + { + toolSettings = toolSettings.NewInstance(); + toolSettings.TargetsInternal.AddRange(targets); + return toolSettings; + } + /// + ///

    Adds values to

    + ///

    Build the specified targets in the project. Specify each target separately, or use a semicolon or comma to separate multiple targets, as the following example shows:
    /target:Resources;Compile

    If you specify any targets by using this switch, they are run instead of any targets in the DefaultTargets attribute in the project file. For more information, see Target Build Order and How to: Specify Which Target to Build First.

    A target is a group of tasks. For more information, see Targets.

    + ///
    + [Pure] + public static T AddTargets(this T toolSettings, IEnumerable targets) where T : DotNetPublishSettings + { + toolSettings = toolSettings.NewInstance(); + toolSettings.TargetsInternal.AddRange(targets); + return toolSettings; + } + /// + ///

    Clears

    + ///

    Build the specified targets in the project. Specify each target separately, or use a semicolon or comma to separate multiple targets, as the following example shows:
    /target:Resources;Compile

    If you specify any targets by using this switch, they are run instead of any targets in the DefaultTargets attribute in the project file. For more information, see Target Build Order and How to: Specify Which Target to Build First.

    A target is a group of tasks. For more information, see Targets.

    + ///
    + [Pure] + public static T ClearTargets(this T toolSettings) where T : DotNetPublishSettings + { + toolSettings = toolSettings.NewInstance(); + toolSettings.TargetsInternal.Clear(); + return toolSettings; + } + /// + ///

    Removes values from

    + ///

    Build the specified targets in the project. Specify each target separately, or use a semicolon or comma to separate multiple targets, as the following example shows:
    /target:Resources;Compile

    If you specify any targets by using this switch, they are run instead of any targets in the DefaultTargets attribute in the project file. For more information, see Target Build Order and How to: Specify Which Target to Build First.

    A target is a group of tasks. For more information, see Targets.

    + ///
    + [Pure] + public static T RemoveTargets(this T toolSettings, params string[] targets) where T : DotNetPublishSettings + { + toolSettings = toolSettings.NewInstance(); + var hashSet = new HashSet(targets); + toolSettings.TargetsInternal.RemoveAll(x => hashSet.Contains(x)); + return toolSettings; + } + /// + ///

    Removes values from

    + ///

    Build the specified targets in the project. Specify each target separately, or use a semicolon or comma to separate multiple targets, as the following example shows:
    /target:Resources;Compile

    If you specify any targets by using this switch, they are run instead of any targets in the DefaultTargets attribute in the project file. For more information, see Target Build Order and How to: Specify Which Target to Build First.

    A target is a group of tasks. For more information, see Targets.

    + ///
    + [Pure] + public static T RemoveTargets(this T toolSettings, IEnumerable targets) where T : DotNetPublishSettings + { + toolSettings = toolSettings.NewInstance(); + var hashSet = new HashSet(targets); + toolSettings.TargetsInternal.RemoveAll(x => hashSet.Contains(x)); + return toolSettings; + } + #endregion #region DisableParallel /// ///

    Sets

    @@ -24659,6 +24845,63 @@ public static T ToggleSkipManifestUpdate(this T toolSettings) where T : DotNe return toolSettings; } #endregion + #region SkipSignCheck + /// + ///

    Sets

    + ///

    Skipping the nuget package signature verification.

    + ///
    + [Pure] + public static T SetSkipSignCheck(this T toolSettings, bool? skipSignCheck) where T : DotNetWorkloadInstallSettings + { + toolSettings = toolSettings.NewInstance(); + toolSettings.SkipSignCheck = skipSignCheck; + return toolSettings; + } + /// + ///

    Resets

    + ///

    Skipping the nuget package signature verification.

    + ///
    + [Pure] + public static T ResetSkipSignCheck(this T toolSettings) where T : DotNetWorkloadInstallSettings + { + toolSettings = toolSettings.NewInstance(); + toolSettings.SkipSignCheck = null; + return toolSettings; + } + /// + ///

    Enables

    + ///

    Skipping the nuget package signature verification.

    + ///
    + [Pure] + public static T EnableSkipSignCheck(this T toolSettings) where T : DotNetWorkloadInstallSettings + { + toolSettings = toolSettings.NewInstance(); + toolSettings.SkipSignCheck = true; + return toolSettings; + } + /// + ///

    Disables

    + ///

    Skipping the nuget package signature verification.

    + ///
    + [Pure] + public static T DisableSkipSignCheck(this T toolSettings) where T : DotNetWorkloadInstallSettings + { + toolSettings = toolSettings.NewInstance(); + toolSettings.SkipSignCheck = false; + return toolSettings; + } + /// + ///

    Toggles

    + ///

    Skipping the nuget package signature verification.

    + ///
    + [Pure] + public static T ToggleSkipSignCheck(this T toolSettings) where T : DotNetWorkloadInstallSettings + { + toolSettings = toolSettings.NewInstance(); + toolSettings.SkipSignCheck = !toolSettings.SkipSignCheck; + return toolSettings; + } + #endregion #region Source /// ///

    Sets

    @@ -25222,6 +25465,63 @@ public static T ToggleSkipManifestUpdate(this T toolSettings) where T : DotNe return toolSettings; } #endregion + #region SkipSignCheck + /// + ///

    Sets

    + ///

    Skipping the nuget package signature verification.

    + ///
    + [Pure] + public static T SetSkipSignCheck(this T toolSettings, bool? skipSignCheck) where T : DotNetWorkloadRestoreSettings + { + toolSettings = toolSettings.NewInstance(); + toolSettings.SkipSignCheck = skipSignCheck; + return toolSettings; + } + /// + ///

    Resets

    + ///

    Skipping the nuget package signature verification.

    + ///
    + [Pure] + public static T ResetSkipSignCheck(this T toolSettings) where T : DotNetWorkloadRestoreSettings + { + toolSettings = toolSettings.NewInstance(); + toolSettings.SkipSignCheck = null; + return toolSettings; + } + /// + ///

    Enables

    + ///

    Skipping the nuget package signature verification.

    + ///
    + [Pure] + public static T EnableSkipSignCheck(this T toolSettings) where T : DotNetWorkloadRestoreSettings + { + toolSettings = toolSettings.NewInstance(); + toolSettings.SkipSignCheck = true; + return toolSettings; + } + /// + ///

    Disables

    + ///

    Skipping the nuget package signature verification.

    + ///
    + [Pure] + public static T DisableSkipSignCheck(this T toolSettings) where T : DotNetWorkloadRestoreSettings + { + toolSettings = toolSettings.NewInstance(); + toolSettings.SkipSignCheck = false; + return toolSettings; + } + /// + ///

    Toggles

    + ///

    Skipping the nuget package signature verification.

    + ///
    + [Pure] + public static T ToggleSkipSignCheck(this T toolSettings) where T : DotNetWorkloadRestoreSettings + { + toolSettings = toolSettings.NewInstance(); + toolSettings.SkipSignCheck = !toolSettings.SkipSignCheck; + return toolSettings; + } + #endregion #region Source /// ///

    Sets

    @@ -25727,6 +26027,63 @@ public static T ToggleNoCache(this T toolSettings) where T : DotNetWorkloadUp return toolSettings; } #endregion + #region SkipSignCheck + /// + ///

    Sets

    + ///

    Skipping the nuget package signature verification.

    + ///
    + [Pure] + public static T SetSkipSignCheck(this T toolSettings, bool? skipSignCheck) where T : DotNetWorkloadUpdateSettings + { + toolSettings = toolSettings.NewInstance(); + toolSettings.SkipSignCheck = skipSignCheck; + return toolSettings; + } + /// + ///

    Resets

    + ///

    Skipping the nuget package signature verification.

    + ///
    + [Pure] + public static T ResetSkipSignCheck(this T toolSettings) where T : DotNetWorkloadUpdateSettings + { + toolSettings = toolSettings.NewInstance(); + toolSettings.SkipSignCheck = null; + return toolSettings; + } + /// + ///

    Enables

    + ///

    Skipping the nuget package signature verification.

    + ///
    + [Pure] + public static T EnableSkipSignCheck(this T toolSettings) where T : DotNetWorkloadUpdateSettings + { + toolSettings = toolSettings.NewInstance(); + toolSettings.SkipSignCheck = true; + return toolSettings; + } + /// + ///

    Disables

    + ///

    Skipping the nuget package signature verification.

    + ///
    + [Pure] + public static T DisableSkipSignCheck(this T toolSettings) where T : DotNetWorkloadUpdateSettings + { + toolSettings = toolSettings.NewInstance(); + toolSettings.SkipSignCheck = false; + return toolSettings; + } + /// + ///

    Toggles

    + ///

    Skipping the nuget package signature verification.

    + ///
    + [Pure] + public static T ToggleSkipSignCheck(this T toolSettings) where T : DotNetWorkloadUpdateSettings + { + toolSettings = toolSettings.NewInstance(); + toolSettings.SkipSignCheck = !toolSettings.SkipSignCheck; + return toolSettings; + } + #endregion #region Source /// ///

    Sets

    @@ -26118,6 +26475,63 @@ public static T ToggleNoCache(this T toolSettings) where T : DotNetWorkloadRe return toolSettings; } #endregion + #region SkipSignCheck + /// + ///

    Sets

    + ///

    Skipping the nuget package signature verification.

    + ///
    + [Pure] + public static T SetSkipSignCheck(this T toolSettings, bool? skipSignCheck) where T : DotNetWorkloadRepairSettings + { + toolSettings = toolSettings.NewInstance(); + toolSettings.SkipSignCheck = skipSignCheck; + return toolSettings; + } + /// + ///

    Resets

    + ///

    Skipping the nuget package signature verification.

    + ///
    + [Pure] + public static T ResetSkipSignCheck(this T toolSettings) where T : DotNetWorkloadRepairSettings + { + toolSettings = toolSettings.NewInstance(); + toolSettings.SkipSignCheck = null; + return toolSettings; + } + /// + ///

    Enables

    + ///

    Skipping the nuget package signature verification.

    + ///
    + [Pure] + public static T EnableSkipSignCheck(this T toolSettings) where T : DotNetWorkloadRepairSettings + { + toolSettings = toolSettings.NewInstance(); + toolSettings.SkipSignCheck = true; + return toolSettings; + } + /// + ///

    Disables

    + ///

    Skipping the nuget package signature verification.

    + ///
    + [Pure] + public static T DisableSkipSignCheck(this T toolSettings) where T : DotNetWorkloadRepairSettings + { + toolSettings = toolSettings.NewInstance(); + toolSettings.SkipSignCheck = false; + return toolSettings; + } + /// + ///

    Toggles

    + ///

    Skipping the nuget package signature verification.

    + ///
    + [Pure] + public static T ToggleSkipSignCheck(this T toolSettings) where T : DotNetWorkloadRepairSettings + { + toolSettings = toolSettings.NewInstance(); + toolSettings.SkipSignCheck = !toolSettings.SkipSignCheck; + return toolSettings; + } + #endregion #region Source /// ///

    Sets

    diff --git a/source/Nuke.Common/Tools/DotnetPackaging/DotnetPackaging.Generated.cs b/source/Nuke.Common/Tools/DotnetPackaging/DotnetPackaging.Generated.cs new file mode 100644 index 000000000..0a9e56ce7 --- /dev/null +++ b/source/Nuke.Common/Tools/DotnetPackaging/DotnetPackaging.Generated.cs @@ -0,0 +1,958 @@ +// Generated from https://github.com/nuke-build/nuke/blob/master/source/Nuke.Common/Tools/DotnetPackaging/DotnetPackaging.json + +using JetBrains.Annotations; +using Newtonsoft.Json; +using Nuke.Common; +using Nuke.Common.Tooling; +using Nuke.Common.Tools; +using Nuke.Common.Utilities.Collections; +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.ComponentModel; +using System.Diagnostics.CodeAnalysis; +using System.IO; +using System.Linq; +using System.Text; + +namespace Nuke.Common.Tools.DotnetPackaging; + +/// +///

    DotnetPackaging is able to package your application into various formats, including Deb and AppImage.

    +///

    For more details, visit the official website.

    +///
    +[PublicAPI] +[ExcludeFromCodeCoverage] +[NuGetPackageRequirement(DotnetPackagingPackageId)] +public partial class DotnetPackagingTasks + : IRequireNuGetPackage +{ + public const string DotnetPackagingPackageId = "DotnetPackaging.Console"; + /// + /// Path to the DotnetPackaging executable. + /// + public static string DotnetPackagingPath => + ToolPathResolver.TryGetEnvironmentExecutable("DOTNETPACKAGING_EXE") ?? + NuGetToolPathResolver.GetPackageExecutable("DotnetPackaging.Console", "DotnetPackaging.Console.dll"); + public static Action DotnetPackagingLogger { get; set; } = ProcessTasks.DefaultLogger; + public static Action DotnetPackagingExitHandler { get; set; } = ProcessTasks.DefaultExitHandler; + /// + ///

    DotnetPackaging is able to package your application into various formats, including Deb and AppImage.

    + ///

    For more details, visit the official website.

    + ///
    + public static IReadOnlyCollection DotnetPackaging(ArgumentStringHandler arguments, string workingDirectory = null, IReadOnlyDictionary environmentVariables = null, int? timeout = null, bool? logOutput = null, bool? logInvocation = null, Action logger = null, Action exitHandler = null) + { + using var process = ProcessTasks.StartProcess(DotnetPackagingPath, arguments, workingDirectory, environmentVariables, timeout, logOutput, logInvocation, logger ?? DotnetPackagingLogger); + (exitHandler ?? (p => DotnetPackagingExitHandler.Invoke(null, p))).Invoke(process.AssertWaitForExit()); + return process.Output; + } + /// + ///

    Creates a Debian package from the specified directory.

    + ///

    For more details, visit the official website.

    + ///
    + /// + ///

    This is a CLI wrapper with fluent API that allows to modify the following arguments:

    + ///
      + ///
    • --directory via
    • + ///
    • --metadata via
    • + ///
    • --output via
    • + ///
    + ///
    + public static IReadOnlyCollection DotnetPackagingDeb(DotnetPackagingDebSettings toolSettings = null) + { + toolSettings = toolSettings ?? new DotnetPackagingDebSettings(); + using var process = ProcessTasks.StartProcess(toolSettings); + toolSettings.ProcessExitHandler.Invoke(toolSettings, process.AssertWaitForExit()); + return process.Output; + } + /// + ///

    Creates a Debian package from the specified directory.

    + ///

    For more details, visit the official website.

    + ///
    + /// + ///

    This is a CLI wrapper with fluent API that allows to modify the following arguments:

    + ///
      + ///
    • --directory via
    • + ///
    • --metadata via
    • + ///
    • --output via
    • + ///
    + ///
    + public static IReadOnlyCollection DotnetPackagingDeb(Configure configurator) + { + return DotnetPackagingDeb(configurator(new DotnetPackagingDebSettings())); + } + /// + ///

    Creates a Debian package from the specified directory.

    + ///

    For more details, visit the official website.

    + ///
    + /// + ///

    This is a CLI wrapper with fluent API that allows to modify the following arguments:

    + ///
      + ///
    • --directory via
    • + ///
    • --metadata via
    • + ///
    • --output via
    • + ///
    + ///
    + public static IEnumerable<(DotnetPackagingDebSettings Settings, IReadOnlyCollection Output)> DotnetPackagingDeb(CombinatorialConfigure configurator, int degreeOfParallelism = 1, bool completeOnFailure = false) + { + return configurator.Invoke(DotnetPackagingDeb, DotnetPackagingLogger, degreeOfParallelism, completeOnFailure); + } + /// + ///

    Creates an AppImage package.

    + ///

    For more details, visit the official website.

    + ///
    + /// + ///

    This is a CLI wrapper with fluent API that allows to modify the following arguments:

    + ///
      + ///
    • --additional-categories via
    • + ///
    • --appId via
    • + ///
    • --application-name via
    • + ///
    • --directory via
    • + ///
    • --homepage via
    • + ///
    • --icon via
    • + ///
    • --license via
    • + ///
    • --main-category via
    • + ///
    • --output via
    • + ///
    • --screenshot-urls via
    • + ///
    • --summary via
    • + ///
    • --version via
    • + ///
    + ///
    + public static IReadOnlyCollection DotnetPackagingAppImage(DotnetPackagingAppImageSettings toolSettings = null) + { + toolSettings = toolSettings ?? new DotnetPackagingAppImageSettings(); + using var process = ProcessTasks.StartProcess(toolSettings); + toolSettings.ProcessExitHandler.Invoke(toolSettings, process.AssertWaitForExit()); + return process.Output; + } + /// + ///

    Creates an AppImage package.

    + ///

    For more details, visit the official website.

    + ///
    + /// + ///

    This is a CLI wrapper with fluent API that allows to modify the following arguments:

    + ///
      + ///
    • --additional-categories via
    • + ///
    • --appId via
    • + ///
    • --application-name via
    • + ///
    • --directory via
    • + ///
    • --homepage via
    • + ///
    • --icon via
    • + ///
    • --license via
    • + ///
    • --main-category via
    • + ///
    • --output via
    • + ///
    • --screenshot-urls via
    • + ///
    • --summary via
    • + ///
    • --version via
    • + ///
    + ///
    + public static IReadOnlyCollection DotnetPackagingAppImage(Configure configurator) + { + return DotnetPackagingAppImage(configurator(new DotnetPackagingAppImageSettings())); + } + /// + ///

    Creates an AppImage package.

    + ///

    For more details, visit the official website.

    + ///
    + /// + ///

    This is a CLI wrapper with fluent API that allows to modify the following arguments:

    + ///
      + ///
    • --additional-categories via
    • + ///
    • --appId via
    • + ///
    • --application-name via
    • + ///
    • --directory via
    • + ///
    • --homepage via
    • + ///
    • --icon via
    • + ///
    • --license via
    • + ///
    • --main-category via
    • + ///
    • --output via
    • + ///
    • --screenshot-urls via
    • + ///
    • --summary via
    • + ///
    • --version via
    • + ///
    + ///
    + public static IEnumerable<(DotnetPackagingAppImageSettings Settings, IReadOnlyCollection Output)> DotnetPackagingAppImage(CombinatorialConfigure configurator, int degreeOfParallelism = 1, bool completeOnFailure = false) + { + return configurator.Invoke(DotnetPackagingAppImage, DotnetPackagingLogger, degreeOfParallelism, completeOnFailure); + } +} +#region DotnetPackagingDebSettings +/// +/// Used within . +/// +[PublicAPI] +[ExcludeFromCodeCoverage] +[Serializable] +public partial class DotnetPackagingDebSettings : ToolSettings +{ + /// + /// Path to the DotnetPackaging executable. + /// + public override string ProcessToolPath => base.ProcessToolPath ?? DotnetPackagingTasks.DotnetPackagingPath; + public override Action ProcessLogger => base.ProcessLogger ?? DotnetPackagingTasks.DotnetPackagingLogger; + public override Action ProcessExitHandler => base.ProcessExitHandler ?? DotnetPackagingTasks.DotnetPackagingExitHandler; + /// + /// The input directory from which to create the package. + /// + public virtual string Directory { get; internal set; } + /// + /// The metadata file to include in the package. + /// + public virtual string Metadata { get; internal set; } + /// + /// The output DEB file to create. + /// + public virtual string Output { get; internal set; } + protected override Arguments ConfigureProcessArguments(Arguments arguments) + { + arguments + .Add("deb") + .Add("--directory={value}", Directory) + .Add("--metadata={value}", Metadata) + .Add("--output={value}", Output); + return base.ConfigureProcessArguments(arguments); + } +} +#endregion +#region DotnetPackagingAppImageSettings +/// +/// Used within . +/// +[PublicAPI] +[ExcludeFromCodeCoverage] +[Serializable] +public partial class DotnetPackagingAppImageSettings : ToolSettings +{ + /// + /// Path to the DotnetPackaging executable. + /// + public override string ProcessToolPath => base.ProcessToolPath ?? DotnetPackagingTasks.DotnetPackagingPath; + public override Action ProcessLogger => base.ProcessLogger ?? DotnetPackagingTasks.DotnetPackagingLogger; + public override Action ProcessExitHandler => base.ProcessExitHandler ?? DotnetPackagingTasks.DotnetPackagingExitHandler; + /// + /// The input directory from which to create the AppImage. + /// + public virtual string Directory { get; internal set; } + /// + /// The output AppImage file to create. + /// + public virtual string Output { get; internal set; } + /// + /// The name of the application for the AppImage. + /// + public virtual string ApplicationName { get; internal set; } + /// + /// Main category of the application. + /// + public virtual DotnetPackagingMainCategory MainCategory { get; internal set; } + /// + /// Additional categories for the application. + /// + public virtual IReadOnlyList AdditionalCategories => AdditionalCategoriesInternal.AsReadOnly(); + internal List AdditionalCategoriesInternal { get; set; } = new List(); + /// + /// The icon path for the application. When not provided, the tool looks up for an image called AppImage.png. + /// + public virtual string Icon { get; internal set; } + /// + /// Home page of the application. + /// + public virtual string Homepage { get; internal set; } + /// + /// License of the application. + /// + public virtual string License { get; internal set; } + /// + /// Version of the application. + /// + public virtual string Version { get; internal set; } + /// + /// URLs of screenshots of the application. + /// + public virtual IReadOnlyList ScreenshotUrls => ScreenshotUrlsInternal.AsReadOnly(); + internal List ScreenshotUrlsInternal { get; set; } = new List(); + /// + /// Short description of the application. + /// + public virtual string Summary { get; internal set; } + /// + /// Application ID, usually a reverse DNS name like com.SomeCompany.SomeApplication. + /// + public virtual string AppId { get; internal set; } + protected override Arguments ConfigureProcessArguments(Arguments arguments) + { + arguments + .Add("appimage") + .Add("--directory={value}", Directory) + .Add("--output={value}", Output) + .Add("--application-name={value}", ApplicationName) + .Add("--main-category {value}", MainCategory) + .Add("--additional-categories {value}", AdditionalCategories) + .Add("--icon {value}", Icon) + .Add("--homepage {value}", Homepage) + .Add("--license {value}", License) + .Add("--version {value}", Version) + .Add("--screenshot-urls {value}", ScreenshotUrls) + .Add("--summary {value}", Summary) + .Add("--appId {value}", AppId); + return base.ConfigureProcessArguments(arguments); + } +} +#endregion +#region DotnetPackagingDebSettingsExtensions +/// +/// Used within . +/// +[PublicAPI] +[ExcludeFromCodeCoverage] +public static partial class DotnetPackagingDebSettingsExtensions +{ + #region Directory + /// + ///

    Sets

    + ///

    The input directory from which to create the package.

    + ///
    + [Pure] + public static T SetDirectory(this T toolSettings, string directory) where T : DotnetPackagingDebSettings + { + toolSettings = toolSettings.NewInstance(); + toolSettings.Directory = directory; + return toolSettings; + } + /// + ///

    Resets

    + ///

    The input directory from which to create the package.

    + ///
    + [Pure] + public static T ResetDirectory(this T toolSettings) where T : DotnetPackagingDebSettings + { + toolSettings = toolSettings.NewInstance(); + toolSettings.Directory = null; + return toolSettings; + } + #endregion + #region Metadata + /// + ///

    Sets

    + ///

    The metadata file to include in the package.

    + ///
    + [Pure] + public static T SetMetadata(this T toolSettings, string metadata) where T : DotnetPackagingDebSettings + { + toolSettings = toolSettings.NewInstance(); + toolSettings.Metadata = metadata; + return toolSettings; + } + /// + ///

    Resets

    + ///

    The metadata file to include in the package.

    + ///
    + [Pure] + public static T ResetMetadata(this T toolSettings) where T : DotnetPackagingDebSettings + { + toolSettings = toolSettings.NewInstance(); + toolSettings.Metadata = null; + return toolSettings; + } + #endregion + #region Output + /// + ///

    Sets

    + ///

    The output DEB file to create.

    + ///
    + [Pure] + public static T SetOutput(this T toolSettings, string output) where T : DotnetPackagingDebSettings + { + toolSettings = toolSettings.NewInstance(); + toolSettings.Output = output; + return toolSettings; + } + /// + ///

    Resets

    + ///

    The output DEB file to create.

    + ///
    + [Pure] + public static T ResetOutput(this T toolSettings) where T : DotnetPackagingDebSettings + { + toolSettings = toolSettings.NewInstance(); + toolSettings.Output = null; + return toolSettings; + } + #endregion +} +#endregion +#region DotnetPackagingAppImageSettingsExtensions +/// +/// Used within . +/// +[PublicAPI] +[ExcludeFromCodeCoverage] +public static partial class DotnetPackagingAppImageSettingsExtensions +{ + #region Directory + /// + ///

    Sets

    + ///

    The input directory from which to create the AppImage.

    + ///
    + [Pure] + public static T SetDirectory(this T toolSettings, string directory) where T : DotnetPackagingAppImageSettings + { + toolSettings = toolSettings.NewInstance(); + toolSettings.Directory = directory; + return toolSettings; + } + /// + ///

    Resets

    + ///

    The input directory from which to create the AppImage.

    + ///
    + [Pure] + public static T ResetDirectory(this T toolSettings) where T : DotnetPackagingAppImageSettings + { + toolSettings = toolSettings.NewInstance(); + toolSettings.Directory = null; + return toolSettings; + } + #endregion + #region Output + /// + ///

    Sets

    + ///

    The output AppImage file to create.

    + ///
    + [Pure] + public static T SetOutput(this T toolSettings, string output) where T : DotnetPackagingAppImageSettings + { + toolSettings = toolSettings.NewInstance(); + toolSettings.Output = output; + return toolSettings; + } + /// + ///

    Resets

    + ///

    The output AppImage file to create.

    + ///
    + [Pure] + public static T ResetOutput(this T toolSettings) where T : DotnetPackagingAppImageSettings + { + toolSettings = toolSettings.NewInstance(); + toolSettings.Output = null; + return toolSettings; + } + #endregion + #region ApplicationName + /// + ///

    Sets

    + ///

    The name of the application for the AppImage.

    + ///
    + [Pure] + public static T SetApplicationName(this T toolSettings, string applicationName) where T : DotnetPackagingAppImageSettings + { + toolSettings = toolSettings.NewInstance(); + toolSettings.ApplicationName = applicationName; + return toolSettings; + } + /// + ///

    Resets

    + ///

    The name of the application for the AppImage.

    + ///
    + [Pure] + public static T ResetApplicationName(this T toolSettings) where T : DotnetPackagingAppImageSettings + { + toolSettings = toolSettings.NewInstance(); + toolSettings.ApplicationName = null; + return toolSettings; + } + #endregion + #region MainCategory + /// + ///

    Sets

    + ///

    Main category of the application.

    + ///
    + [Pure] + public static T SetMainCategory(this T toolSettings, DotnetPackagingMainCategory mainCategory) where T : DotnetPackagingAppImageSettings + { + toolSettings = toolSettings.NewInstance(); + toolSettings.MainCategory = mainCategory; + return toolSettings; + } + /// + ///

    Resets

    + ///

    Main category of the application.

    + ///
    + [Pure] + public static T ResetMainCategory(this T toolSettings) where T : DotnetPackagingAppImageSettings + { + toolSettings = toolSettings.NewInstance(); + toolSettings.MainCategory = null; + return toolSettings; + } + #endregion + #region AdditionalCategories + /// + ///

    Sets to a new list

    + ///

    Additional categories for the application.

    + ///
    + [Pure] + public static T SetAdditionalCategories(this T toolSettings, params DotnetPackagingAdditionalCategory[] additionalCategories) where T : DotnetPackagingAppImageSettings + { + toolSettings = toolSettings.NewInstance(); + toolSettings.AdditionalCategoriesInternal = additionalCategories.ToList(); + return toolSettings; + } + /// + ///

    Sets to a new list

    + ///

    Additional categories for the application.

    + ///
    + [Pure] + public static T SetAdditionalCategories(this T toolSettings, IEnumerable additionalCategories) where T : DotnetPackagingAppImageSettings + { + toolSettings = toolSettings.NewInstance(); + toolSettings.AdditionalCategoriesInternal = additionalCategories.ToList(); + return toolSettings; + } + /// + ///

    Adds values to

    + ///

    Additional categories for the application.

    + ///
    + [Pure] + public static T AddAdditionalCategories(this T toolSettings, params DotnetPackagingAdditionalCategory[] additionalCategories) where T : DotnetPackagingAppImageSettings + { + toolSettings = toolSettings.NewInstance(); + toolSettings.AdditionalCategoriesInternal.AddRange(additionalCategories); + return toolSettings; + } + /// + ///

    Adds values to

    + ///

    Additional categories for the application.

    + ///
    + [Pure] + public static T AddAdditionalCategories(this T toolSettings, IEnumerable additionalCategories) where T : DotnetPackagingAppImageSettings + { + toolSettings = toolSettings.NewInstance(); + toolSettings.AdditionalCategoriesInternal.AddRange(additionalCategories); + return toolSettings; + } + /// + ///

    Clears

    + ///

    Additional categories for the application.

    + ///
    + [Pure] + public static T ClearAdditionalCategories(this T toolSettings) where T : DotnetPackagingAppImageSettings + { + toolSettings = toolSettings.NewInstance(); + toolSettings.AdditionalCategoriesInternal.Clear(); + return toolSettings; + } + /// + ///

    Removes values from

    + ///

    Additional categories for the application.

    + ///
    + [Pure] + public static T RemoveAdditionalCategories(this T toolSettings, params DotnetPackagingAdditionalCategory[] additionalCategories) where T : DotnetPackagingAppImageSettings + { + toolSettings = toolSettings.NewInstance(); + var hashSet = new HashSet(additionalCategories); + toolSettings.AdditionalCategoriesInternal.RemoveAll(x => hashSet.Contains(x)); + return toolSettings; + } + /// + ///

    Removes values from

    + ///

    Additional categories for the application.

    + ///
    + [Pure] + public static T RemoveAdditionalCategories(this T toolSettings, IEnumerable additionalCategories) where T : DotnetPackagingAppImageSettings + { + toolSettings = toolSettings.NewInstance(); + var hashSet = new HashSet(additionalCategories); + toolSettings.AdditionalCategoriesInternal.RemoveAll(x => hashSet.Contains(x)); + return toolSettings; + } + #endregion + #region Icon + /// + ///

    Sets

    + ///

    The icon path for the application. When not provided, the tool looks up for an image called AppImage.png.

    + ///
    + [Pure] + public static T SetIcon(this T toolSettings, string icon) where T : DotnetPackagingAppImageSettings + { + toolSettings = toolSettings.NewInstance(); + toolSettings.Icon = icon; + return toolSettings; + } + /// + ///

    Resets

    + ///

    The icon path for the application. When not provided, the tool looks up for an image called AppImage.png.

    + ///
    + [Pure] + public static T ResetIcon(this T toolSettings) where T : DotnetPackagingAppImageSettings + { + toolSettings = toolSettings.NewInstance(); + toolSettings.Icon = null; + return toolSettings; + } + #endregion + #region Homepage + /// + ///

    Sets

    + ///

    Home page of the application.

    + ///
    + [Pure] + public static T SetHomepage(this T toolSettings, string homepage) where T : DotnetPackagingAppImageSettings + { + toolSettings = toolSettings.NewInstance(); + toolSettings.Homepage = homepage; + return toolSettings; + } + /// + ///

    Resets

    + ///

    Home page of the application.

    + ///
    + [Pure] + public static T ResetHomepage(this T toolSettings) where T : DotnetPackagingAppImageSettings + { + toolSettings = toolSettings.NewInstance(); + toolSettings.Homepage = null; + return toolSettings; + } + #endregion + #region License + /// + ///

    Sets

    + ///

    License of the application.

    + ///
    + [Pure] + public static T SetLicense(this T toolSettings, string license) where T : DotnetPackagingAppImageSettings + { + toolSettings = toolSettings.NewInstance(); + toolSettings.License = license; + return toolSettings; + } + /// + ///

    Resets

    + ///

    License of the application.

    + ///
    + [Pure] + public static T ResetLicense(this T toolSettings) where T : DotnetPackagingAppImageSettings + { + toolSettings = toolSettings.NewInstance(); + toolSettings.License = null; + return toolSettings; + } + #endregion + #region Version + /// + ///

    Sets

    + ///

    Version of the application.

    + ///
    + [Pure] + public static T SetVersion(this T toolSettings, string version) where T : DotnetPackagingAppImageSettings + { + toolSettings = toolSettings.NewInstance(); + toolSettings.Version = version; + return toolSettings; + } + /// + ///

    Resets

    + ///

    Version of the application.

    + ///
    + [Pure] + public static T ResetVersion(this T toolSettings) where T : DotnetPackagingAppImageSettings + { + toolSettings = toolSettings.NewInstance(); + toolSettings.Version = null; + return toolSettings; + } + #endregion + #region ScreenshotUrls + /// + ///

    Sets to a new list

    + ///

    URLs of screenshots of the application.

    + ///
    + [Pure] + public static T SetScreenshotUrls(this T toolSettings, params string[] screenshotUrls) where T : DotnetPackagingAppImageSettings + { + toolSettings = toolSettings.NewInstance(); + toolSettings.ScreenshotUrlsInternal = screenshotUrls.ToList(); + return toolSettings; + } + /// + ///

    Sets to a new list

    + ///

    URLs of screenshots of the application.

    + ///
    + [Pure] + public static T SetScreenshotUrls(this T toolSettings, IEnumerable screenshotUrls) where T : DotnetPackagingAppImageSettings + { + toolSettings = toolSettings.NewInstance(); + toolSettings.ScreenshotUrlsInternal = screenshotUrls.ToList(); + return toolSettings; + } + /// + ///

    Adds values to

    + ///

    URLs of screenshots of the application.

    + ///
    + [Pure] + public static T AddScreenshotUrls(this T toolSettings, params string[] screenshotUrls) where T : DotnetPackagingAppImageSettings + { + toolSettings = toolSettings.NewInstance(); + toolSettings.ScreenshotUrlsInternal.AddRange(screenshotUrls); + return toolSettings; + } + /// + ///

    Adds values to

    + ///

    URLs of screenshots of the application.

    + ///
    + [Pure] + public static T AddScreenshotUrls(this T toolSettings, IEnumerable screenshotUrls) where T : DotnetPackagingAppImageSettings + { + toolSettings = toolSettings.NewInstance(); + toolSettings.ScreenshotUrlsInternal.AddRange(screenshotUrls); + return toolSettings; + } + /// + ///

    Clears

    + ///

    URLs of screenshots of the application.

    + ///
    + [Pure] + public static T ClearScreenshotUrls(this T toolSettings) where T : DotnetPackagingAppImageSettings + { + toolSettings = toolSettings.NewInstance(); + toolSettings.ScreenshotUrlsInternal.Clear(); + return toolSettings; + } + /// + ///

    Removes values from

    + ///

    URLs of screenshots of the application.

    + ///
    + [Pure] + public static T RemoveScreenshotUrls(this T toolSettings, params string[] screenshotUrls) where T : DotnetPackagingAppImageSettings + { + toolSettings = toolSettings.NewInstance(); + var hashSet = new HashSet(screenshotUrls); + toolSettings.ScreenshotUrlsInternal.RemoveAll(x => hashSet.Contains(x)); + return toolSettings; + } + /// + ///

    Removes values from

    + ///

    URLs of screenshots of the application.

    + ///
    + [Pure] + public static T RemoveScreenshotUrls(this T toolSettings, IEnumerable screenshotUrls) where T : DotnetPackagingAppImageSettings + { + toolSettings = toolSettings.NewInstance(); + var hashSet = new HashSet(screenshotUrls); + toolSettings.ScreenshotUrlsInternal.RemoveAll(x => hashSet.Contains(x)); + return toolSettings; + } + #endregion + #region Summary + /// + ///

    Sets

    + ///

    Short description of the application.

    + ///
    + [Pure] + public static T SetSummary(this T toolSettings, string summary) where T : DotnetPackagingAppImageSettings + { + toolSettings = toolSettings.NewInstance(); + toolSettings.Summary = summary; + return toolSettings; + } + /// + ///

    Resets

    + ///

    Short description of the application.

    + ///
    + [Pure] + public static T ResetSummary(this T toolSettings) where T : DotnetPackagingAppImageSettings + { + toolSettings = toolSettings.NewInstance(); + toolSettings.Summary = null; + return toolSettings; + } + #endregion + #region AppId + /// + ///

    Sets

    + ///

    Application ID, usually a reverse DNS name like com.SomeCompany.SomeApplication.

    + ///
    + [Pure] + public static T SetAppId(this T toolSettings, string appId) where T : DotnetPackagingAppImageSettings + { + toolSettings = toolSettings.NewInstance(); + toolSettings.AppId = appId; + return toolSettings; + } + /// + ///

    Resets

    + ///

    Application ID, usually a reverse DNS name like com.SomeCompany.SomeApplication.

    + ///
    + [Pure] + public static T ResetAppId(this T toolSettings) where T : DotnetPackagingAppImageSettings + { + toolSettings = toolSettings.NewInstance(); + toolSettings.AppId = null; + return toolSettings; + } + #endregion +} +#endregion +#region DotnetPackagingMainCategory +/// +/// Used within . +/// +[PublicAPI] +[Serializable] +[ExcludeFromCodeCoverage] +[TypeConverter(typeof(TypeConverter))] +public partial class DotnetPackagingMainCategory : Enumeration +{ + public static DotnetPackagingMainCategory AudioVideo = (DotnetPackagingMainCategory) "AudioVideo"; + public static DotnetPackagingMainCategory Audio = (DotnetPackagingMainCategory) "Audio"; + public static DotnetPackagingMainCategory Video = (DotnetPackagingMainCategory) "Video"; + public static DotnetPackagingMainCategory Development = (DotnetPackagingMainCategory) "Development"; + public static DotnetPackagingMainCategory Education = (DotnetPackagingMainCategory) "Education"; + public static DotnetPackagingMainCategory Game = (DotnetPackagingMainCategory) "Game"; + public static DotnetPackagingMainCategory Graphics = (DotnetPackagingMainCategory) "Graphics"; + public static DotnetPackagingMainCategory Network = (DotnetPackagingMainCategory) "Network"; + public static DotnetPackagingMainCategory Office = (DotnetPackagingMainCategory) "Office"; + public static DotnetPackagingMainCategory Settings = (DotnetPackagingMainCategory) "Settings"; + public static DotnetPackagingMainCategory Utility = (DotnetPackagingMainCategory) "Utility"; + public static implicit operator DotnetPackagingMainCategory(string value) + { + return new DotnetPackagingMainCategory { Value = value }; + } +} +#endregion +#region DotnetPackagingAdditionalCategory +/// +/// Used within . +/// +[PublicAPI] +[Serializable] +[ExcludeFromCodeCoverage] +[TypeConverter(typeof(TypeConverter))] +public partial class DotnetPackagingAdditionalCategory : Enumeration +{ + public static DotnetPackagingAdditionalCategory Building = (DotnetPackagingAdditionalCategory) "Building"; + public static DotnetPackagingAdditionalCategory Debugger = (DotnetPackagingAdditionalCategory) "Debugger"; + public static DotnetPackagingAdditionalCategory IDE = (DotnetPackagingAdditionalCategory) "IDE"; + public static DotnetPackagingAdditionalCategory GUIDesigner = (DotnetPackagingAdditionalCategory) "GUIDesigner"; + public static DotnetPackagingAdditionalCategory Profiling = (DotnetPackagingAdditionalCategory) "Profiling"; + public static DotnetPackagingAdditionalCategory RevisionControl = (DotnetPackagingAdditionalCategory) "RevisionControl"; + public static DotnetPackagingAdditionalCategory Translation = (DotnetPackagingAdditionalCategory) "Translation"; + public static DotnetPackagingAdditionalCategory Calendar = (DotnetPackagingAdditionalCategory) "Calendar"; + public static DotnetPackagingAdditionalCategory ContactManagement = (DotnetPackagingAdditionalCategory) "ContactManagement"; + public static DotnetPackagingAdditionalCategory Database = (DotnetPackagingAdditionalCategory) "Database"; + public static DotnetPackagingAdditionalCategory Dictionary = (DotnetPackagingAdditionalCategory) "Dictionary"; + public static DotnetPackagingAdditionalCategory Chart = (DotnetPackagingAdditionalCategory) "Chart"; + public static DotnetPackagingAdditionalCategory Email = (DotnetPackagingAdditionalCategory) "Email"; + public static DotnetPackagingAdditionalCategory Finance = (DotnetPackagingAdditionalCategory) "Finance"; + public static DotnetPackagingAdditionalCategory FlowChart = (DotnetPackagingAdditionalCategory) "FlowChart"; + public static DotnetPackagingAdditionalCategory PDA = (DotnetPackagingAdditionalCategory) "PDA"; + public static DotnetPackagingAdditionalCategory ProjectManagement = (DotnetPackagingAdditionalCategory) "ProjectManagement"; + public static DotnetPackagingAdditionalCategory Presentation = (DotnetPackagingAdditionalCategory) "Presentation"; + public static DotnetPackagingAdditionalCategory Spreadsheet = (DotnetPackagingAdditionalCategory) "Spreadsheet"; + public static DotnetPackagingAdditionalCategory WordProcessor = (DotnetPackagingAdditionalCategory) "WordProcessor"; + public static DotnetPackagingAdditionalCategory TwoDGraphics = (DotnetPackagingAdditionalCategory) "TwoDGraphics"; + public static DotnetPackagingAdditionalCategory VectorGraphics = (DotnetPackagingAdditionalCategory) "VectorGraphics"; + public static DotnetPackagingAdditionalCategory RasterGraphics = (DotnetPackagingAdditionalCategory) "RasterGraphics"; + public static DotnetPackagingAdditionalCategory ThreeDGraphics = (DotnetPackagingAdditionalCategory) "ThreeDGraphics"; + public static DotnetPackagingAdditionalCategory Scanning = (DotnetPackagingAdditionalCategory) "Scanning"; + public static DotnetPackagingAdditionalCategory OCR = (DotnetPackagingAdditionalCategory) "OCR"; + public static DotnetPackagingAdditionalCategory Photography = (DotnetPackagingAdditionalCategory) "Photography"; + public static DotnetPackagingAdditionalCategory Publishing = (DotnetPackagingAdditionalCategory) "Publishing"; + public static DotnetPackagingAdditionalCategory Viewer = (DotnetPackagingAdditionalCategory) "Viewer"; + public static DotnetPackagingAdditionalCategory TextTools = (DotnetPackagingAdditionalCategory) "TextTools"; + public static DotnetPackagingAdditionalCategory DesktopSettings = (DotnetPackagingAdditionalCategory) "DesktopSettings"; + public static DotnetPackagingAdditionalCategory HardwareSettings = (DotnetPackagingAdditionalCategory) "HardwareSettings"; + public static DotnetPackagingAdditionalCategory Printing = (DotnetPackagingAdditionalCategory) "Printing"; + public static DotnetPackagingAdditionalCategory PackageManager = (DotnetPackagingAdditionalCategory) "PackageManager"; + public static DotnetPackagingAdditionalCategory Dialup = (DotnetPackagingAdditionalCategory) "Dialup"; + public static DotnetPackagingAdditionalCategory InstantMessaging = (DotnetPackagingAdditionalCategory) "InstantMessaging"; + public static DotnetPackagingAdditionalCategory Chat = (DotnetPackagingAdditionalCategory) "Chat"; + public static DotnetPackagingAdditionalCategory IRCClient = (DotnetPackagingAdditionalCategory) "IRCClient"; + public static DotnetPackagingAdditionalCategory FileTransfer = (DotnetPackagingAdditionalCategory) "FileTransfer"; + public static DotnetPackagingAdditionalCategory HamRadio = (DotnetPackagingAdditionalCategory) "HamRadio"; + public static DotnetPackagingAdditionalCategory News = (DotnetPackagingAdditionalCategory) "News"; + public static DotnetPackagingAdditionalCategory P2P = (DotnetPackagingAdditionalCategory) "P2P"; + public static DotnetPackagingAdditionalCategory RemoteAccess = (DotnetPackagingAdditionalCategory) "RemoteAccess"; + public static DotnetPackagingAdditionalCategory Telephony = (DotnetPackagingAdditionalCategory) "Telephony"; + public static DotnetPackagingAdditionalCategory TelephonyTools = (DotnetPackagingAdditionalCategory) "TelephonyTools"; + public static DotnetPackagingAdditionalCategory VideoConference = (DotnetPackagingAdditionalCategory) "VideoConference"; + public static DotnetPackagingAdditionalCategory WebBrowser = (DotnetPackagingAdditionalCategory) "WebBrowser"; + public static DotnetPackagingAdditionalCategory WebDevelopment = (DotnetPackagingAdditionalCategory) "WebDevelopment"; + public static DotnetPackagingAdditionalCategory Midi = (DotnetPackagingAdditionalCategory) "Midi"; + public static DotnetPackagingAdditionalCategory Mixer = (DotnetPackagingAdditionalCategory) "Mixer"; + public static DotnetPackagingAdditionalCategory Sequencer = (DotnetPackagingAdditionalCategory) "Sequencer"; + public static DotnetPackagingAdditionalCategory Tuner = (DotnetPackagingAdditionalCategory) "Tuner"; + public static DotnetPackagingAdditionalCategory TV = (DotnetPackagingAdditionalCategory) "TV"; + public static DotnetPackagingAdditionalCategory AudioVideoEditing = (DotnetPackagingAdditionalCategory) "AudioVideoEditing"; + public static DotnetPackagingAdditionalCategory Player = (DotnetPackagingAdditionalCategory) "Player"; + public static DotnetPackagingAdditionalCategory Recorder = (DotnetPackagingAdditionalCategory) "Recorder"; + public static DotnetPackagingAdditionalCategory DiscBurning = (DotnetPackagingAdditionalCategory) "DiscBurning"; + public static DotnetPackagingAdditionalCategory ActionGame = (DotnetPackagingAdditionalCategory) "ActionGame"; + public static DotnetPackagingAdditionalCategory AdventureGame = (DotnetPackagingAdditionalCategory) "AdventureGame"; + public static DotnetPackagingAdditionalCategory ArcadeGame = (DotnetPackagingAdditionalCategory) "ArcadeGame"; + public static DotnetPackagingAdditionalCategory BoardGame = (DotnetPackagingAdditionalCategory) "BoardGame"; + public static DotnetPackagingAdditionalCategory BlocksGame = (DotnetPackagingAdditionalCategory) "BlocksGame"; + public static DotnetPackagingAdditionalCategory CardGame = (DotnetPackagingAdditionalCategory) "CardGame"; + public static DotnetPackagingAdditionalCategory KidsGame = (DotnetPackagingAdditionalCategory) "KidsGame"; + public static DotnetPackagingAdditionalCategory LogicGame = (DotnetPackagingAdditionalCategory) "LogicGame"; + public static DotnetPackagingAdditionalCategory RolePlaying = (DotnetPackagingAdditionalCategory) "RolePlaying"; + public static DotnetPackagingAdditionalCategory Simulation = (DotnetPackagingAdditionalCategory) "Simulation"; + public static DotnetPackagingAdditionalCategory SportsGame = (DotnetPackagingAdditionalCategory) "SportsGame"; + public static DotnetPackagingAdditionalCategory StrategyGame = (DotnetPackagingAdditionalCategory) "StrategyGame"; + public static DotnetPackagingAdditionalCategory Art = (DotnetPackagingAdditionalCategory) "Art"; + public static DotnetPackagingAdditionalCategory Construction = (DotnetPackagingAdditionalCategory) "Construction"; + public static DotnetPackagingAdditionalCategory Music = (DotnetPackagingAdditionalCategory) "Music"; + public static DotnetPackagingAdditionalCategory Languages = (DotnetPackagingAdditionalCategory) "Languages"; + public static DotnetPackagingAdditionalCategory Science = (DotnetPackagingAdditionalCategory) "Science"; + public static DotnetPackagingAdditionalCategory ArtificialIntelligence = (DotnetPackagingAdditionalCategory) "ArtificialIntelligence"; + public static DotnetPackagingAdditionalCategory Astronomy = (DotnetPackagingAdditionalCategory) "Astronomy"; + public static DotnetPackagingAdditionalCategory Biology = (DotnetPackagingAdditionalCategory) "Biology"; + public static DotnetPackagingAdditionalCategory Chemistry = (DotnetPackagingAdditionalCategory) "Chemistry"; + public static DotnetPackagingAdditionalCategory ComputerScience = (DotnetPackagingAdditionalCategory) "ComputerScience"; + public static DotnetPackagingAdditionalCategory DataVisualization = (DotnetPackagingAdditionalCategory) "DataVisualization"; + public static DotnetPackagingAdditionalCategory Economy = (DotnetPackagingAdditionalCategory) "Economy"; + public static DotnetPackagingAdditionalCategory Electricity = (DotnetPackagingAdditionalCategory) "Electricity"; + public static DotnetPackagingAdditionalCategory Geography = (DotnetPackagingAdditionalCategory) "Geography"; + public static DotnetPackagingAdditionalCategory Geology = (DotnetPackagingAdditionalCategory) "Geology"; + public static DotnetPackagingAdditionalCategory Geoscience = (DotnetPackagingAdditionalCategory) "Geoscience"; + public static DotnetPackagingAdditionalCategory History = (DotnetPackagingAdditionalCategory) "History"; + public static DotnetPackagingAdditionalCategory ImageProcessing = (DotnetPackagingAdditionalCategory) "ImageProcessing"; + public static DotnetPackagingAdditionalCategory Literature = (DotnetPackagingAdditionalCategory) "Literature"; + public static DotnetPackagingAdditionalCategory Math = (DotnetPackagingAdditionalCategory) "Math"; + public static DotnetPackagingAdditionalCategory NumericalAnalysis = (DotnetPackagingAdditionalCategory) "NumericalAnalysis"; + public static DotnetPackagingAdditionalCategory MedicalSoftware = (DotnetPackagingAdditionalCategory) "MedicalSoftware"; + public static DotnetPackagingAdditionalCategory Physics = (DotnetPackagingAdditionalCategory) "Physics"; + public static DotnetPackagingAdditionalCategory Robotics = (DotnetPackagingAdditionalCategory) "Robotics"; + public static DotnetPackagingAdditionalCategory Sports = (DotnetPackagingAdditionalCategory) "Sports"; + public static DotnetPackagingAdditionalCategory ParallelComputing = (DotnetPackagingAdditionalCategory) "ParallelComputing"; + public static DotnetPackagingAdditionalCategory Amusement = (DotnetPackagingAdditionalCategory) "Amusement"; + public static DotnetPackagingAdditionalCategory Archiving = (DotnetPackagingAdditionalCategory) "Archiving"; + public static DotnetPackagingAdditionalCategory Compression = (DotnetPackagingAdditionalCategory) "Compression"; + public static DotnetPackagingAdditionalCategory Electronics = (DotnetPackagingAdditionalCategory) "Electronics"; + public static DotnetPackagingAdditionalCategory Emulator = (DotnetPackagingAdditionalCategory) "Emulator"; + public static DotnetPackagingAdditionalCategory Engineering = (DotnetPackagingAdditionalCategory) "Engineering"; + public static DotnetPackagingAdditionalCategory FileTools = (DotnetPackagingAdditionalCategory) "FileTools"; + public static DotnetPackagingAdditionalCategory FileManager = (DotnetPackagingAdditionalCategory) "FileManager"; + public static DotnetPackagingAdditionalCategory TerminalEmulator = (DotnetPackagingAdditionalCategory) "TerminalEmulator"; + public static DotnetPackagingAdditionalCategory Filesystem = (DotnetPackagingAdditionalCategory) "Filesystem"; + public static DotnetPackagingAdditionalCategory Monitor = (DotnetPackagingAdditionalCategory) "Monitor"; + public static DotnetPackagingAdditionalCategory Security = (DotnetPackagingAdditionalCategory) "Security"; + public static DotnetPackagingAdditionalCategory Accessibility = (DotnetPackagingAdditionalCategory) "Accessibility"; + public static DotnetPackagingAdditionalCategory Calculator = (DotnetPackagingAdditionalCategory) "Calculator"; + public static DotnetPackagingAdditionalCategory Clock = (DotnetPackagingAdditionalCategory) "Clock"; + public static DotnetPackagingAdditionalCategory TextEditor = (DotnetPackagingAdditionalCategory) "TextEditor"; + public static DotnetPackagingAdditionalCategory Documentation = (DotnetPackagingAdditionalCategory) "Documentation"; + public static DotnetPackagingAdditionalCategory Core = (DotnetPackagingAdditionalCategory) "Core"; + public static DotnetPackagingAdditionalCategory KDE = (DotnetPackagingAdditionalCategory) "KDE"; + public static DotnetPackagingAdditionalCategory GNOME = (DotnetPackagingAdditionalCategory) "GNOME"; + public static DotnetPackagingAdditionalCategory GTK = (DotnetPackagingAdditionalCategory) "GTK"; + public static DotnetPackagingAdditionalCategory Qt = (DotnetPackagingAdditionalCategory) "Qt"; + public static DotnetPackagingAdditionalCategory Motif = (DotnetPackagingAdditionalCategory) "Motif"; + public static DotnetPackagingAdditionalCategory Java = (DotnetPackagingAdditionalCategory) "Java"; + public static DotnetPackagingAdditionalCategory ConsoleOnly = (DotnetPackagingAdditionalCategory) "ConsoleOnly"; + public static implicit operator DotnetPackagingAdditionalCategory(string value) + { + return new DotnetPackagingAdditionalCategory { Value = value }; + } +} +#endregion diff --git a/source/Nuke.Common/Tools/EntityFramework/EntityFramework.Generated.cs b/source/Nuke.Common/Tools/EntityFramework/EntityFramework.Generated.cs index 4e7504f0f..930b98249 100644 --- a/source/Nuke.Common/Tools/EntityFramework/EntityFramework.Generated.cs +++ b/source/Nuke.Common/Tools/EntityFramework/EntityFramework.Generated.cs @@ -23,17 +23,17 @@ namespace Nuke.Common.Tools.EntityFramework; ///
    [PublicAPI] [ExcludeFromCodeCoverage] -[PathToolRequirement(EntityFrameworkPathExecutable)] +[NuGetPackageRequirement(EntityFrameworkPackageId)] public partial class EntityFrameworkTasks - : IRequirePathTool + : IRequireNuGetPackage { - public const string EntityFrameworkPathExecutable = "dotnet"; + public const string EntityFrameworkPackageId = "dotnet-ef"; /// /// Path to the EntityFramework executable. /// public static string EntityFrameworkPath => ToolPathResolver.TryGetEnvironmentExecutable("ENTITYFRAMEWORK_EXE") ?? - ToolPathResolver.GetPathExecutable("dotnet"); + GetToolPath(); public static Action EntityFrameworkLogger { get; set; } = ProcessTasks.DefaultLogger; public static Action EntityFrameworkExitHandler { get; set; } = ProcessTasks.DefaultExitHandler; /// @@ -978,12 +978,12 @@ public static IReadOnlyCollection EntityFrameworkMigrationsScript(Config [PublicAPI] [ExcludeFromCodeCoverage] [Serializable] -public partial class EntityFrameworkDatabaseDropSettings : ToolSettings +public partial class EntityFrameworkDatabaseDropSettings : EntityFrameworkSettings { /// /// Path to the EntityFramework executable. /// - public override string ProcessToolPath => base.ProcessToolPath ?? EntityFrameworkTasks.EntityFrameworkPath; + public override string ProcessToolPath => base.ProcessToolPath ?? GetProcessToolPath(); public override Action ProcessLogger => base.ProcessLogger ?? EntityFrameworkTasks.EntityFrameworkLogger; public override Action ProcessExitHandler => base.ProcessExitHandler ?? EntityFrameworkTasks.EntityFrameworkExitHandler; /// @@ -1066,12 +1066,12 @@ protected override Arguments ConfigureProcessArguments(Arguments arguments) [PublicAPI] [ExcludeFromCodeCoverage] [Serializable] -public partial class EntityFrameworkDatabaseUpdateSettings : ToolSettings +public partial class EntityFrameworkDatabaseUpdateSettings : EntityFrameworkSettings { /// /// Path to the EntityFramework executable. /// - public override string ProcessToolPath => base.ProcessToolPath ?? EntityFrameworkTasks.EntityFrameworkPath; + public override string ProcessToolPath => base.ProcessToolPath ?? GetProcessToolPath(); public override Action ProcessLogger => base.ProcessLogger ?? EntityFrameworkTasks.EntityFrameworkLogger; public override Action ProcessExitHandler => base.ProcessExitHandler ?? EntityFrameworkTasks.EntityFrameworkExitHandler; /// @@ -1154,12 +1154,12 @@ protected override Arguments ConfigureProcessArguments(Arguments arguments) [PublicAPI] [ExcludeFromCodeCoverage] [Serializable] -public partial class EntityFrameworkDbContextInfoSettings : ToolSettings +public partial class EntityFrameworkDbContextInfoSettings : EntityFrameworkSettings { /// /// Path to the EntityFramework executable. /// - public override string ProcessToolPath => base.ProcessToolPath ?? EntityFrameworkTasks.EntityFrameworkPath; + public override string ProcessToolPath => base.ProcessToolPath ?? GetProcessToolPath(); public override Action ProcessLogger => base.ProcessLogger ?? EntityFrameworkTasks.EntityFrameworkLogger; public override Action ProcessExitHandler => base.ProcessExitHandler ?? EntityFrameworkTasks.EntityFrameworkExitHandler; /// @@ -1232,12 +1232,12 @@ protected override Arguments ConfigureProcessArguments(Arguments arguments) [PublicAPI] [ExcludeFromCodeCoverage] [Serializable] -public partial class EntityFrameworkDbContextListSettings : ToolSettings +public partial class EntityFrameworkDbContextListSettings : EntityFrameworkSettings { /// /// Path to the EntityFramework executable. /// - public override string ProcessToolPath => base.ProcessToolPath ?? EntityFrameworkTasks.EntityFrameworkPath; + public override string ProcessToolPath => base.ProcessToolPath ?? GetProcessToolPath(); public override Action ProcessLogger => base.ProcessLogger ?? EntityFrameworkTasks.EntityFrameworkLogger; public override Action ProcessExitHandler => base.ProcessExitHandler ?? EntityFrameworkTasks.EntityFrameworkExitHandler; /// @@ -1310,12 +1310,12 @@ protected override Arguments ConfigureProcessArguments(Arguments arguments) [PublicAPI] [ExcludeFromCodeCoverage] [Serializable] -public partial class EntityFrameworkDbContextScaffoldSettings : ToolSettings +public partial class EntityFrameworkDbContextScaffoldSettings : EntityFrameworkSettings { /// /// Path to the EntityFramework executable. /// - public override string ProcessToolPath => base.ProcessToolPath ?? EntityFrameworkTasks.EntityFrameworkPath; + public override string ProcessToolPath => base.ProcessToolPath ?? GetProcessToolPath(); public override Action ProcessLogger => base.ProcessLogger ?? EntityFrameworkTasks.EntityFrameworkLogger; public override Action ProcessExitHandler => base.ProcessExitHandler ?? EntityFrameworkTasks.EntityFrameworkExitHandler; /// @@ -1455,12 +1455,12 @@ protected override Arguments ConfigureProcessArguments(Arguments arguments) [PublicAPI] [ExcludeFromCodeCoverage] [Serializable] -public partial class EntityFrameworkDbContextScriptSettings : ToolSettings +public partial class EntityFrameworkDbContextScriptSettings : EntityFrameworkSettings { /// /// Path to the EntityFramework executable. /// - public override string ProcessToolPath => base.ProcessToolPath ?? EntityFrameworkTasks.EntityFrameworkPath; + public override string ProcessToolPath => base.ProcessToolPath ?? GetProcessToolPath(); public override Action ProcessLogger => base.ProcessLogger ?? EntityFrameworkTasks.EntityFrameworkLogger; public override Action ProcessExitHandler => base.ProcessExitHandler ?? EntityFrameworkTasks.EntityFrameworkExitHandler; /// @@ -1538,12 +1538,12 @@ protected override Arguments ConfigureProcessArguments(Arguments arguments) [PublicAPI] [ExcludeFromCodeCoverage] [Serializable] -public partial class EntityFrameworkMigrationsAddSettings : ToolSettings +public partial class EntityFrameworkMigrationsAddSettings : EntityFrameworkSettings { /// /// Path to the EntityFramework executable. /// - public override string ProcessToolPath => base.ProcessToolPath ?? EntityFrameworkTasks.EntityFrameworkPath; + public override string ProcessToolPath => base.ProcessToolPath ?? GetProcessToolPath(); public override Action ProcessLogger => base.ProcessLogger ?? EntityFrameworkTasks.EntityFrameworkLogger; public override Action ProcessExitHandler => base.ProcessExitHandler ?? EntityFrameworkTasks.EntityFrameworkExitHandler; /// @@ -1631,12 +1631,12 @@ protected override Arguments ConfigureProcessArguments(Arguments arguments) [PublicAPI] [ExcludeFromCodeCoverage] [Serializable] -public partial class EntityFrameworkMigrationsListSettings : ToolSettings +public partial class EntityFrameworkMigrationsListSettings : EntityFrameworkSettings { /// /// Path to the EntityFramework executable. /// - public override string ProcessToolPath => base.ProcessToolPath ?? EntityFrameworkTasks.EntityFrameworkPath; + public override string ProcessToolPath => base.ProcessToolPath ?? GetProcessToolPath(); public override Action ProcessLogger => base.ProcessLogger ?? EntityFrameworkTasks.EntityFrameworkLogger; public override Action ProcessExitHandler => base.ProcessExitHandler ?? EntityFrameworkTasks.EntityFrameworkExitHandler; /// @@ -1719,12 +1719,12 @@ protected override Arguments ConfigureProcessArguments(Arguments arguments) [PublicAPI] [ExcludeFromCodeCoverage] [Serializable] -public partial class EntityFrameworkMigrationsRemoveSettings : ToolSettings +public partial class EntityFrameworkMigrationsRemoveSettings : EntityFrameworkSettings { /// /// Path to the EntityFramework executable. /// - public override string ProcessToolPath => base.ProcessToolPath ?? EntityFrameworkTasks.EntityFrameworkPath; + public override string ProcessToolPath => base.ProcessToolPath ?? GetProcessToolPath(); public override Action ProcessLogger => base.ProcessLogger ?? EntityFrameworkTasks.EntityFrameworkLogger; public override Action ProcessExitHandler => base.ProcessExitHandler ?? EntityFrameworkTasks.EntityFrameworkExitHandler; /// @@ -1802,12 +1802,12 @@ protected override Arguments ConfigureProcessArguments(Arguments arguments) [PublicAPI] [ExcludeFromCodeCoverage] [Serializable] -public partial class EntityFrameworkMigrationsBundleSettings : ToolSettings +public partial class EntityFrameworkMigrationsBundleSettings : EntityFrameworkSettings { /// /// Path to the EntityFramework executable. /// - public override string ProcessToolPath => base.ProcessToolPath ?? EntityFrameworkTasks.EntityFrameworkPath; + public override string ProcessToolPath => base.ProcessToolPath ?? GetProcessToolPath(); public override Action ProcessLogger => base.ProcessLogger ?? EntityFrameworkTasks.EntityFrameworkLogger; public override Action ProcessExitHandler => base.ProcessExitHandler ?? EntityFrameworkTasks.EntityFrameworkExitHandler; /// @@ -1900,12 +1900,12 @@ protected override Arguments ConfigureProcessArguments(Arguments arguments) [PublicAPI] [ExcludeFromCodeCoverage] [Serializable] -public partial class EntityFrameworkMigrationsScriptSettings : ToolSettings +public partial class EntityFrameworkMigrationsScriptSettings : EntityFrameworkSettings { /// /// Path to the EntityFramework executable. /// - public override string ProcessToolPath => base.ProcessToolPath ?? EntityFrameworkTasks.EntityFrameworkPath; + public override string ProcessToolPath => base.ProcessToolPath ?? GetProcessToolPath(); public override Action ProcessLogger => base.ProcessLogger ?? EntityFrameworkTasks.EntityFrameworkLogger; public override Action ProcessExitHandler => base.ProcessExitHandler ?? EntityFrameworkTasks.EntityFrameworkExitHandler; /// From f6a60d5ecb4314525385b2852722f6597094baa9 Mon Sep 17 00:00:00 2001 From: Matthias Koch Date: Tue, 10 Sep 2024 02:55:49 +0200 Subject: [PATCH 55/56] chore: update settings.kts --- .teamcity/settings.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.teamcity/settings.kts b/.teamcity/settings.kts index 62b866404..c4b4ef5ae 100644 --- a/.teamcity/settings.kts +++ b/.teamcity/settings.kts @@ -65,7 +65,7 @@ project { text ( "env.SignPathSettings", label = "SignPathSettings", - value = "", + value = "SignPathSettings { OrganizationId = 0fdaf334-6910-41f4-83d2-e58e4cccb087, ProjectSlug = nuke, PolicySlug = release-signing }", allowEmpty = true, display = ParameterDisplay.NORMAL) text ( From f389c1768b1687c8875b58367d389adc7565ae4f Mon Sep 17 00:00:00 2001 From: Matthias Koch Date: Tue, 10 Sep 2024 02:56:30 +0200 Subject: [PATCH 56/56] chore: CHANGELOG.md for 8.1.0 --- CHANGELOG.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b73124504..db39c9f8c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). ## [vNext] + +## [8.1.0] / 2024-09-10 - Added schema generation with references for `build.schema.json` - Added deserialization of full objects from `parameters.json` - Added `AbsolutePath` extension methods for `AddUnixSymlink`, `Copy*`, `Move*`, `Rename*` @@ -1148,7 +1150,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - Added CLT tasks for Git - Fixed background color in console output -[vNext]: https://github.com/nuke-build/nuke/compare/8.0.0...HEAD +[vNext]: https://github.com/nuke-build/nuke/compare/8.1.0...HEAD +[8.1.0]: https://github.com/nuke-build/nuke/compare/8.0.0...8.1.0 [8.0.0]: https://github.com/nuke-build/nuke/compare/7.0.6...8.0.0 [7.0.6]: https://github.com/nuke-build/nuke/compare/7.0.5...7.0.6 [7.0.5]: https://github.com/nuke-build/nuke/compare/7.0.4...7.0.5