From 39eb982fb556b80fc661ddd72a4a96f596d21548 Mon Sep 17 00:00:00 2001 From: Nice3point Date: Mon, 28 Sep 2026 10:37:05 +0300 Subject: [PATCH 1/4] [Build] Rename the NuGet deletion command to delete --- build/Program.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/Program.cs b/build/Program.cs index 53276f4..a5bee60 100644 --- a/build/Program.cs +++ b/build/Program.cs @@ -21,7 +21,7 @@ builder.Services.AddModule(); } -if (args.Contains("clean-nuget")) +if (args.Contains("delete")) { builder.Services.AddModule(); } From 10649911e284884f40fd188cf0d3fb65dc74f06c Mon Sep 17 00:00:00 2001 From: Nice3point Date: Mon, 28 Sep 2026 10:38:10 +0300 Subject: [PATCH 2/4] [Build] Delete the NuGet versions recorded at a git reference --- build/Modules/DeleteNugetModule.cs | 45 ++++++++++++++++++++++++++++-- build/Options/DeleteOptions.cs | 11 ++++++++ build/Program.cs | 1 + build/appsettings.json | 3 ++ 4 files changed, 57 insertions(+), 3 deletions(-) create mode 100644 build/Options/DeleteOptions.cs 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 a5bee60..df7df5c 100644 --- a/build/Program.cs +++ b/build/Program.cs @@ -15,6 +15,7 @@ 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) { 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": "", From 1468ccb1c8ac42ba1bb806d58ea6db59ed3d283e Mon Sep 17 00:00:00 2001 From: Nice3point Date: Mon, 28 Sep 2026 10:38:10 +0300 Subject: [PATCH 3/4] [CI] Add a workflow deleting a release --- .github/workflows/DeleteRelease.yml | 37 +++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 .github/workflows/DeleteRelease.yml diff --git a/.github/workflows/DeleteRelease.yml b/.github/workflows/DeleteRelease.yml new file mode 100644 index 0000000..b4872c8 --- /dev/null +++ b/.github/workflows/DeleteRelease.yml @@ -0,0 +1,37 @@ +name: Delete release + +on: + workflow_dispatch: + inputs: + ref: + description: 'Release tag to delete' + required: true + type: string + +permissions: + contents: read + +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: Delete release + run: dotnet run -c Release -- delete + working-directory: "build" + env: + Delete__Ref: ${{ inputs.ref }} + NuGet__ApiKey: ${{ secrets.NUGET_API_KEY }} From 3408bf6493bdca370ac258a18d93726e1e401627 Mon Sep 17 00:00:00 2001 From: Nice3point Date: Mon, 28 Sep 2026 11:07:12 +0300 Subject: [PATCH 4/4] [CI] Delete a release through trusted publishing --- .github/workflows/DeleteRelease.yml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/.github/workflows/DeleteRelease.yml b/.github/workflows/DeleteRelease.yml index b4872c8..ceae9aa 100644 --- a/.github/workflows/DeleteRelease.yml +++ b/.github/workflows/DeleteRelease.yml @@ -10,6 +10,7 @@ on: permissions: contents: read + id-token: write jobs: windows: @@ -29,9 +30,15 @@ jobs: 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: ${{ secrets.NUGET_API_KEY }} + NuGet__ApiKey: ${{ steps.nuget.outputs.NUGET_API_KEY }}