diff --git a/.build/Build.CI.cs b/.build/Build.CI.cs index 5916801d..60639973 100644 --- a/.build/Build.CI.cs +++ b/.build/Build.CI.cs @@ -3,6 +3,7 @@ using Nuke.Common.CI.GitHubActions; using Rocket.Surgery.Nuke.ContinuousIntegration; using Rocket.Surgery.Nuke.GithubActions; +using Rocket.Surgery.Nuke.Jobs; #pragma warning disable CA1050 diff --git a/.github/workflows/close-milestone.yml b/.github/workflows/close-milestone.yml index 4f1c0532..0ee5b122 100644 --- a/.github/workflows/close-milestone.yml +++ b/.github/workflows/close-milestone.yml @@ -58,10 +58,6 @@ jobs: uses: gittools/actions/gitversion/setup@v3.1.1 with: versionSpec: '6.1.0' - - name: 📲 Install GitReleaseManager - uses: gittools/actions/gitreleasemanager/setup@v3.1.1 - with: - versionSpec: '0.18.0' - name: 🔨 Use GitVersion id: gitversion uses: gittools/actions/gitversion/execute@v3.1.1 @@ -70,7 +66,6 @@ jobs: - name: Create Milestone env: GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}' - continue-on-error: true uses: WyriHaximus/github-action-create-milestone@v1 with: title: 'v${{ steps.gitversion.outputs.majorMinorPatch }}' @@ -79,6 +74,10 @@ jobs: with: default-label: ':sparkles: mysterious' github-token: '${{ secrets.GITHUB_TOKEN }}' + - name: 📲 Install GitReleaseManager + uses: gittools/actions/gitreleasemanager/setup@v3.1.1 + with: + versionSpec: '0.18.0' - name: Get Repo and Owner id: repository if: ${{ !github.event.release.prerelease && steps.gitversion.outputs.preReleaseTag == '' }} diff --git a/.github/workflows/draft-release.yml b/.github/workflows/draft-release.yml index e5e744bb..1acd6463 100644 --- a/.github/workflows/draft-release.yml +++ b/.github/workflows/draft-release.yml @@ -64,10 +64,6 @@ jobs: uses: gittools/actions/gitversion/setup@v3.1.1 with: versionSpec: '6.1.0' - - name: 📲 Install GitReleaseManager - uses: gittools/actions/gitreleasemanager/setup@v3.1.1 - with: - versionSpec: '0.18.0' - name: 🔨 Use GitVersion id: gitversion uses: gittools/actions/gitversion/execute@v3.1.1 @@ -89,8 +85,11 @@ jobs: with: allowUpdates: 'true' generateReleaseNotes: 'true' + updateOnlyUnreleased: 'true' draft: 'true' + omitBodyDuringUpdate: 'true' omitNameDuringUpdate: 'true' + omitDraftDuringUpdate: 'true' name: 'v${{ steps.gitversion.outputs.majorMinorPatch }}' tag: 'v${{ steps.gitversion.outputs.majorMinorPatch }}' token: '${{ secrets.RSG_BOT_TOKEN }}' diff --git a/.github/workflows/publish-nuget.yml b/.github/workflows/publish-nuget.yml index c481063b..041cdc4a 100644 --- a/.github/workflows/publish-nuget.yml +++ b/.github/workflows/publish-nuget.yml @@ -64,3 +64,4 @@ jobs: run: | dotnet nuget push **/*.nupkg --skip-duplicate -s nuget.org --api-key $ENV:ApiKey dotnet nuget push **/*.snupkg --skip-duplicate -s nuget.org --api-key $ENV:ApiKey + diff --git a/.github/workflows/update-milestone.yml b/.github/workflows/update-milestone.yml index 79c4958c..9841a446 100644 --- a/.github/workflows/update-milestone.yml +++ b/.github/workflows/update-milestone.yml @@ -60,10 +60,6 @@ jobs: uses: gittools/actions/gitversion/setup@v3.1.1 with: versionSpec: '6.1.0' - - name: 📲 Install GitReleaseManager - uses: gittools/actions/gitreleasemanager/setup@v3.1.1 - with: - versionSpec: '0.18.0' - name: 🔨 Use GitVersion id: gitversion uses: gittools/actions/gitversion/execute@v3.1.1 @@ -72,7 +68,6 @@ jobs: - name: Create Milestone env: GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}' - continue-on-error: true uses: WyriHaximus/github-action-create-milestone@v1 with: title: 'v${{ steps.gitversion.outputs.majorMinorPatch }}' diff --git a/src/Nuke/DotNetCore/ICanDotNetFormat.cs b/src/Nuke/DotNetCore/ICanDotNetFormat.cs index 84ef5f8f..ba9293ab 100644 --- a/src/Nuke/DotNetCore/ICanDotNetFormat.cs +++ b/src/Nuke/DotNetCore/ICanDotNetFormat.cs @@ -17,6 +17,23 @@ public interface ICanDotNetFormat : IHaveSolution, ICanLint, IHaveOutputLogs { private static Matcher? jbMatcher; private static Matcher? dnfMatcher; + private static readonly HashSet _dotNetFormatIncludedDiagnostics = new(StringComparer.OrdinalIgnoreCase); + + private static readonly HashSet _dotNetFormatExcludedDiagnostics = new(StringComparer.OrdinalIgnoreCase) + { + "RCS1060", + "RCS1110", + "RCS1250", + "RCS1163", + "CS1591", + "CS0108", + "CS0246", + "IDE1006", + "RCS1175", + "IDE0052", + "RCS1246", + "RCS1112" + }; /// /// The default severity to use for DotNetFormat @@ -31,26 +48,12 @@ public interface ICanDotNetFormat : IHaveSolution, ICanLint, IHaveOutputLogs /// /// A list of diagnostic ids to exclude from the dotnet format /// - public ImmutableArray DotNetFormatExcludedDiagnostics => - [ - "RCS1060", - "RCS1110", - "RCS1250", - "RCS1163", - "CS1591", - "CS0108", - "CS0246", - "IDE1006", - "RCS1175", - "IDE0052", - "RCS1246", - "RCS1112", - ]; + public HashSet DotNetFormatExcludedDiagnostics => _dotNetFormatExcludedDiagnostics; /// /// A list of diagnostic ids to include in the dotnet format /// - public ImmutableArray? DotNetFormatIncludedDiagnostics => null; + public HashSet? DotNetFormatIncludedDiagnostics => _dotNetFormatIncludedDiagnostics; /// /// The dotnet format target @@ -64,23 +67,25 @@ public interface ICanDotNetFormat : IHaveSolution, ICanLint, IHaveOutputLogs .Executes( () => { - var formatSettings = new DotNetFormatSettings() .SetSeverity(DotNetFormatSeverity) .SetVerbosity(Verbosity.MapVerbosity(DotNetVerbosity.normal)) .EnableNoRestore() .SetBinaryLog(LogsDirectory / "dotnet-format.binlog") + ; - ; - - if (DotNetFormatIncludedDiagnostics is { Length: > 0 }) + if (DotNetFormatIncludedDiagnostics is { Count: > 0 }) { - formatSettings = formatSettings.SetProcessAdditionalArguments(["--diagnostics", .. DotNetFormatIncludedDiagnostics.Value]); + formatSettings = formatSettings.SetProcessAdditionalArguments( + ["--diagnostics", .. DotNetFormatIncludedDiagnostics] + ); } - if (DotNetFormatExcludedDiagnostics is { Length: > 0 }) + if (DotNetFormatExcludedDiagnostics is { Count: > 0 }) { - formatSettings = formatSettings.SetProcessAdditionalArguments(["--exclude-diagnostics", .. DotNetFormatExcludedDiagnostics]); + formatSettings = formatSettings.SetProcessAdditionalArguments( + ["--exclude-diagnostics", .. DotNetFormatExcludedDiagnostics] + ); } if (LintPaths.Glob(DotnetFormatMatcher) is { Count: > 0 } values) diff --git a/src/Nuke/GithubActions/CloseMilestoneJobAttribute.cs b/src/Nuke/GithubActions/CloseMilestoneJobAttribute.cs deleted file mode 100644 index 793b58ff..00000000 --- a/src/Nuke/GithubActions/CloseMilestoneJobAttribute.cs +++ /dev/null @@ -1,150 +0,0 @@ -using System.Diagnostics; -using Nuke.Common.CI; -using Nuke.Common.CI.GitHubActions; -using Nuke.Common.Execution; - -namespace Rocket.Surgery.Nuke.GithubActions; - -/// -/// Adds draft release support to the build -/// -[PublicAPI] -[AttributeUsage(AttributeTargets.Class)] -[DebuggerDisplay("{DebuggerDisplay,nq}")] -public sealed class CloseMilestoneJobAttribute : GitHubActionsStepsAttribute -{ - /// - /// Adds draft release support to the build - /// - public CloseMilestoneJobAttribute() : base("close-milestone", GitHubActionsImage.UbuntuLatest) { } - - /// - /// Adds draft release support to the build - /// - public CloseMilestoneJobAttribute(string image, params string[] images) : base("close-milestone", image, images) { } - - /// - /// Adds draft release support to the build - /// - public CloseMilestoneJobAttribute(GitHubActionsImage image) : base("close-milestone", image) { } - - private string DebuggerDisplay => ToString(); - - /// - public override ConfigurationEntity GetConfiguration(IReadOnlyCollection relevantTargets) - { - var build = new RocketSurgeonGitHubActionsConfiguration - { - Name = "Close Milestone" - }; - build.DetailedTriggers.Add( - new RocketSurgeonGitHubActionsWorkflowTrigger - { - Kind = RocketSurgeonGitHubActionsTrigger.WorkflowCall, - Secrets = [new GitHubActionsSecret("RSG_BOT_TOKEN", Required: true)], - } - ); - build.DetailedTriggers.Add( - new RocketSurgeonGitHubActionsVcsTrigger - { - Kind = RocketSurgeonGitHubActionsTrigger.Release, - Types = ["released"], - } - ); - build.Jobs.Add( - new RocketSurgeonsGithubActionsJob("close_milestone") - { - RunsOn = ( !IsGithubHosted ) ? Images : [], - Matrix = IsGithubHosted ? Images : [], - Steps = - [ - new CheckoutStep("Checkout") - { - FetchDepth = 0, - }, - new RunStep("Fetch all history for all tags and branches") - { - Run = "git fetch --prune", - }, - new SetupDotNetStep("Install DotNet"), - new RunStep("dotnet tool restore") - { - Run = "dotnet tool restore", - }, - new UsingStep("Install GitVersion") - { - Uses = "gittools/actions/gitversion/setup@v3.1.1", - With = - { - ["versionSpec"] = DotNetTool.GetToolDefinition("GitVersion.Tool").Version - }, - }, - new UsingStep("Install GitReleaseManager") - { - Uses = "gittools/actions/gitreleasemanager/setup@v3.1.1", - With = - { - ["versionSpec"] = DotNetTool.GetToolDefinition("GitReleaseManager.Tool").Version - }, - }, - new UsingStep("Use GitVersion") - { - Id = "gitversion", - Uses = "gittools/actions/gitversion/execute@v3.1.1", - With = - { - ["useConfigFile"] = "true", - } - }, - new UsingStep("Create Milestone") - { - Uses = "WyriHaximus/github-action-create-milestone@v1", - With = - { - ["title"] = "v${{ steps.gitversion.outputs.majorMinorPatch }}" - }, - Environment = - { - ["GITHUB_TOKEN"] = "${{ secrets.GITHUB_TOKEN }}" - }, - ContinueOnError = true, - }, - new UsingStep("sync milestones") - { - Uses = "RocketSurgeonsGuild/actions/sync-milestone@v0.3.15", - With = - { - ["default-label"] = ":sparkles: mysterious", - ["github-token"] = "${{ secrets.GITHUB_TOKEN }}" - }, - }, - new RunStep("Get Repo and Owner") - { - Shell = "pwsh", - Id = "repository", - If = "${{ !github.event.release.prerelease && steps.gitversion.outputs.preReleaseTag == '' }}", - Run = """ - $parts = $ENV:GITHUB_REPOSITORY.Split('/') - echo "::set-output name=owner::$($parts[0])" - echo "::set-output name=repository::$($parts[1])" - """ - }, - new RunStep("Close Milestone") - { - Shell = "pwsh", - If = "${{ !github.event.release.prerelease && steps.gitversion.outputs.preReleaseTag == '' }}", - Run = """ - dotnet gitreleasemanager close ` - -o "${{ steps.repository.outputs.owner }}" ` - -r "${{ steps.repository.outputs.repository }}" ` - --token "${{ secrets.GITHUB_TOKEN }}" ` - -m "v${{ steps.gitversion.outputs.majorMinorPatch }}" - """ - }, - ] - } - ); - - return build; - } -} diff --git a/src/Nuke/GithubActions/DraftReleaseJobAttribute.cs b/src/Nuke/GithubActions/DraftReleaseJobAttribute.cs deleted file mode 100644 index 2bba7e5a..00000000 --- a/src/Nuke/GithubActions/DraftReleaseJobAttribute.cs +++ /dev/null @@ -1,129 +0,0 @@ -using System.Diagnostics; -using Nuke.Common.CI; -using Nuke.Common.CI.GitHubActions; -using Nuke.Common.CI.GitHubActions.Configuration; -using Nuke.Common.Execution; - -namespace Rocket.Surgery.Nuke.GithubActions; - -/// -/// Adds draft release support to the build -/// -[PublicAPI] -[AttributeUsage(AttributeTargets.Class)] -[DebuggerDisplay("{DebuggerDisplay,nq}")] -public sealed class DraftReleaseJobAttribute() : GitHubActionsStepsAttribute("draft-release", GitHubActionsImage.UbuntuLatest) -{ - private string DebuggerDisplay => ToString(); - - /// - public override ConfigurationEntity GetConfiguration(IReadOnlyCollection relevantTargets) - { - var build = new RocketSurgeonGitHubActionsConfiguration - { - Name = "Draft Release and Create Milestone" - }; - build.DetailedTriggers.Add( - new RocketSurgeonGitHubActionsWorkflowTrigger - { - Kind = RocketSurgeonGitHubActionsTrigger.WorkflowCall, - Secrets = [new GitHubActionsSecret("RSG_BOT_TOKEN", Required: true)], - } - ); - build.DetailedTriggers.Add( - new RocketSurgeonGitHubActionsVcsTrigger - { - Kind = RocketSurgeonGitHubActionsTrigger.Push, - Branches = ["master"], - ExcludePaths = ["**/*.md"], - } - ); - build.DetailedTriggers.Add(new GitHubActionsScheduledTrigger { Cron = "0 0 * * 4" }); - build.Jobs.Add( - new RocketSurgeonsGithubActionsJob("draft_release") - { - RunsOn = ( !IsGithubHosted ) ? Images : [], - Matrix = IsGithubHosted ? Images : [], - Steps = - [ - new CheckoutStep("Checkout") - { - FetchDepth = 0, - }, - new RunStep("Fetch all history for all tags and branches") - { - Run = "git fetch --prune", - }, - new SetupDotNetStep("Install DotNet"), - new RunStep("dotnet tool restore") - { - Run = "dotnet tool restore", - }, - new UsingStep("Install GitVersion") - { - Uses = "gittools/actions/gitversion/setup@v3.1.1", - With = - { - ["versionSpec"] = DotNetTool.GetToolDefinition("GitVersion.Tool").Version - }, - }, - new UsingStep("Install GitReleaseManager") - { - Uses = "gittools/actions/gitreleasemanager/setup@v3.1.1", - With = - { - ["versionSpec"] = DotNetTool.GetToolDefinition("GitReleaseManager.Tool").Version - }, - }, - new UsingStep("Use GitVersion") - { - Id = "gitversion", - Uses = "gittools/actions/gitversion/execute@v3.1.1", - With = - { - ["useConfigFile"] = "true", - } - }, - new UsingStep("Create Milestone") - { - Uses = "WyriHaximus/github-action-create-milestone@v1", - With = - { - ["title"] = "v${{ steps.gitversion.outputs.majorMinorPatch }}" - }, - Environment = - { - ["GITHUB_TOKEN"] = "${{ secrets.GITHUB_TOKEN }}" - }, - }, - new UsingStep("sync milestones") - { - Uses = "RocketSurgeonsGuild/actions/sync-milestone@v0.3.15", - With = - { - ["default-label"] = ":sparkles: mysterious", - ["github-token"] = "${{ secrets.GITHUB_TOKEN }}" - } - }, - - new UsingStep("Create Release") - { - Uses = "ncipollo/release-action@v1", - With = - { - ["allowUpdates"] = "true", ["generateReleaseNotes"] = "true", - ["draft"] = "true", - ["omitNameDuringUpdate"] = "true", - ["name"] = "v${{ steps.gitversion.outputs.majorMinorPatch }}", - ["tag"] = "v${{ steps.gitversion.outputs.majorMinorPatch }}", - ["token"] = "${{ secrets.RSG_BOT_TOKEN }}", - ["commit"] = "${{ github.base_ref }}" - }, - }, - ] - } - ); - - return build; - } -} diff --git a/src/Nuke/GithubActions/UpdateMilestoneJobAttribute.cs b/src/Nuke/GithubActions/UpdateMilestoneJobAttribute.cs deleted file mode 100644 index d23f5bc0..00000000 --- a/src/Nuke/GithubActions/UpdateMilestoneJobAttribute.cs +++ /dev/null @@ -1,106 +0,0 @@ -using System.Diagnostics; -using Nuke.Common.CI; -using Nuke.Common.CI.GitHubActions; -using Nuke.Common.Execution; - -namespace Rocket.Surgery.Nuke.GithubActions; - -/// -/// Adds update milestone support to the build -/// -[PublicAPI] -[AttributeUsage(AttributeTargets.Class)] -[DebuggerDisplay("{DebuggerDisplay,nq}")] -public sealed class UpdateMilestoneJobAttribute() : GitHubActionsStepsAttribute("update-milestone", GitHubActionsImage.UbuntuLatest) -{ - private string DebuggerDisplay => ToString(); - - /// - public override ConfigurationEntity GetConfiguration(IReadOnlyCollection relevantTargets) - { - var build = new RocketSurgeonGitHubActionsConfiguration - { - Name = "Update Milestone" - }; - build.DetailedTriggers.Add(new RocketSurgeonGitHubActionsWorkflowTrigger()); - build.DetailedTriggers.Add( - new RocketSurgeonGitHubActionsVcsTrigger - { - Kind = RocketSurgeonGitHubActionsTrigger.PullRequestTarget, - Types = ["closed", "opened", "reopened", "synchronize"], - } - ); - build.Jobs.Add( - new RocketSurgeonsGithubActionsJob("update_milestone") - { - RunsOn = ( !IsGithubHosted ) ? Images : [], - Matrix = IsGithubHosted ? Images : [], - Steps = - [ - new CheckoutStep("Checkout") - { - FetchDepth = 0, - }, - new RunStep("Fetch all history for all tags and branches") - { - Run = "git fetch --prune", - }, - new SetupDotNetStep("Install DotNet"), - new RunStep("dotnet tool restore") - { - Run = "dotnet tool restore", - }, - new UsingStep("Install GitVersion") - { - Uses = "gittools/actions/gitversion/setup@v3.1.1", - With = - { - ["versionSpec"] = DotNetTool.GetToolDefinition("GitVersion.Tool").Version - }, - }, - new UsingStep("Install GitReleaseManager") - { - Uses = "gittools/actions/gitreleasemanager/setup@v3.1.1", - With = - { - ["versionSpec"] = DotNetTool.GetToolDefinition("GitReleaseManager.Tool").Version - }, - }, - new UsingStep("Use GitVersion") - { - Id = "gitversion", - Uses = "gittools/actions/gitversion/execute@v3.1.1", - With = - { - ["useConfigFile"] = "true", - } - }, - new UsingStep("Create Milestone") - { - Uses = "WyriHaximus/github-action-create-milestone@v1", - With = - { - ["title"] = "v${{ steps.gitversion.outputs.majorMinorPatch }}" - }, - Environment = - { - ["GITHUB_TOKEN"] = "${{ secrets.GITHUB_TOKEN }}" - }, - ContinueOnError = true, - }, - new UsingStep("sync milestones") - { - Uses = "RocketSurgeonsGuild/actions/sync-milestone@v0.3.15", - With = - { - ["default-label"] = ":sparkles: mysterious", - ["github-token"] = "${{ secrets.GITHUB_TOKEN }}" - }, - }, - ] - } - ); - - return build; - } -} diff --git a/src/Nuke/Jobs/CloseMilestoneJobAttribute.cs b/src/Nuke/Jobs/CloseMilestoneJobAttribute.cs new file mode 100644 index 00000000..90329344 --- /dev/null +++ b/src/Nuke/Jobs/CloseMilestoneJobAttribute.cs @@ -0,0 +1,92 @@ +using System.Diagnostics; +using Nuke.Common.CI; +using Nuke.Common.CI.GitHubActions; +using Nuke.Common.Execution; +using Rocket.Surgery.Nuke.GithubActions; + +namespace Rocket.Surgery.Nuke.Jobs; + +/// +/// Adds draft release support to the build +/// +[PublicAPI] +[AttributeUsage(AttributeTargets.Class)] +[DebuggerDisplay("{DebuggerDisplay,nq}")] +public sealed class CloseMilestoneJobAttribute : GitHubActionsStepsAttribute +{ + /// + /// Adds draft release support to the build + /// + public CloseMilestoneJobAttribute() : base("close-milestone", GitHubActionsImage.UbuntuLatest) { } + + /// + /// Adds draft release support to the build + /// + public CloseMilestoneJobAttribute(string image, params string[] images) : base("close-milestone", image, images) { } + + /// + /// Adds draft release support to the build + /// + public CloseMilestoneJobAttribute(GitHubActionsImage image) : base("close-milestone", image) { } + + private string DebuggerDisplay => ToString(); + + /// + public override ConfigurationEntity GetConfiguration(IReadOnlyCollection relevantTargets) + { + var build = new RocketSurgeonGitHubActionsConfiguration + { + Name = "Close Milestone" + }; + build.DetailedTriggers.Add( + new RocketSurgeonGitHubActionsWorkflowTrigger + { + Kind = RocketSurgeonGitHubActionsTrigger.WorkflowCall, + Secrets = [new GitHubActionsSecret("RSG_BOT_TOKEN", Required: true)], + } + ); + build.DetailedTriggers.Add( + new RocketSurgeonGitHubActionsVcsTrigger + { + Kind = RocketSurgeonGitHubActionsTrigger.Release, + Types = ["released"], + } + ); + var job = this.CreateJob( + "close_milestone", + true, + [ + ..WorkflowHelpers.RunGitVersion(), + ..WorkflowHelpers.CreateMilestone(), + ..WorkflowHelpers.SyncMilestones(), + ..WorkflowHelpers.InstallGitReleaseManager(), + new RunStep("Get Repo and Owner") + { + Shell = "pwsh", + Id = "repository", + If = "${{ !github.event.release.prerelease && steps.gitversion.outputs.preReleaseTag == '' }}", + Run = """ + $parts = $ENV:GITHUB_REPOSITORY.Split('/') + echo "::set-output name=owner::$($parts[0])" + echo "::set-output name=repository::$($parts[1])" + """ + }, + new RunStep("Close Milestone") + { + Shell = "pwsh", + If = "${{ !github.event.release.prerelease && steps.gitversion.outputs.preReleaseTag == '' }}", + Run = """ + dotnet gitreleasemanager close ` + -o "${{ steps.repository.outputs.owner }}" ` + -r "${{ steps.repository.outputs.repository }}" ` + --token "${{ secrets.GITHUB_TOKEN }}" ` + -m "v${{ steps.gitversion.outputs.majorMinorPatch }}" + """ + } + ] + ); + build.Jobs.Add(job); + + return build; + } +} diff --git a/src/Nuke/Jobs/DraftReleaseJobAttribute.cs b/src/Nuke/Jobs/DraftReleaseJobAttribute.cs new file mode 100644 index 00000000..d97fbefa --- /dev/null +++ b/src/Nuke/Jobs/DraftReleaseJobAttribute.cs @@ -0,0 +1,74 @@ +using System.Diagnostics; +using Nuke.Common.CI; +using Nuke.Common.CI.GitHubActions; +using Nuke.Common.CI.GitHubActions.Configuration; +using Nuke.Common.Execution; +using Rocket.Surgery.Nuke.GithubActions; + +namespace Rocket.Surgery.Nuke.Jobs; + +/// +/// Adds draft release support to the build +/// +[PublicAPI] +[AttributeUsage(AttributeTargets.Class)] +[DebuggerDisplay("{DebuggerDisplay,nq}")] +public sealed class DraftReleaseJobAttribute() : GitHubActionsStepsAttribute("draft-release", GitHubActionsImage.UbuntuLatest) +{ + private string DebuggerDisplay => ToString(); + + /// + public override ConfigurationEntity GetConfiguration(IReadOnlyCollection relevantTargets) + { + var build = new RocketSurgeonGitHubActionsConfiguration + { + Name = "Draft Release and Create Milestone" + }; + build.DetailedTriggers.Add( + new RocketSurgeonGitHubActionsWorkflowTrigger + { + Kind = RocketSurgeonGitHubActionsTrigger.WorkflowCall, + Secrets = [new GitHubActionsSecret("RSG_BOT_TOKEN", Required: true)], + } + ); + build.DetailedTriggers.Add( + new RocketSurgeonGitHubActionsVcsTrigger + { + Kind = RocketSurgeonGitHubActionsTrigger.Push, + Branches = ["master"], + ExcludePaths = ["**/*.md"], + } + ); + build.DetailedTriggers.Add(new GitHubActionsScheduledTrigger { Cron = "0 0 * * 4" }); + var job = this.CreateJob( + "draft_release", + true, + [ + ..WorkflowHelpers.RunGitVersion(), + ..WorkflowHelpers.CreateMilestone(), + ..WorkflowHelpers.SyncMilestones(), + new UsingStep("Create Release") + { + Uses = "ncipollo/release-action@v1", + With = + { + ["allowUpdates"] = "true", + ["generateReleaseNotes"] = "true", + ["updateOnlyUnreleased"] = "true", + ["draft"] = "true", + ["omitBodyDuringUpdate"] = "true", + ["omitNameDuringUpdate"] = "true", + ["omitDraftDuringUpdate"] = "true", + ["name"] = "v${{ steps.gitversion.outputs.majorMinorPatch }}", + ["tag"] = "v${{ steps.gitversion.outputs.majorMinorPatch }}", + ["token"] = "${{ secrets.RSG_BOT_TOKEN }}", + ["commit"] = "${{ github.base_ref }}" + }, + } + ] + ); + build.Jobs.Add(job); + + return build; + } +} diff --git a/src/Nuke/GithubActions/PublishNugetPackagesJobAttribute.cs b/src/Nuke/Jobs/PublishNugetPackagesJobAttribute.cs similarity index 80% rename from src/Nuke/GithubActions/PublishNugetPackagesJobAttribute.cs rename to src/Nuke/Jobs/PublishNugetPackagesJobAttribute.cs index b0d345bd..3ff6d923 100644 --- a/src/Nuke/GithubActions/PublishNugetPackagesJobAttribute.cs +++ b/src/Nuke/Jobs/PublishNugetPackagesJobAttribute.cs @@ -3,8 +3,11 @@ using Nuke.Common.CI; using Nuke.Common.CI.GitHubActions; using Nuke.Common.Execution; +using Rocket.Surgery.Nuke.GithubActions; -namespace Rocket.Surgery.Nuke.GithubActions; +#pragma warning disable RS0026, RS0027 + +namespace Rocket.Surgery.Nuke.Jobs; /// /// Adds close milestone support to the build @@ -16,35 +19,39 @@ public sealed class PublishNugetPackagesJobAttribute : GitHubActionsStepsAttribu { private readonly string _secretKey; private readonly string _triggeringWorkflow; + private readonly GithubActionCondition _nugetOrgCondition; private readonly ImmutableArray _includeBranches; /// /// Adds draft release support to the build /// - public PublishNugetPackagesJobAttribute(string secretKey, string triggeringWorkflow, string[]? includeBranches = null) : base("publish-nuget", GitHubActionsImage.UbuntuLatest) + public PublishNugetPackagesJobAttribute(string secretKey, string triggeringWorkflow, string[]? includeBranches = null, string? nugetOrgCondition = null) : base("publish-nuget", GitHubActionsImage.UbuntuLatest) { _secretKey = secretKey; _triggeringWorkflow = triggeringWorkflow; + _nugetOrgCondition = nugetOrgCondition ?? "startsWith(github.ref, 'refs/tags/')"; _includeBranches = [.. includeBranches ?? ["master", "main"]]; } /// /// Adds draft release support to the build /// - public PublishNugetPackagesJobAttribute(string secretKey, string triggeringWorkflow, string[] includeBranches, string image, params string[] images) : base("publish-nuget", image, images) + public PublishNugetPackagesJobAttribute(string secretKey, string triggeringWorkflow, string[] includeBranches, string? nugetOrgCondition, string image, params string[] images) : base("publish-nuget", image, images) { _secretKey = secretKey; _triggeringWorkflow = triggeringWorkflow; + _nugetOrgCondition = nugetOrgCondition ?? "startsWith(github.ref, 'refs/tags/')"; _includeBranches = [.. includeBranches]; } /// /// Adds draft release support to the build /// - public PublishNugetPackagesJobAttribute(string secretKey, string triggeringWorkflow, GitHubActionsImage image, string[]? includeBranches = null) : base("publish-nuget", image) + public PublishNugetPackagesJobAttribute(string secretKey, string triggeringWorkflow, GitHubActionsImage image, string[]? includeBranches = null, string? nugetOrgCondition = null) : base("publish-nuget", image) { _secretKey = secretKey; _triggeringWorkflow = triggeringWorkflow; + _nugetOrgCondition = nugetOrgCondition ?? "startsWith(github.ref, 'refs/tags/')"; _includeBranches = [.. includeBranches ?? ["master", "main"]]; } @@ -88,7 +95,7 @@ public override ConfigurationEntity GetConfiguration(IReadOnlyCollection +/// Adds update milestone support to the build +/// +[PublicAPI] +[AttributeUsage(AttributeTargets.Class)] +[DebuggerDisplay("{DebuggerDisplay,nq}")] +public sealed class UpdateMilestoneJobAttribute() : GitHubActionsStepsAttribute("update-milestone", GitHubActionsImage.UbuntuLatest) +{ + private string DebuggerDisplay => ToString(); + + /// + public override ConfigurationEntity GetConfiguration(IReadOnlyCollection relevantTargets) + { + var build = new RocketSurgeonGitHubActionsConfiguration + { + Name = "Update Milestone" + }; + build.DetailedTriggers.Add(new RocketSurgeonGitHubActionsWorkflowTrigger()); + build.DetailedTriggers.Add( + new RocketSurgeonGitHubActionsVcsTrigger + { + Kind = RocketSurgeonGitHubActionsTrigger.PullRequestTarget, + Types = ["closed", "opened", "reopened", "synchronize"], + } + ); + var job = this.CreateJob( + "update_milestone", + true, + [ + ..WorkflowHelpers.RunGitVersion(), + ..WorkflowHelpers.CreateMilestone(), + ..WorkflowHelpers.SyncMilestones(), + ] + ); + build.Jobs.Add(job); + + return build; + } +} diff --git a/src/Nuke/Jobs/WorkflowHelpers.cs b/src/Nuke/Jobs/WorkflowHelpers.cs new file mode 100644 index 00000000..c20a6d58 --- /dev/null +++ b/src/Nuke/Jobs/WorkflowHelpers.cs @@ -0,0 +1,140 @@ +using Rocket.Surgery.Nuke.GithubActions; + +namespace Rocket.Surgery.Nuke.Jobs; + +/// +/// Common helpers for creating github workflows +/// +public static class WorkflowHelpers +{ + /// + /// Create a job with the correct runson matrix + /// + /// + /// + /// + /// + /// + public static RocketSurgeonsGithubActionsJob CreateJob( + this GitHubActionsStepsAttribute attribute, + string name, + bool fetchHistory = false, + params IEnumerable steps + ) + { + return new(name) + { + RunsOn = ( !attribute.IsGithubHosted ) ? attribute.Images : [], + Matrix = ( attribute.IsGithubHosted ) ? attribute.Images : [], + Steps = + [ + new CheckoutStep("Checkout") + { + FetchDepth = fetchHistory ? 0 : null, + }, + ..fetchHistory + ? + [ + new RunStep("Fetch all history for all tags and branches") + { + Run = "git fetch --prune", + } + ] + : Array.Empty(), + new SetupDotNetStep("Install DotNet"), + new RunStep("dotnet tool restore") + { + Run = "dotnet tool restore", + }, + ..steps + ] + }; + } + + /// + /// Install the git release manager + /// + /// + /// + public static IEnumerable InstallGitReleaseManager(GithubActionCondition? condition = null) + { + yield return new UsingStep("Install GitReleaseManager") + { + If = condition, + Uses = "gittools/actions/gitreleasemanager/setup@v3.1.1", + With = + { + ["versionSpec"] = DotNetTool.GetToolDefinition("GitReleaseManager.Tool").Version + }, + }; + } + + /// + /// Create a milestone + /// + /// + /// + public static IEnumerable CreateMilestone(GithubActionCondition? condition = null) + { + yield return new UsingStep("Create Milestone") + { + If = condition, + Uses = "WyriHaximus/github-action-create-milestone@v1", + With = + { + ["title"] = "v${{ steps.gitversion.outputs.majorMinorPatch }}" + }, + Environment = + { + ["GITHUB_TOKEN"] = "${{ secrets.GITHUB_TOKEN }}" + }, + }; + } + + /// + /// Sync the milestones + /// + /// + /// + public static IEnumerable SyncMilestones(GithubActionCondition? condition = null) + { + yield return new UsingStep("sync milestones") + { + If = condition, + Uses = "RocketSurgeonsGuild/actions/sync-milestone@v0.3.15", + With = + { + ["default-label"] = ":sparkles: mysterious", + ["github-token"] = "${{ secrets.GITHUB_TOKEN }}" + } + }; + } + + /// + /// Run gitversion + /// + /// + /// + public static IEnumerable RunGitVersion(GithubActionCondition? condition = null) + { + yield return new UsingStep("Install GitVersion") + { + If = condition, + Uses = "gittools/actions/gitversion/setup@v3.1.1", + With = + { + ["versionSpec"] = DotNetTool.GetToolDefinition("GitVersion.Tool").Version + }, + }; + yield return new UsingStep("Use GitVersion") + { + If = condition, + Id = "gitversion", + Uses = "gittools/actions/gitversion/execute@v3.1.1", + With = + { + ["useConfigFile"] = "true", + } + }; + } +}