diff --git a/.github/workflows/DeleteRelease.yml b/.github/workflows/DeleteRelease.yml new file mode 100644 index 0000000..ceae9aa --- /dev/null +++ b/.github/workflows/DeleteRelease.yml @@ -0,0 +1,44 @@ +name: Delete release + +on: + workflow_dispatch: + inputs: + ref: + description: 'Release tag to delete' + required: true + type: string + +permissions: + contents: read + id-token: write + +jobs: + windows: + name: windows-2025 + runs-on: windows-2025 + steps: + + - name: Checkout + uses: actions/checkout@v7 + with: + fetch-depth: 0 + + - name: Cache packages + uses: actions/cache@v6 + with: + path: ~/.nuget/packages + key: ${{ runner.os }}-nuget-${{ hashFiles('**/*.csproj', 'Directory.Build.props', 'Directory.Packages.props') }} + restore-keys: ${{ runner.os }}-nuget- + + - name: Log in to NuGet + id: nuget + uses: NuGet/login@v1 + with: + user: Nice3point + + - name: Delete release + run: dotnet run -c Release -- delete + working-directory: "build" + env: + Delete__Ref: ${{ inputs.ref }} + NuGet__ApiKey: ${{ steps.nuget.outputs.NUGET_API_KEY }} diff --git a/build/Modules/DeleteNugetModule.cs b/build/Modules/DeleteNugetModule.cs index 36a9057..8324165 100644 --- a/build/Modules/DeleteNugetModule.cs +++ b/build/Modules/DeleteNugetModule.cs @@ -1,23 +1,38 @@ +using System.Text; using Build.Options; using EnumerableAsyncProcessor.Extensions; +using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Options; using ModularPipelines.Context; using ModularPipelines.DotNet.Extensions; using ModularPipelines.DotNet.Options; +using ModularPipelines.Git.Extensions; +using ModularPipelines.Git.Options; using ModularPipelines.Models; using ModularPipelines.Modules; +using ModularPipelines.Options; +using Shouldly; namespace Build.Modules; -public sealed class DeleteNugetModule(IOptions buildOptions, IOptions nuGetOptions) : Module +/// +/// Delete the NuGet packages published from the specified git reference. +/// +public sealed class DeleteNugetModule(IOptions deleteOptions, IOptions nuGetOptions) : Module { protected override async Task ExecuteAsync(IModuleContext context, CancellationToken cancellationToken) { - return await buildOptions.Value.Versions.Values + var reference = deleteOptions.Value.Ref; + reference.ShouldNotBeNullOrWhiteSpace("No git reference was specified to delete"); + + var buildOptions = await ReadBuildOptionsAsync(context, reference, cancellationToken); + buildOptions.Versions.ShouldNotBeEmpty($"No NuGet versions were found to delete at: {reference}"); + + return await buildOptions.Versions.Values .SelectAsync(async version => await context.DotNet().Nuget.Delete(new DotNetNugetDeleteOptions { PackageName = "Nice3point.BenchmarkDotNet.Revit", - Version = version.ToString(), + Version = version, ApiKey = nuGetOptions.Value.ApiKey, Source = nuGetOptions.Value.Source, NonInteractive = true @@ -25,4 +40,28 @@ public sealed class DeleteNugetModule(IOptions buildOptions, IOpti cancellationToken) .ProcessInParallel(); } + + /// + /// Read the build options from the settings file stored at the specified git reference. + /// + private static async Task ReadBuildOptionsAsync(IModuleContext context, string reference, CancellationToken cancellationToken) + { + var showResult = await context.Git().Commands.Show( + new GitShowOptions + { + Arguments = [$"{reference}:build/appsettings.json"] + }, + new CommandExecutionOptions + { + LogSettings = CommandLoggingOptions.Silent + }, + cancellationToken); + + using var settingsStream = new MemoryStream(Encoding.UTF8.GetBytes(showResult.StandardOutput)); + var configuration = new ConfigurationBuilder() + .AddJsonStream(settingsStream) + .Build(); + + return configuration.GetSection("Build").Get() ?? new BuildOptions(); + } } diff --git a/build/Options/DeleteOptions.cs b/build/Options/DeleteOptions.cs new file mode 100644 index 0000000..3ee405f --- /dev/null +++ b/build/Options/DeleteOptions.cs @@ -0,0 +1,11 @@ +namespace Build.Options; + +[PublicAPI] +public sealed record DeleteOptions +{ + /// + /// The git reference of the release to delete. + /// + /// 2027.0.0 + public string Ref { get; init; } = string.Empty; +} diff --git a/build/Program.cs b/build/Program.cs index 53276f4..df7df5c 100644 --- a/build/Program.cs +++ b/build/Program.cs @@ -15,13 +15,14 @@ builder.Services.Configure(builder.Configuration.GetSection("Build")); builder.Services.Configure(builder.Configuration.GetSection("NuGet")); builder.Services.Configure(builder.Configuration.GetSection("Publish")); +builder.Services.Configure(builder.Configuration.GetSection("Delete")); if (args.Length == 0) { builder.Services.AddModule(); } -if (args.Contains("clean-nuget")) +if (args.Contains("delete")) { builder.Services.AddModule(); } diff --git a/build/appsettings.json b/build/appsettings.json index 529c615..1745be8 100644 --- a/build/appsettings.json +++ b/build/appsettings.json @@ -14,6 +14,9 @@ "Publish": { "Version": "" }, + "Delete": { + "Ref": "" + }, "NuGet": { "InternalApiKey": "", "ApiKey": "",