Skip to content

Commit fef0403

Browse files
thomhurstclaude
andauthored
Modules - Composition (#1343)
* Refactor module result repository to use IModule interface * refactor: change TaskCompletionSource to instance variable in EngineCancellationTokenTests * Refactor module interfaces and implementations to use IModule instead of ModuleBase - Updated IModuleScheduler and IPipelineSetupExecutor interfaces to accept IModule instead of ModuleBase. - Introduced ModuleDependencyResolver to handle module dependencies using DependsOn attributes. - Refactored ModuleDisposer and ModuleExecutor to work with IModule and ModuleState. - Enhanced ModuleState to track module results and skip decisions. - Updated event notifications to use ModuleState instead of ModuleBase. - Adjusted ProgressPrinter to manage progress for IModule and ModuleState. - Modified IPipelineModuleHooks to work with IModule. - Ensured all modules and related classes now consistently use IModule for better abstraction and flexibility. * Refactor unit tests to use IModule interface and improve consistency * refactor: update JSON serialization handling for IModule properties in PipelineSummary * refactor: add global.json for SDK and test configuration; update TrxParsingTests to use temporary results directory * refactor: update AzureCommandTests to implement IModule interface and improve test consistency * refactor: update ModuleExecutor to create a scope for resolving IPipelineContext * refactor: update .NET version in workflow to 10.0.x * refactor: create a scope for resolving scoped services in ModuleExecutor * fix: use scoped service provider in tests for IPipelineContext IPipelineContext is a scoped service, so tests need to create a scope before resolving it from the host's service provider. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * refactor: update test options to use WorkingDirectory instead of ProjectSolutionDirectoryDllExe * refactor: update IModule references to use Module base class in various modules and tests * refactor: replace RunModuleWithResult with RunModule in test cases * fix: set completion result for skipped modules in ModuleExecutionPipeline * refactor: update AzureCommandModules to inherit from Module base class and adjust test cases * refactor: update modules to inherit from Module base class and override ExecuteAsync method * refactor: enhance module dependency resolution to support self-referencing checks and available module types * refactor: enhance logging for NotInParallel constraint checks in ModuleScheduler and related tests * refactor: enhance logging in ModuleScheduler and simplify test setup in NotInParallelTestsWithConstraintKeys * refactor: replace ConcurrentBag with ConcurrentDictionary for accurate module tracking in NotInParallelTestsWithConstraintKeys * refactor: replace Dictionary with ConcurrentDictionary for thread-safe module start time tracking in MyModuleHooks --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent 784ce43 commit fef0403

File tree

202 files changed

+3763
-2828
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

202 files changed

+3763
-2828
lines changed

.github/copilot-instructions.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ dotnet build ModularPipelines.Examples.sln -c Release
4343
4. **Run Build Pipeline** (150+ seconds - NEVER CANCEL):
4444
```bash
4545
cd src/ModularPipelines.Build
46-
dotnet run -c Release --framework net8.0
46+
dotnet run -c Release --framework net10.0
4747
```
4848
Note: The build pipeline may fail in development environment due to missing CI environment variables (like origin/main branch). This is expected. The pipeline includes test execution with code coverage.
4949

@@ -138,7 +138,7 @@ yarn start
138138
1. Build the affected solutions
139139
2. Run formatting: `dotnet format ModularPipelines.sln`
140140
3. Run tests for affected areas
141-
4. If modifying the build pipeline, test with: `cd src/ModularPipelines.Build && dotnet run -c Release --framework net8.0`
141+
4. If modifying the build pipeline, test with: `cd src/ModularPipelines.Build && dotnet run -c Release --framework net10.0`
142142

143143
**For module development:**
144144
1. Create a module inheriting from `Module<T>`

.github/workflows/dotnet.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ jobs:
5151
- name: Setup .NET
5252
uses: actions/setup-dotnet@v5
5353
with:
54-
dotnet-version: 9.0.x
54+
dotnet-version: 10.0.x
5555
- name: Cache NuGet
5656
uses: actions/cache@v4
5757
with:
@@ -70,7 +70,7 @@ jobs:
7070
done
7171
7272
- name: Run Pipeline
73-
run: dotnet run -c Release --framework net8.0
73+
run: dotnet run -c Release --framework net10.0
7474
working-directory: "src/ModularPipelines.Build"
7575
env:
7676
GITHUB_TOKEN: ${{ github.token }}

CLAUDE.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,18 +15,18 @@ dotnet build ModularPipelines.Analyzers.sln -c Release
1515

1616
# Run the build pipeline (from src/ModularPipelines.Build)
1717
cd src/ModularPipelines.Build
18-
dotnet run -c Release --framework net8.0
18+
dotnet run -c Release --framework net10.0
1919
```
2020

2121
### Running Tests
2222
```bash
2323
# Run all unit tests (pattern: *UnitTests.csproj)
2424
# Tests are executed via the build pipeline with coverage
2525
cd src/ModularPipelines.Build
26-
dotnet run -c Release --framework net8.0
26+
dotnet run -c Release --framework net10.0
2727

2828
# Run a single test project manually
29-
dotnet run --project <path-to-test-project> --framework net9.0 -- --coverage --coverage-output-format cobertura
29+
dotnet run --project <path-to-test-project> --framework net10.0 -- --coverage --coverage-output-format cobertura
3030
```
3131

3232
### Code Formatting
@@ -111,4 +111,5 @@ The build pipeline (`src/ModularPipelines.Build/`) demonstrates best practices:
111111
- Unit tests use the project's own pipeline system
112112
- Tests run with code coverage collection enabled
113113
- Coverage reports uploaded to Codacy and Codecov
114-
- Test projects identified by "*UnitTests.csproj" pattern
114+
- Test projects identified by "*UnitTests.csproj" pattern
115+
- remember the correct filter syntax

Directory.Build.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<Project>
33
<PropertyGroup>
4-
<TargetFrameworks Condition="'$(TargetFrameworks)' == ''">net8.0;net9.0</TargetFrameworks>
4+
<TargetFrameworks Condition="'$(TargetFrameworks)' == ''">net10.0</TargetFrameworks>
55
<ImplicitUsings>enable</ImplicitUsings>
66
<Nullable>enable</Nullable>
77
<LangVersion>preview</LangVersion>

global.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
{
22
"sdk": {
3-
"version": "9.0.304",
3+
"version": "10.0.100",
44
"rollForward": "latestMinor",
55
"allowPrerelease": false
6+
},
7+
"test": {
8+
"runner": "Microsoft.Testing.Platform"
69
}
710
}

src/ModularPipelines.Analyzers/ModularPipelines.Analyzers.Test/Net.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,11 @@ internal static class Net
1919

2020
private static readonly Lazy<ReferenceAssemblies> LazyNet80 = new(() =>
2121
new ReferenceAssemblies(
22-
"net8.0",
22+
"net10.0",
2323
new PackageIdentity(
2424
"Microsoft.NETCore.App.Ref",
2525
"8.0.6"),
26-
Path.Combine("ref", "net8.0"))
26+
Path.Combine("ref", "net10.0"))
2727
.AddPackages(ImmutableArray.Create(new PackageIdentity("Microsoft.Extensions.Logging", "8.0.0")))
2828
);
2929

src/ModularPipelines.Build/Modules/ChangedFilesInPullRequestModule.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ namespace ModularPipelines.Build.Modules;
1212
[SkipOnMainBranch]
1313
public class ChangedFilesInPullRequestModule : Module<IReadOnlyList<File>>
1414
{
15-
protected override async Task<IReadOnlyList<File>?> ExecuteAsync(IPipelineContext context, CancellationToken cancellationToken)
15+
public override async Task<IReadOnlyList<File>?> ExecuteAsync(IModuleContext context, CancellationToken cancellationToken)
1616
{
1717
var result = await context.Git().Commands.Diff(new GitDiffOptions
1818
{

src/ModularPipelines.Build/Modules/CodeFormattedNicelyModule.cs

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,16 @@
1111
using ModularPipelines.GitHub.Extensions;
1212
using ModularPipelines.Models;
1313
using ModularPipelines.Modules;
14+
using ModularPipelines.Modules.Behaviors;
1415

1516
namespace ModularPipelines.Build.Modules;
1617

1718
[SkipIfNoGitHubToken]
1819
[SkipIfNoStandardGitHubToken]
1920
[SkipOnMainBranch]
2021
[RunOnLinuxOnly]
21-
public class CodeFormattedNicelyModule : Module<CommandResult>
22+
public class CodeFormattedNicelyModule : Module<CommandResult>, ISkippable, IAlwaysRun
2223
{
23-
public override ModuleRunType ModuleRunType => ModuleRunType.AlwaysRun;
24-
2524
private const string DotnetFormatGitMessage = "DotNet Format";
2625

2726
private readonly IOptions<GitHubSettings> _githubSettings;
@@ -31,7 +30,7 @@ public CodeFormattedNicelyModule(IOptions<GitHubSettings> githubSettings)
3130
_githubSettings = githubSettings;
3231
}
3332

34-
protected override Task<SkipDecision> ShouldSkip(IPipelineContext context)
33+
public Task<SkipDecision> ShouldSkip(IPipelineContext context)
3534
{
3635
if (context.GitHub().EnvironmentVariables.EventName != "pull_request")
3736
{
@@ -46,12 +45,11 @@ protected override Task<SkipDecision> ShouldSkip(IPipelineContext context)
4645
return SkipDecision.DoNotSkip.AsTask();
4746
}
4847

49-
/// <inheritdoc/>
50-
protected override async Task<CommandResult?> ExecuteAsync(IPipelineContext context, CancellationToken cancellationToken)
48+
public override async Task<CommandResult?> ExecuteAsync(IModuleContext context, CancellationToken cancellationToken)
5149
{
5250
if (!context.Git().Information.BranchName!.Contains("pull"))
5351
{
54-
return await NothingAsync();
52+
return null;
5553
}
5654

5755
try

src/ModularPipelines.Build/Modules/CreateReleaseModule.cs

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
using ModularPipelines.GitHub.Extensions;
99
using ModularPipelines.Models;
1010
using ModularPipelines.Modules;
11+
using ModularPipelines.Modules.Behaviors;
1112
using Octokit;
1213

1314
namespace ModularPipelines.Build.Modules;
@@ -18,7 +19,7 @@ namespace ModularPipelines.Build.Modules;
1819
[DependsOn<NugetVersionGeneratorModule>]
1920
[DependsOn<UploadPackagesToNugetModule>]
2021
[DependsOn<DependabotCommitsModule>]
21-
public class CreateReleaseModule : Module<Release>
22+
public class CreateReleaseModule : Module<Release>, ISkippable, IIgnoreFailures
2223
{
2324
private readonly IOptions<GitHubSettings> _githubSettings;
2425
private readonly IOptions<PublishSettings> _publishSettings;
@@ -30,14 +31,13 @@ public CreateReleaseModule(IOptions<GitHubSettings> githubSettings,
3031
_publishSettings = publishSettings;
3132
}
3233

33-
protected override async Task<bool> ShouldIgnoreFailures(IPipelineContext context, Exception exception)
34+
public async Task<bool> ShouldIgnoreFailures(IPipelineContext context, Exception exception)
3435
{
3536
await Task.Yield();
3637
return exception is ApiValidationException;
3738
}
3839

39-
/// <inheritdoc/>
40-
protected override async Task<SkipDecision> ShouldSkip(IPipelineContext context)
40+
public async Task<SkipDecision> ShouldSkip(IPipelineContext context)
4141
{
4242
await Task.CompletedTask;
4343

@@ -49,10 +49,9 @@ protected override async Task<SkipDecision> ShouldSkip(IPipelineContext context)
4949
return string.IsNullOrEmpty(_githubSettings.Value.AdminToken);
5050
}
5151

52-
/// <inheritdoc/>
53-
protected override async Task<Release?> ExecuteAsync(IPipelineContext context, CancellationToken cancellationToken)
52+
public override async Task<Release?> ExecuteAsync(IModuleContext context, CancellationToken cancellationToken)
5453
{
55-
var versionInfoResult = await GetModule<NugetVersionGeneratorModule>();
54+
var versionInfoResult = context.GetModule<NugetVersionGeneratorModule, string>();
5655

5756
return await context.GitHub().Client.Repository.Release.Create(long.Parse(context.GitHub().EnvironmentVariables.RepositoryId!),
5857
new NewRelease($"v{versionInfoResult.Value}")

src/ModularPipelines.Build/Modules/DependabotCommitsModule.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ namespace ModularPipelines.Build.Modules;
1212
[RunOnLinuxOnly]
1313
public class DependabotCommitsModule : Module<List<string>>
1414
{
15-
protected override async Task<List<string>?> ExecuteAsync(IPipelineContext context, CancellationToken cancellationToken)
15+
public override async Task<List<string>?> ExecuteAsync(IModuleContext context, CancellationToken cancellationToken)
1616
{
1717
var repositoryInfo = context.GitHub().RepositoryInfo;
1818

0 commit comments

Comments
 (0)