From 827724aeba9e0396c814e82454fe710e28456a88 Mon Sep 17 00:00:00 2001 From: Mabrouk Mahdhi Date: Mon, 27 Jan 2025 18:45:44 +0100 Subject: [PATCH 1/7] EXPOSERS: GitHub Pipeline Builder --- ADotNet/Clients/ADotNetClient.cs | 2 +- .../Clients/Builders/GitHubPipelineBuilder.cs | 77 +++++++++++ ADotNet/Clients/Builders/JobBuilder.cs | 122 ++++++++++++++++++ 3 files changed, 200 insertions(+), 1 deletion(-) create mode 100644 ADotNet/Clients/Builders/GitHubPipelineBuilder.cs create mode 100644 ADotNet/Clients/Builders/JobBuilder.cs diff --git a/ADotNet/Clients/ADotNetClient.cs b/ADotNet/Clients/ADotNetClient.cs index a19fb24..8692500 100644 --- a/ADotNet/Clients/ADotNetClient.cs +++ b/ADotNet/Clients/ADotNetClient.cs @@ -10,7 +10,7 @@ namespace ADotNet.Clients { - public class ADotNetClient + public class ADotNetClient : IADotNetClient { private readonly IBuildService buildService; diff --git a/ADotNet/Clients/Builders/GitHubPipelineBuilder.cs b/ADotNet/Clients/Builders/GitHubPipelineBuilder.cs new file mode 100644 index 0000000..7509aea --- /dev/null +++ b/ADotNet/Clients/Builders/GitHubPipelineBuilder.cs @@ -0,0 +1,77 @@ +// --------------------------------------------------------------------------- +// Copyright (c) Hassan Habib & Shri Humrudha Jagathisun All rights reserved. +// Licensed under the MIT License. +// See License.txt in the project root for license information. +// --------------------------------------------------------------------------- + +using System; +using System.Collections.Generic; +using ADotNet.Models.Pipelines.GithubPipelines.DotNets; + +namespace ADotNet.Clients.Builders +{ + public class GitHubPipelineBuilder + { + private readonly GithubPipeline githubPipeline; + private readonly IADotNetClient aDotNetClient; + + internal GitHubPipelineBuilder(IADotNetClient aDotNetClient) + { + this.githubPipeline = new GithubPipeline + { + OnEvents = new Events(), + Jobs = new Dictionary() + }; + + this.aDotNetClient = aDotNetClient; + } + + public static GitHubPipelineBuilder CreateNewPipeline() + { + var aDotNetClient = new ADotNetClient(); + + return new GitHubPipelineBuilder(aDotNetClient); + } + + public GitHubPipelineBuilder SetName(string name) + { + this.githubPipeline.Name = name; + + return this; + } + + public GitHubPipelineBuilder OnPush(params string[] branches) + { + this.githubPipeline.OnEvents.Push = new PushEvent + { + Branches = branches + }; + + return this; + } + + public GitHubPipelineBuilder OnPullRequest(params string[] branches) + { + this.githubPipeline.OnEvents.PullRequest = new PullRequestEvent + { + Branches = branches + }; + + return this; + } + + public GitHubPipelineBuilder AddJob(string jobIdentifier, Action configureJob) + { + var jobBuilder = new JobBuilder(); + + configureJob(jobBuilder); + + this.githubPipeline.Jobs[jobIdentifier] = jobBuilder.Build(); + + return this; + } + + public void SaveToFile(string path) => + this.aDotNetClient.SerializeAndWriteToFile(this.githubPipeline, path); + } +} diff --git a/ADotNet/Clients/Builders/JobBuilder.cs b/ADotNet/Clients/Builders/JobBuilder.cs new file mode 100644 index 0000000..9c8412a --- /dev/null +++ b/ADotNet/Clients/Builders/JobBuilder.cs @@ -0,0 +1,122 @@ +// --------------------------------------------------------------------------- +// Copyright (c) Hassan Habib & Shri Humrudha Jagathisun All rights reserved. +// Licensed under the MIT License. +// See License.txt in the project root for license information. +// --------------------------------------------------------------------------- + +using System.Collections.Generic; +using ADotNet.Models.Pipelines.GithubPipelines.DotNets; +using ADotNet.Models.Pipelines.GithubPipelines.DotNets.Tasks; +using ADotNet.Models.Pipelines.GithubPipelines.DotNets.Tasks.SetupDotNetTaskV1s; + +namespace ADotNet.Clients.Builders +{ + public class JobBuilder + { + private readonly Job job; + + internal JobBuilder() + { + this.job = new Job + { + Steps = new List(), + EnvironmentVariables = null + }; + } + + public JobBuilder WithName(string name) + { + this.job.Name = name; + return this; + } + + public JobBuilder RunsOn(string machine) + { + this.job.RunsOn = machine; + return this; + } + + public JobBuilder AddEnvironmentVariable(string key, string value) + { + this.job.EnvironmentVariables ??= new Dictionary(); + + this.job.EnvironmentVariables[key] = value; + return this; + } + + public JobBuilder AddEnvironmentVariables(Dictionary variables) + { + this.job.EnvironmentVariables ??= new Dictionary(); + + foreach (var variable in variables) + { + this.job.EnvironmentVariables[variable.Key] = variable.Value; + } + + return this; + } + + public JobBuilder AddCheckoutStep(string name = "Check out") + { + this.job.Steps.Add(new CheckoutTaskV2 { Name = name }); + + return this; + } + + public JobBuilder AddSetupDotNetStep( + string version, + string stepName = "Setup Dot Net Version", + bool includePrerelease = false) + { + this.job.Steps.Add(new SetupDotNetTaskV1 + { + Name = stepName, + TargetDotNetVersion = new TargetDotNetVersion + { + DotNetVersion = version, + IncludePrerelease = includePrerelease + } + }); + + return this; + } + + public JobBuilder AddRestoreStep(string name = "Restore") + { + this.job.Steps.Add(new RestoreTask { Name = name }); + + return this; + } + + public JobBuilder AddBuildStep(string name = "Build") + { + this.job.Steps.Add(new DotNetBuildTask { Name = name }); + + return this; + } + + public JobBuilder AddTestStep(string name = "Test", string command = null) + { + this.job.Steps.Add(new TestTask + { + Name = name, + Run = command ?? "dotnet test --no-build --verbosity normal" + }); + + return this; + } + + public JobBuilder AddGenericStep(string name, string runCommand) + { + this.job.Steps.Add(new GithubTask + { + Name = name, + Run = runCommand + }); + + return this; + } + + public Job Build() => this.job; + } +} \ No newline at end of file From 9f6271968493b26577ab28ce63560900ac0e2c5d Mon Sep 17 00:00:00 2001 From: Mabrouk Mahdhi Date: Mon, 27 Jan 2025 18:56:42 +0100 Subject: [PATCH 2/7] CLIENTS: Manual Test in Client App --- AdoNet.Tests.Console/Program.cs | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/AdoNet.Tests.Console/Program.cs b/AdoNet.Tests.Console/Program.cs index 06d673f..445eb6e 100644 --- a/AdoNet.Tests.Console/Program.cs +++ b/AdoNet.Tests.Console/Program.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using ADotNet.Clients; +using ADotNet.Clients.Builders; using ADotNet.Models.Pipelines.AdoPipelines.AspNets; using ADotNet.Models.Pipelines.AdoPipelines.AspNets.Tasks.DotNetExecutionTasks; using ADotNet.Models.Pipelines.AdoPipelines.AspNets.Tasks.PublishBuildArtifactTasks; @@ -185,6 +186,33 @@ static void Main(string[] args) }; adoClient.SerializeAndWriteToFile(githubPipeline, "github-pipelines.yaml"); + + + GitHubPipelineBuilder.CreateNewPipeline() + .SetName("Github") + .OnPush("master") + .OnPullRequest("master") + .AddJob("build", job => job + .WithName("Build") + .RunsOn(BuildMachines.WindowsLatest) + .AddEnvironmentVariable("AzureClientId", "${{ secrets.AZURECLIENTID }}") + .AddEnvironmentVariables(new Dictionary + { + { "AzureTenantId", "${{ secrets.AZURETENANTID }}" }, + { "AzureClientSecret", "${{ secrets.AZURECLIENTSECRET }}" }, + { "AzureAdminName", "${{ secrets.AZUREADMINNAME }}" }, + { "AzureAdminAccess", "${{ secrets.AZUREADMINACCESS }}" } + }) + .AddCheckoutStep("Check Out") + .AddSetupDotNetStep( + version: "6.0.101", + includePrerelease: true) + .AddRestoreStep() + .AddBuildStep() + .AddGenericStep( + name: "Provision", + runCommand: "dotnet run --project .\\OtripleS.Api.Infrastructure.Provision\\OtripleS.Web.Api.Infrastructure.Provision.csproj")) + .SaveToFile("github-pipelines-fluent.yaml"); } } } From 025e501a6dd127dcdc81975e5c40b775a89ac2af Mon Sep 17 00:00:00 2001 From: Mabrouk Mahdhi Date: Mon, 27 Jan 2025 19:01:30 +0100 Subject: [PATCH 3/7] ShouldCreateNewPipeline -> PASS ShouldSetPipelineName -> PASS ShouldAddPushTrigger -> PASS ShouldAddPullRequestTrigger -> PASS ShouldAddJobToPipeline -> PASS ShouldSavePipelineToFile -> PASS --- ADotNet/ADotNet.csproj | 4 + .../GitHubPipelineBuilderTests.Logic.cs | 144 ++++++++++++++++++ .../Builders/GitHubPipelineBuilderTests.cs | 55 +++++++ 3 files changed, 203 insertions(+) create mode 100644 AdoNet.Tests.Unit/Clients/Builders/GitHubPipelineBuilderTests.Logic.cs create mode 100644 AdoNet.Tests.Unit/Clients/Builders/GitHubPipelineBuilderTests.cs diff --git a/ADotNet/ADotNet.csproj b/ADotNet/ADotNet.csproj index 254ea25..4fd789c 100644 --- a/ADotNet/ADotNet.csproj +++ b/ADotNet/ADotNet.csproj @@ -86,4 +86,8 @@ + + + + diff --git a/AdoNet.Tests.Unit/Clients/Builders/GitHubPipelineBuilderTests.Logic.cs b/AdoNet.Tests.Unit/Clients/Builders/GitHubPipelineBuilderTests.Logic.cs new file mode 100644 index 0000000..eb45ad2 --- /dev/null +++ b/AdoNet.Tests.Unit/Clients/Builders/GitHubPipelineBuilderTests.Logic.cs @@ -0,0 +1,144 @@ +// --------------------------------------------------------------------------- +// Copyright (c) Hassan Habib & Shri Humrudha Jagathisun All rights reserved. +// Licensed under the MIT License. +// See License.txt in the project root for license information. +// --------------------------------------------------------------------------- + +using ADotNet.Clients.Builders; +using ADotNet.Models.Pipelines.GithubPipelines.DotNets; +using ADotNet.Models.Pipelines.GithubPipelines.DotNets.Tasks; +using FluentAssertions; +using Moq; +using Xunit; + +namespace ADotNet.Tests.Unit.Clients.Builders +{ + public partial class GitHubPipelineBuilderTests + { + [Fact] + public void ShouldCreateNewPipeline() + { + // given..when + var builder = GitHubPipelineBuilder.CreateNewPipeline(); + + // then + builder.Should().NotBeNull(); + } + + [Fact] + public void ShouldSetPipelineName() + { + // given + string inputName = "My GitHub Pipeline"; + string expectedName = inputName; + + // when + var pipelineBuilder = GitHubPipelineBuilder.CreateNewPipeline() + .SetName(inputName); + + var actualPipeline = GetPipeline(pipelineBuilder); + + // then + actualPipeline.Should().NotBeNull(); + actualPipeline.Name.Should().BeEquivalentTo(expectedName); + } + + [Fact] + public void ShouldAddPushTrigger() + { + // given + string[] inputBranches = { "main", "dev" }; + + // when + var pipelineBuilder = GitHubPipelineBuilder.CreateNewPipeline() + .OnPush(inputBranches); + + var actualPipeline = GetPipeline(pipelineBuilder); + + // then + actualPipeline.OnEvents.Push.Should().NotBeNull(); + actualPipeline.OnEvents.Push.Branches.Should().BeEquivalentTo(inputBranches); + } + + + [Fact] + public void ShouldAddPullRequestTrigger() + { + // given + string[] inputBranches = { "main", "feature/*" }; + + // when + var pipelineBuilder = GitHubPipelineBuilder.CreateNewPipeline() + .OnPullRequest(inputBranches); + + var actualPipeline = GetPipeline(pipelineBuilder); + + // then + actualPipeline.OnEvents.PullRequest.Should().NotBeNull(); + actualPipeline.OnEvents.PullRequest.Branches.Should().BeEquivalentTo(inputBranches); + } + + [Fact] + public void ShouldAddJobToPipeline() + { + // given + string inputJobName = "build"; + string inputRunsOn = BuildMachines.WindowsLatest; + string inputTaskName = "Restore"; + + string expectedRunsOn = inputRunsOn; + string expectedTaskName = inputTaskName; + + // when + var pipelineBuilder = GitHubPipelineBuilder.CreateNewPipeline() + .AddJob(inputJobName, job => + job.RunsOn(inputRunsOn) + .AddRestoreStep(inputTaskName)); + + var actualPipeline = GetPipeline(pipelineBuilder); + + // then + var actualJob = actualPipeline.Jobs[inputJobName]; + actualJob.Should().NotBeNull(); + actualJob.RunsOn.Should().Be(expectedRunsOn); + actualJob.Steps.Should().HaveCount(1); + actualJob.Steps[0].Should().BeOfType() + .Which.Name.Should().Be(expectedTaskName); + } + + [Fact] + public void ShouldSavePipelineToFile() + { + // given + string randomFileName = GetRandomFileName(); + string randomPipelineName = GetRandomString(); + GithubPipeline randomPipeline = + CreateRandomGithubPipeline(randomPipelineName); + + GithubPipeline inputPipeline = randomPipeline; + + string inputPath = randomFileName; + string inputPipelineName = randomPipelineName; + + this.aDotNetClientMock.Setup(client => + client.SerializeAndWriteToFile( + inputPipeline, + inputPath)) + .Verifiable(); + + this.gitHubPipelineBuilder.SetName(inputPipelineName); + + // when + this.gitHubPipelineBuilder.SaveToFile(inputPath); + + // then + this.aDotNetClientMock.Verify(client => + client.SerializeAndWriteToFile( + It.IsAny(), + It.IsAny()), + Times.Once); + + this.aDotNetClientMock.VerifyNoOtherCalls(); + } + } +} diff --git a/AdoNet.Tests.Unit/Clients/Builders/GitHubPipelineBuilderTests.cs b/AdoNet.Tests.Unit/Clients/Builders/GitHubPipelineBuilderTests.cs new file mode 100644 index 0000000..8ed1ebc --- /dev/null +++ b/AdoNet.Tests.Unit/Clients/Builders/GitHubPipelineBuilderTests.cs @@ -0,0 +1,55 @@ +// --------------------------------------------------------------------------- +// Copyright (c) Hassan Habib & Shri Humrudha Jagathisun All rights reserved. +// Licensed under the MIT License. +// See License.txt in the project root for license information. +// --------------------------------------------------------------------------- + +using System.IO; +using ADotNet.Clients; +using ADotNet.Clients.Builders; +using ADotNet.Models.Pipelines.GithubPipelines.DotNets; +using Moq; +using Tynamix.ObjectFiller; + +namespace ADotNet.Tests.Unit.Clients.Builders +{ + public partial class GitHubPipelineBuilderTests + { + private readonly Mock aDotNetClientMock; + private readonly GitHubPipelineBuilder gitHubPipelineBuilder; + + public GitHubPipelineBuilderTests() + { + this.aDotNetClientMock = new Mock(); + + this.gitHubPipelineBuilder = new GitHubPipelineBuilder( + aDotNetClient: aDotNetClientMock.Object); + } + + private static GithubPipeline GetPipeline(GitHubPipelineBuilder builder) + { + var privateField = typeof(GitHubPipelineBuilder) + .GetField("githubPipeline", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); + + return (GithubPipeline)privateField.GetValue(builder); + } + + private static string GetRandomString() => + new MnemonicString(wordCount: GetRandomNumber()).GetValue(); + + private static int GetRandomNumber() => + new IntRange(min: 2, max: 10).GetValue(); + + private static string GetRandomFileName() => + Path.GetRandomFileName(); + + private static GithubPipeline CreateRandomGithubPipeline(string name) => + CreateGithubPipelineFiller(name).Create(); + + private static GithubPipeline CreateRandomGithubPipeline() => + CreateGithubPipelineFiller(name: GetRandomString()).Create(); + + private static Filler CreateGithubPipelineFiller(string name) => + new Filler(); + } +} From d637208dd2840561ea2adab7d935f724bec5c198 Mon Sep 17 00:00:00 2001 From: Mabrouk Mahdhi Date: Mon, 27 Jan 2025 19:14:18 +0100 Subject: [PATCH 4/7] CODE RUB: Cleanup and summaries --- .../Clients/Builders/GitHubPipelineBuilder.cs | 32 +++++++++ ADotNet/Clients/Builders/JobBuilder.cs | 65 +++++++++++++++++++ 2 files changed, 97 insertions(+) diff --git a/ADotNet/Clients/Builders/GitHubPipelineBuilder.cs b/ADotNet/Clients/Builders/GitHubPipelineBuilder.cs index 7509aea..86e62ae 100644 --- a/ADotNet/Clients/Builders/GitHubPipelineBuilder.cs +++ b/ADotNet/Clients/Builders/GitHubPipelineBuilder.cs @@ -10,6 +10,9 @@ namespace ADotNet.Clients.Builders { + /// + /// Builder for creating a GitHub pipeline. + /// public class GitHubPipelineBuilder { private readonly GithubPipeline githubPipeline; @@ -26,6 +29,10 @@ internal GitHubPipelineBuilder(IADotNetClient aDotNetClient) this.aDotNetClient = aDotNetClient; } + /// + /// Creates a new instance of the class with a default . + /// + /// A new instance of . public static GitHubPipelineBuilder CreateNewPipeline() { var aDotNetClient = new ADotNetClient(); @@ -33,6 +40,11 @@ public static GitHubPipelineBuilder CreateNewPipeline() return new GitHubPipelineBuilder(aDotNetClient); } + /// + /// Sets the name of the GitHub pipeline. + /// + /// The name of the pipeline. + /// The current instance of . public GitHubPipelineBuilder SetName(string name) { this.githubPipeline.Name = name; @@ -40,6 +52,11 @@ public GitHubPipelineBuilder SetName(string name) return this; } + /// + /// Configures the pipeline to trigger on push events for specified branches. + /// + /// The branches to trigger on push events. + /// The current instance of . public GitHubPipelineBuilder OnPush(params string[] branches) { this.githubPipeline.OnEvents.Push = new PushEvent @@ -50,6 +67,11 @@ public GitHubPipelineBuilder OnPush(params string[] branches) return this; } + /// + /// Configures the pipeline to trigger on pull request events for specified branches. + /// + /// The branches to trigger on pull request events. + /// The current instance of . public GitHubPipelineBuilder OnPullRequest(params string[] branches) { this.githubPipeline.OnEvents.PullRequest = new PullRequestEvent @@ -60,6 +82,12 @@ public GitHubPipelineBuilder OnPullRequest(params string[] branches) return this; } + /// + /// Adds a job to the GitHub pipeline. + /// + /// The unique identifier for the job. + /// The action to configure the job. + /// The current instance of . public GitHubPipelineBuilder AddJob(string jobIdentifier, Action configureJob) { var jobBuilder = new JobBuilder(); @@ -71,6 +99,10 @@ public GitHubPipelineBuilder AddJob(string jobIdentifier, Action con return this; } + /// + /// Saves the configured pipeline (yml) to the specified file path. + /// + /// The file path where the pipeline will be saved. public void SaveToFile(string path) => this.aDotNetClient.SerializeAndWriteToFile(this.githubPipeline, path); } diff --git a/ADotNet/Clients/Builders/JobBuilder.cs b/ADotNet/Clients/Builders/JobBuilder.cs index 9c8412a..9f1d78e 100644 --- a/ADotNet/Clients/Builders/JobBuilder.cs +++ b/ADotNet/Clients/Builders/JobBuilder.cs @@ -11,6 +11,9 @@ namespace ADotNet.Clients.Builders { + /// + /// A builder to create a job for a GitHub Actions workflow. + /// public class JobBuilder { private readonly Job job; @@ -24,26 +27,50 @@ internal JobBuilder() }; } + /// + /// Sets the name of the job. + /// + /// The name of the job. + /// The current instance of . public JobBuilder WithName(string name) { this.job.Name = name; + return this; } + /// + /// Specifies the machine on which the job will run. + /// + /// The machine or environment to run the job on. + /// The current instance of . public JobBuilder RunsOn(string machine) { this.job.RunsOn = machine; + return this; } + /// + /// Adds an environment variable to the job. + /// + /// The key of the environment variable. + /// The value of the environment variable. + /// The current instance of . public JobBuilder AddEnvironmentVariable(string key, string value) { this.job.EnvironmentVariables ??= new Dictionary(); this.job.EnvironmentVariables[key] = value; + return this; } + /// + /// Adds multiple environment variables to the job. + /// + /// A dictionary of environment variables to add. + /// The current instance of . public JobBuilder AddEnvironmentVariables(Dictionary variables) { this.job.EnvironmentVariables ??= new Dictionary(); @@ -56,6 +83,11 @@ public JobBuilder AddEnvironmentVariables(Dictionary variables) return this; } + /// + /// Adds a checkout step to the job. + /// + /// The name of the checkout step (default: "Check out"). + /// The current instance of . public JobBuilder AddCheckoutStep(string name = "Check out") { this.job.Steps.Add(new CheckoutTaskV2 { Name = name }); @@ -63,6 +95,13 @@ public JobBuilder AddCheckoutStep(string name = "Check out") return this; } + /// + /// Adds a setup step for a specific .NET version to the job. + /// + /// The version of .NET to set up. + /// The name of the setup step (default: "Setup Dot Net Version"). + /// Specifies whether to include prerelease versions. + /// The current instance of . public JobBuilder AddSetupDotNetStep( string version, string stepName = "Setup Dot Net Version", @@ -81,6 +120,11 @@ public JobBuilder AddSetupDotNetStep( return this; } + /// + /// Adds a restore step to the job. + /// + /// The name of the restore step (default: "Restore"). + /// The current instance of . public JobBuilder AddRestoreStep(string name = "Restore") { this.job.Steps.Add(new RestoreTask { Name = name }); @@ -88,6 +132,11 @@ public JobBuilder AddRestoreStep(string name = "Restore") return this; } + /// + /// Adds a build step to the job. + /// + /// The name of the build step (default: "Build"). + /// The current instance of . public JobBuilder AddBuildStep(string name = "Build") { this.job.Steps.Add(new DotNetBuildTask { Name = name }); @@ -95,6 +144,12 @@ public JobBuilder AddBuildStep(string name = "Build") return this; } + /// + /// Adds a test step to the job. + /// + /// The name of the test step (default: "Test"). + /// The command to execute the test (default: "dotnet test --no-build --verbosity normal"). + /// The current instance of . public JobBuilder AddTestStep(string name = "Test", string command = null) { this.job.Steps.Add(new TestTask @@ -106,6 +161,12 @@ public JobBuilder AddTestStep(string name = "Test", string command = null) return this; } + /// + /// Adds a generic step to the job with a custom command. + /// + /// The name of the step. + /// The command to execute for this step. + /// The current instance of . public JobBuilder AddGenericStep(string name, string runCommand) { this.job.Steps.Add(new GithubTask @@ -117,6 +178,10 @@ public JobBuilder AddGenericStep(string name, string runCommand) return this; } + /// + /// Builds and returns the configured job. + /// + /// The configured instance. public Job Build() => this.job; } } \ No newline at end of file From 41821a2adbe39aacfcf08972c17f698ee5e0e82b Mon Sep 17 00:00:00 2001 From: Mabrouk Mahdhi Date: Mon, 27 Jan 2025 19:22:53 +0100 Subject: [PATCH 5/7] CODE RUB: Syntax fix --- ADotNet/Clients/Builders/GitHubPipelineBuilder.cs | 5 ++--- ADotNet/Clients/Builders/JobBuilder.cs | 3 ++- AdoNet.Tests.Console/Program.cs | 1 - 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/ADotNet/Clients/Builders/GitHubPipelineBuilder.cs b/ADotNet/Clients/Builders/GitHubPipelineBuilder.cs index 86e62ae..0d6d99c 100644 --- a/ADotNet/Clients/Builders/GitHubPipelineBuilder.cs +++ b/ADotNet/Clients/Builders/GitHubPipelineBuilder.cs @@ -30,7 +30,8 @@ internal GitHubPipelineBuilder(IADotNetClient aDotNetClient) } /// - /// Creates a new instance of the class with a default . + /// Creates a new instance of the class + /// with a default . /// /// A new instance of . public static GitHubPipelineBuilder CreateNewPipeline() @@ -91,9 +92,7 @@ public GitHubPipelineBuilder OnPullRequest(params string[] branches) public GitHubPipelineBuilder AddJob(string jobIdentifier, Action configureJob) { var jobBuilder = new JobBuilder(); - configureJob(jobBuilder); - this.githubPipeline.Jobs[jobIdentifier] = jobBuilder.Build(); return this; diff --git a/ADotNet/Clients/Builders/JobBuilder.cs b/ADotNet/Clients/Builders/JobBuilder.cs index 9f1d78e..8584e0e 100644 --- a/ADotNet/Clients/Builders/JobBuilder.cs +++ b/ADotNet/Clients/Builders/JobBuilder.cs @@ -148,7 +148,8 @@ public JobBuilder AddBuildStep(string name = "Build") /// Adds a test step to the job. /// /// The name of the test step (default: "Test"). - /// The command to execute the test (default: "dotnet test --no-build --verbosity normal"). + /// The command to execute the test + /// (default: "dotnet test --no-build --verbosity normal"). /// The current instance of . public JobBuilder AddTestStep(string name = "Test", string command = null) { diff --git a/AdoNet.Tests.Console/Program.cs b/AdoNet.Tests.Console/Program.cs index 445eb6e..349c944 100644 --- a/AdoNet.Tests.Console/Program.cs +++ b/AdoNet.Tests.Console/Program.cs @@ -187,7 +187,6 @@ static void Main(string[] args) adoClient.SerializeAndWriteToFile(githubPipeline, "github-pipelines.yaml"); - GitHubPipelineBuilder.CreateNewPipeline() .SetName("Github") .OnPush("master") From b4d75f5b1140b80727edbdf00640f13d26d5bd09 Mon Sep 17 00:00:00 2001 From: Mabrouk Mahdhi Date: Mon, 27 Jan 2025 19:28:36 +0100 Subject: [PATCH 6/7] CODE RUB: Fix Manual Tests Format --- AdoNet.Tests.Console/Program.cs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/AdoNet.Tests.Console/Program.cs b/AdoNet.Tests.Console/Program.cs index 349c944..c581dc1 100644 --- a/AdoNet.Tests.Console/Program.cs +++ b/AdoNet.Tests.Console/Program.cs @@ -187,14 +187,18 @@ static void Main(string[] args) adoClient.SerializeAndWriteToFile(githubPipeline, "github-pipelines.yaml"); + string projectName = "OtripleS.Api.Infrastructure.Provision"; + GitHubPipelineBuilder.CreateNewPipeline() .SetName("Github") .OnPush("master") .OnPullRequest("master") + .AddJob("build", job => job .WithName("Build") .RunsOn(BuildMachines.WindowsLatest) .AddEnvironmentVariable("AzureClientId", "${{ secrets.AZURECLIENTID }}") + .AddEnvironmentVariables(new Dictionary { { "AzureTenantId", "${{ secrets.AZURETENANTID }}" }, @@ -202,15 +206,21 @@ static void Main(string[] args) { "AzureAdminName", "${{ secrets.AZUREADMINNAME }}" }, { "AzureAdminAccess", "${{ secrets.AZUREADMINACCESS }}" } }) + .AddCheckoutStep("Check Out") + .AddSetupDotNetStep( version: "6.0.101", includePrerelease: true) + .AddRestoreStep() .AddBuildStep() + .AddGenericStep( name: "Provision", - runCommand: "dotnet run --project .\\OtripleS.Api.Infrastructure.Provision\\OtripleS.Web.Api.Infrastructure.Provision.csproj")) + runCommand: + "dotnet run --project .\\{projectName}\\{projectName}.csproj")) + .SaveToFile("github-pipelines-fluent.yaml"); } } From 3e04baba3be505db67f2e7c3d342e05e54730653 Mon Sep 17 00:00:00 2001 From: Mabrouk Mahdhi Date: Mon, 27 Jan 2025 19:32:21 +0100 Subject: [PATCH 7/7] CODE RUB: Fix Tests Syntax --- .../Clients/Builders/GitHubPipelineBuilderTests.Logic.cs | 4 ++-- .../Clients/Builders/GitHubPipelineBuilderTests.cs | 5 ++++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/AdoNet.Tests.Unit/Clients/Builders/GitHubPipelineBuilderTests.Logic.cs b/AdoNet.Tests.Unit/Clients/Builders/GitHubPipelineBuilderTests.Logic.cs index eb45ad2..65cd9bb 100644 --- a/AdoNet.Tests.Unit/Clients/Builders/GitHubPipelineBuilderTests.Logic.cs +++ b/AdoNet.Tests.Unit/Clients/Builders/GitHubPipelineBuilderTests.Logic.cs @@ -60,7 +60,6 @@ public void ShouldAddPushTrigger() actualPipeline.OnEvents.Push.Branches.Should().BeEquivalentTo(inputBranches); } - [Fact] public void ShouldAddPullRequestTrigger() { @@ -102,6 +101,7 @@ public void ShouldAddJobToPipeline() actualJob.Should().NotBeNull(); actualJob.RunsOn.Should().Be(expectedRunsOn); actualJob.Steps.Should().HaveCount(1); + actualJob.Steps[0].Should().BeOfType() .Which.Name.Should().Be(expectedTaskName); } @@ -112,11 +112,11 @@ public void ShouldSavePipelineToFile() // given string randomFileName = GetRandomFileName(); string randomPipelineName = GetRandomString(); + GithubPipeline randomPipeline = CreateRandomGithubPipeline(randomPipelineName); GithubPipeline inputPipeline = randomPipeline; - string inputPath = randomFileName; string inputPipelineName = randomPipelineName; diff --git a/AdoNet.Tests.Unit/Clients/Builders/GitHubPipelineBuilderTests.cs b/AdoNet.Tests.Unit/Clients/Builders/GitHubPipelineBuilderTests.cs index 8ed1ebc..f362b5a 100644 --- a/AdoNet.Tests.Unit/Clients/Builders/GitHubPipelineBuilderTests.cs +++ b/AdoNet.Tests.Unit/Clients/Builders/GitHubPipelineBuilderTests.cs @@ -29,7 +29,10 @@ public GitHubPipelineBuilderTests() private static GithubPipeline GetPipeline(GitHubPipelineBuilder builder) { var privateField = typeof(GitHubPipelineBuilder) - .GetField("githubPipeline", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); + .GetField( + name: "githubPipeline", + bindingAttr: System.Reflection.BindingFlags.NonPublic + | System.Reflection.BindingFlags.Instance); return (GithubPipeline)privateField.GetValue(builder); }