Skip to content

Commit 8b828d6

Browse files
thomhurstclaude
andcommitted
feat!: modernize host setup API with ASP.NET Core minimal API pattern
BREAKING CHANGE: Replace PipelineHostBuilder with new PipelineBuilder API This is a complete redesign of the pipeline configuration API to follow ASP.NET Core's WebApplicationBuilder pattern: Before (callback-based): await PipelineHostBuilder.Create() .ConfigureServices((context, services) => { services.AddModule<MyModule>(); }) .ConfigurePipelineOptions((context, options) => { }) .ExecutePipelineAsync(); After (direct property access): var builder = Pipeline.CreateBuilder(); builder.Services.AddModule<MyModule>(); builder.Options.DefaultRetryCount = 3; await builder.Build().RunAsync(); Changes: - New Pipeline.CreateBuilder() static factory method - New PipelineBuilder with direct property access (Services, Configuration, Options) - New IPipeline interface for built pipelines (replaces IPipelineHost) - New PipelineBuilderExtensions for convenience methods (AddModule, ConfigureServices) - Remove PipelineHostBuilder, PipelineHost, IPipelineHost - Remove callback-based configuration methods - Update all examples and tests to use new API Closes #2065 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 02ab751 commit 8b828d6

20 files changed

Lines changed: 1067 additions & 1090 deletions

src/ModularPipelines.Build/Program.cs

Lines changed: 72 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -9,88 +9,85 @@
99
using ModularPipelines.Build.Modules.LocalMachine;
1010
using ModularPipelines.Build.Settings;
1111
using ModularPipelines.Extensions;
12-
using ModularPipelines.Host;
1312
using Octokit;
1413
using Octokit.Internal;
1514

16-
await PipelineHostBuilder.Create()
17-
.ConfigureAppConfiguration((_, builder) =>
18-
{
19-
builder.AddJsonFile("appsettings.json")
20-
.AddUserSecrets<Program>()
21-
.AddEnvironmentVariables();
22-
})
23-
.ConfigureServices((context, collection) =>
24-
{
25-
collection.Configure<PipelineSettings>(context.Configuration.GetSection("Pipeline"));
26-
collection.Configure<NuGetSettings>(context.Configuration.GetSection("NuGet"));
27-
collection.Configure<LocalNuGetSettings>(context.Configuration.GetSection("LocalNuGet"));
28-
collection.Configure<GitHubSettings>(context.Configuration.GetSection("GitHub"));
29-
collection.Configure<PublishSettings>(context.Configuration.GetSection("Publish"));
30-
collection.Configure<CodacySettings>(context.Configuration.GetSection("Codacy"));
31-
collection.Configure<CodeCovSettings>(context.Configuration.GetSection("CodeCov"));
32-
33-
collection
34-
.AddModule<RunUnitTestsModule>()
35-
.AddModule<NugetVersionGeneratorModule>()
36-
.AddModule<FindProjectsModule>()
37-
.AddModule<FindProjectDependenciesModule>()
38-
.AddModule<PackProjectsModule>()
39-
.AddModule<PackageFilesRemovalModule>()
40-
.AddModule<PackagePathsParserModule>()
41-
.AddModule<CodeFormattedNicelyModule>()
42-
.AddModule<GenerateReadMeModule>()
43-
.AddModule<FormatMarkdownModule>()
44-
.AddModule<ChangedFilesInPullRequestModule>()
45-
.AddModule<DependabotCommitsModule>()
46-
.AddModule<PrintEnvironmentVariablesModule>()
47-
.AddModule<PrintGitInformationModule>()
48-
.AddModule<PushVersionTagModule>()
49-
.AddPipelineModuleHooks<MyModuleHooks>();
15+
var builder = Pipeline.CreateBuilder(args);
5016

51-
collection.AddSingleton<IGitHubClient>(sp =>
52-
{
53-
var githubSettings = sp.GetRequiredService<IOptions<GitHubSettings>>();
54-
var pipelineSettings = sp.GetRequiredService<IOptions<PipelineSettings>>();
17+
builder.Configuration
18+
.AddJsonFile("appsettings.json")
19+
.AddUserSecrets<Program>()
20+
.AddEnvironmentVariables();
5521

56-
var githubToken = githubSettings.Value.StandardToken;
22+
builder.Services.Configure<PipelineSettings>(builder.Configuration.GetSection("Pipeline"));
23+
builder.Services.Configure<NuGetSettings>(builder.Configuration.GetSection("NuGet"));
24+
builder.Services.Configure<LocalNuGetSettings>(builder.Configuration.GetSection("LocalNuGet"));
25+
builder.Services.Configure<GitHubSettings>(builder.Configuration.GetSection("GitHub"));
26+
builder.Services.Configure<PublishSettings>(builder.Configuration.GetSection("Publish"));
27+
builder.Services.Configure<CodacySettings>(builder.Configuration.GetSection("Codacy"));
28+
builder.Services.Configure<CodeCovSettings>(builder.Configuration.GetSection("CodeCov"));
5729

58-
if (string.IsNullOrEmpty(githubToken))
59-
{
60-
githubToken = "token";
61-
}
30+
builder.Services
31+
.AddModule<RunUnitTestsModule>()
32+
.AddModule<NugetVersionGeneratorModule>()
33+
.AddModule<FindProjectsModule>()
34+
.AddModule<FindProjectDependenciesModule>()
35+
.AddModule<PackProjectsModule>()
36+
.AddModule<PackageFilesRemovalModule>()
37+
.AddModule<PackagePathsParserModule>()
38+
.AddModule<CodeFormattedNicelyModule>()
39+
.AddModule<GenerateReadMeModule>()
40+
.AddModule<FormatMarkdownModule>()
41+
.AddModule<ChangedFilesInPullRequestModule>()
42+
.AddModule<DependabotCommitsModule>()
43+
.AddModule<PrintEnvironmentVariablesModule>()
44+
.AddModule<PrintGitInformationModule>()
45+
.AddModule<PushVersionTagModule>()
46+
.AddPipelineModuleHooks<MyModuleHooks>();
6247

63-
return new GitHubClient(new ProductHeaderValue(pipelineSettings.Value.GitHubProductHeader),
64-
new InMemoryCredentialStore(new Credentials(githubToken)));
65-
});
48+
builder.Services.AddSingleton<IGitHubClient>(sp =>
49+
{
50+
var githubSettings = sp.GetRequiredService<IOptions<GitHubSettings>>();
51+
var pipelineSettings = sp.GetRequiredService<IOptions<PipelineSettings>>();
6652

67-
// Local NuGet modules should only run in local development, not CI
68-
// IsDevelopment() returns true for both local dev AND PR builds in CI (DOTNET_ENVIRONMENT=Development)
69-
// Check common CI environment variables to distinguish local dev from CI
70-
var isRunningInCI = !string.IsNullOrEmpty(Environment.GetEnvironmentVariable("CI"))
71-
|| !string.IsNullOrEmpty(Environment.GetEnvironmentVariable("GITHUB_ACTIONS"))
72-
|| !string.IsNullOrEmpty(Environment.GetEnvironmentVariable("TF_BUILD"))
73-
|| !string.IsNullOrEmpty(Environment.GetEnvironmentVariable("GITLAB_CI"));
74-
var isLocalDevelopment = context.HostingEnvironment.IsDevelopment() && !isRunningInCI;
53+
var githubToken = githubSettings.Value.StandardToken;
7554

76-
if (isLocalDevelopment)
77-
{
78-
collection.AddModule<CreateLocalNugetFolderModule>()
79-
.AddModule<AddLocalNugetSourceModule>()
80-
.AddModule<UploadPackagesToLocalNuGetModule>();
81-
}
82-
else if (!context.HostingEnvironment.IsDevelopment())
83-
{
84-
// Production environment (main branch CI)
85-
collection.AddModule<UploadPackagesToNugetModule>()
86-
.AddModule<CreateReleaseModule>();
87-
}
88-
// else: CI Development mode (PR builds) - don't register local NuGet or production upload modules
89-
})
90-
.ConfigurePipelineOptions((context, options) =>
55+
if (string.IsNullOrEmpty(githubToken))
9156
{
92-
var pipelineSettings = context.Configuration.GetSection("Pipeline").Get<PipelineSettings>() ?? new PipelineSettings();
93-
options.DefaultRetryCount = pipelineSettings.DefaultRetryCount;
94-
})
95-
.SetLogLevel(LogLevel.Debug) // Temporarily hardcoded for debugging
96-
.ExecutePipelineAsync();
57+
githubToken = "token";
58+
}
59+
60+
return new GitHubClient(new ProductHeaderValue(pipelineSettings.Value.GitHubProductHeader),
61+
new InMemoryCredentialStore(new Credentials(githubToken)));
62+
});
63+
64+
// Local NuGet modules should only run in local development, not CI
65+
// IsDevelopment() returns true for both local dev AND PR builds in CI (DOTNET_ENVIRONMENT=Development)
66+
// Check common CI environment variables to distinguish local dev from CI
67+
var isRunningInCI = !string.IsNullOrEmpty(Environment.GetEnvironmentVariable("CI"))
68+
|| !string.IsNullOrEmpty(Environment.GetEnvironmentVariable("GITHUB_ACTIONS"))
69+
|| !string.IsNullOrEmpty(Environment.GetEnvironmentVariable("TF_BUILD"))
70+
|| !string.IsNullOrEmpty(Environment.GetEnvironmentVariable("GITLAB_CI"));
71+
var isLocalDevelopment = builder.Environment.IsDevelopment() && !isRunningInCI;
72+
73+
if (isLocalDevelopment)
74+
{
75+
builder.Services.AddModule<CreateLocalNugetFolderModule>()
76+
.AddModule<AddLocalNugetSourceModule>()
77+
.AddModule<UploadPackagesToLocalNuGetModule>();
78+
}
79+
else if (!builder.Environment.IsDevelopment())
80+
{
81+
// Production environment (main branch CI)
82+
builder.Services.AddModule<UploadPackagesToNugetModule>()
83+
.AddModule<CreateReleaseModule>();
84+
}
85+
// else: CI Development mode (PR builds) - don't register local NuGet or production upload modules
86+
87+
var pipelineSettings = builder.Configuration.GetSection("Pipeline").Get<PipelineSettings>() ?? new PipelineSettings();
88+
builder.Options.DefaultRetryCount = pipelineSettings.DefaultRetryCount;
89+
90+
builder.SetLogLevel(LogLevel.Debug); // Temporarily hardcoded for debugging
91+
92+
var pipeline = builder.Build();
93+
await pipeline.RunAsync();

src/ModularPipelines/Extensions/HostExtensions.cs

Lines changed: 0 additions & 19 deletions
This file was deleted.

0 commit comments

Comments
 (0)