diff --git a/src/Cake.Common.Tests/Fixtures/Build/WoodpeckerCICommandsFixture.cs b/src/Cake.Common.Tests/Fixtures/Build/WoodpeckerCICommandsFixture.cs new file mode 100644 index 0000000000..8baf1b185a --- /dev/null +++ b/src/Cake.Common.Tests/Fixtures/Build/WoodpeckerCICommandsFixture.cs @@ -0,0 +1,56 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Cake.Common.Build.WoodpeckerCI.Commands; +using Cake.Common.Build.WoodpeckerCI.Data; +using Cake.Core; +using Cake.Core.IO; +using Cake.Testing; + +namespace Cake.Common.Tests.Fixtures.Build +{ + internal sealed class WoodpeckerCICommandsFixture + { + public ICakeEnvironment Environment { get; set; } + public IFileSystem FileSystem { get; set; } + public WoodpeckerCIEnvironmentInfo WoodpeckerEnvironment { get; set; } + + public WoodpeckerCICommandsFixture() + { + Environment = FakeEnvironment.CreateUnixEnvironment(); + FileSystem = new FakeFileSystem(Environment); + + // Set up the WoodpeckerCI environment variables + ((FakeEnvironment)Environment).SetEnvironmentVariable("CI", "woodpecker"); + ((FakeEnvironment)Environment).SetEnvironmentVariable("CI_WORKSPACE", "/woodpecker/src/git.example.com/john-doe/my-repo"); + + WoodpeckerEnvironment = new WoodpeckerCIEnvironmentInfo(Environment); + + // Create the .woodpecker/env file for testing + var envFile = WoodpeckerEnvironment.Workspace?.CombineWithFilePath(".woodpecker/env"); + if (envFile != null) + { + // Create the directory structure first + var directory = envFile.GetDirectory(); + ((FakeFileSystem)FileSystem).CreateDirectory(directory); + ((FakeFileSystem)FileSystem).CreateFile(envFile); + } + } + + public WoodpeckerCICommands CreateWoodpeckerCICommands() + { + return new WoodpeckerCICommands(Environment, FileSystem, WoodpeckerEnvironment); + } + + public WoodpeckerCICommandsFixture WithNoWoodpeckerEnv() + { + var envFile = Environment.WorkingDirectory.CombineWithFilePath(".woodpecker/env"); + if (FileSystem.Exist(envFile)) + { + FileSystem.GetFile(envFile).Delete(); + } + return this; + } + } +} diff --git a/src/Cake.Common.Tests/Fixtures/Build/WoodpeckerCIInfoFixture.cs b/src/Cake.Common.Tests/Fixtures/Build/WoodpeckerCIInfoFixture.cs new file mode 100644 index 0000000000..d343c3d1c3 --- /dev/null +++ b/src/Cake.Common.Tests/Fixtures/Build/WoodpeckerCIInfoFixture.cs @@ -0,0 +1,132 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Cake.Common.Build.WoodpeckerCI.Data; +using Cake.Core; +using NSubstitute; + +namespace Cake.Common.Tests.Fixtures.Build +{ + public class WoodpeckerCIInfoFixture + { + public ICakeEnvironment Environment { get; set; } + + public WoodpeckerCIInfoFixture() + { + Environment = Substitute.For(); + + // WoodpeckerCI Environment + Environment.GetEnvironmentVariable("CI").Returns("woodpecker"); + Environment.GetEnvironmentVariable("CI_WORKSPACE").Returns("/woodpecker/src/git.example.com/john-doe/my-repo"); + + // WoodpeckerCI RepositoryInfo + Environment.GetEnvironmentVariable("CI_REPO").Returns("john-doe/my-repo"); + Environment.GetEnvironmentVariable("CI_REPO_OWNER").Returns("john-doe"); + Environment.GetEnvironmentVariable("CI_REPO_NAME").Returns("my-repo"); + Environment.GetEnvironmentVariable("CI_REPO_REMOTE_ID").Returns("82"); + Environment.GetEnvironmentVariable("CI_REPO_URL").Returns("https://git.example.com/john-doe/my-repo"); + Environment.GetEnvironmentVariable("CI_REPO_CLONE_URL").Returns("https://git.example.com/john-doe/my-repo.git"); + Environment.GetEnvironmentVariable("CI_REPO_CLONE_SSH_URL").Returns("git@git.example.com:john-doe/my-repo.git"); + Environment.GetEnvironmentVariable("CI_REPO_DEFAULT_BRANCH").Returns("main"); + Environment.GetEnvironmentVariable("CI_REPO_PRIVATE").Returns("true"); + Environment.GetEnvironmentVariable("CI_REPO_TRUSTED_NETWORK").Returns("false"); + Environment.GetEnvironmentVariable("CI_REPO_TRUSTED_VOLUMES").Returns("false"); + Environment.GetEnvironmentVariable("CI_REPO_TRUSTED_SECURITY").Returns("false"); + + // WoodpeckerCI CommitInfo + Environment.GetEnvironmentVariable("CI_COMMIT_SHA").Returns("eba09b46064473a1d345da7abf28b477468e8dbd"); + Environment.GetEnvironmentVariable("CI_COMMIT_REF").Returns("refs/heads/main"); + Environment.GetEnvironmentVariable("CI_COMMIT_REFSPEC").Returns("issue-branch:main"); + Environment.GetEnvironmentVariable("CI_COMMIT_BRANCH").Returns("main"); + Environment.GetEnvironmentVariable("CI_COMMIT_SOURCE_BRANCH").Returns("issue-branch"); + Environment.GetEnvironmentVariable("CI_COMMIT_TARGET_BRANCH").Returns("main"); + Environment.GetEnvironmentVariable("CI_COMMIT_TAG").Returns("v1.10.3"); + Environment.GetEnvironmentVariable("CI_COMMIT_PULL_REQUEST").Returns("1"); + Environment.GetEnvironmentVariable("CI_COMMIT_PULL_REQUEST_LABELS").Returns("server"); + Environment.GetEnvironmentVariable("CI_COMMIT_MESSAGE").Returns("Initial commit"); + Environment.GetEnvironmentVariable("CI_COMMIT_AUTHOR").Returns("john-doe"); + Environment.GetEnvironmentVariable("CI_COMMIT_AUTHOR_EMAIL").Returns("john-doe@example.com"); + Environment.GetEnvironmentVariable("CI_COMMIT_PRERELEASE").Returns("false"); + + // WoodpeckerCI PipelineInfo + Environment.GetEnvironmentVariable("CI_PIPELINE_NUMBER").Returns("8"); + Environment.GetEnvironmentVariable("CI_PIPELINE_PARENT").Returns("0"); + Environment.GetEnvironmentVariable("CI_PIPELINE_EVENT").Returns("push"); + Environment.GetEnvironmentVariable("CI_PIPELINE_URL").Returns("https://ci.example.com/repos/john-doe/my-repo/pipeline/123"); + Environment.GetEnvironmentVariable("CI_PIPELINE_FORGE_URL").Returns("https://git.example.com/john-doe/my-repo/commit/abc123"); + Environment.GetEnvironmentVariable("CI_PIPELINE_DEPLOY_TARGET").Returns("production"); + Environment.GetEnvironmentVariable("CI_PIPELINE_DEPLOY_TASK").Returns("migration"); + Environment.GetEnvironmentVariable("CI_PIPELINE_CREATED").Returns("1722617519"); + Environment.GetEnvironmentVariable("CI_PIPELINE_STARTED").Returns("1722617519"); + Environment.GetEnvironmentVariable("CI_PIPELINE_FILES").Returns("[\".woodpecker.yml\",\"README.md\"]"); + Environment.GetEnvironmentVariable("CI_PIPELINE_AUTHOR").Returns("octocat"); + Environment.GetEnvironmentVariable("CI_PIPELINE_AVATAR").Returns("https://git.example.com/avatars/john-doe"); + + // WoodpeckerCI WorkflowInfo + Environment.GetEnvironmentVariable("CI_WORKFLOW_NAME").Returns("release"); + + // WoodpeckerCI StepInfo + Environment.GetEnvironmentVariable("CI_STEP_NAME").Returns("build package"); + Environment.GetEnvironmentVariable("CI_STEP_NUMBER").Returns("0"); + Environment.GetEnvironmentVariable("CI_STEP_STARTED").Returns("1722617519"); + Environment.GetEnvironmentVariable("CI_STEP_URL").Returns("https://ci.example.com/repos/7/pipeline/8"); + + // WoodpeckerCI SystemInfo + Environment.GetEnvironmentVariable("CI_SYSTEM_NAME").Returns("woodpecker"); + Environment.GetEnvironmentVariable("CI_SYSTEM_URL").Returns("https://ci.example.com"); + Environment.GetEnvironmentVariable("CI_SYSTEM_HOST").Returns("ci.example.com"); + Environment.GetEnvironmentVariable("CI_SYSTEM_VERSION").Returns("2.7.0"); + + // WoodpeckerCI ForgeInfo + Environment.GetEnvironmentVariable("CI_FORGE_TYPE").Returns("github"); + Environment.GetEnvironmentVariable("CI_FORGE_URL").Returns("https://git.example.com"); + } + + public WoodpeckerCIEnvironmentInfo CreateEnvironmentInfo() + { + return new WoodpeckerCIEnvironmentInfo(Environment); + } + + public WoodpeckerCIRepositoryInfo CreateRepositoryInfo() + { + return new WoodpeckerCIRepositoryInfo(Environment); + } + + public WoodpeckerCICommitInfo CreateCommitInfo() + { + return new WoodpeckerCICommitInfo(Environment); + } + + public WoodpeckerCIPipelineInfo CreatePipelineInfo() + { + return new WoodpeckerCIPipelineInfo(Environment); + } + + public WoodpeckerCIWorkflowInfo CreateWorkflowInfo() + { + return new WoodpeckerCIWorkflowInfo(Environment); + } + + public WoodpeckerCIStepInfo CreateStepInfo() + { + return new WoodpeckerCIStepInfo(Environment); + } + + public WoodpeckerCISystemInfo CreateSystemInfo() + { + return new WoodpeckerCISystemInfo(Environment); + } + + public WoodpeckerCIForgeInfo CreateForgeInfo() + { + return new WoodpeckerCIForgeInfo(Environment); + } + + public WoodpeckerCIInfoFixture SetEnvironmentVariable(string name, string value) + { + Environment.GetEnvironmentVariable(name).Returns(value); + return this; + } + } +} diff --git a/src/Cake.Common.Tests/Unit/Build/BuildSystemTests.cs b/src/Cake.Common.Tests/Unit/Build/BuildSystemTests.cs index 9dd8f51de3..8729fea255 100644 --- a/src/Cake.Common.Tests/Unit/Build/BuildSystemTests.cs +++ b/src/Cake.Common.Tests/Unit/Build/BuildSystemTests.cs @@ -16,6 +16,7 @@ using Cake.Common.Build.MyGet; using Cake.Common.Build.TeamCity; using Cake.Common.Build.TravisCI; +using Cake.Common.Build.WoodpeckerCI; using Cake.Common.Tests.Fixtures.Build; using NSubstitute; using Xunit; @@ -42,9 +43,10 @@ public void Should_Throw_If_AppVeyor_Is_Null() var gitLabCIProvider = Substitute.For(); var gitHubActionsProvider = Substitute.For(); var azurePipelinesProvider = Substitute.For(); + var woodpeckerCIProvider = Substitute.For(); // When - var result = Record.Exception(() => new BuildSystem(null, teamCityProvider, myGetProvider, bambooProvider, continuaCIProvider, jenkinsProvider, bitriseProvider, travisCIProvider, bitbucketPipelinesProvider, goCDProvider, gitLabCIProvider, gitHubActionsProvider, azurePipelinesProvider)); + var result = Record.Exception(() => new BuildSystem(null, teamCityProvider, myGetProvider, bambooProvider, continuaCIProvider, jenkinsProvider, bitriseProvider, travisCIProvider, bitbucketPipelinesProvider, goCDProvider, gitLabCIProvider, gitHubActionsProvider, azurePipelinesProvider, woodpeckerCIProvider)); // Then AssertEx.IsArgumentNullException(result, "appVeyorProvider"); @@ -66,9 +68,10 @@ public void Should_Throw_If_TeamCity_Is_Null() var gitLabCIProvider = Substitute.For(); var gitHubActionsProvider = Substitute.For(); var azurePipelinesProvider = Substitute.For(); + var woodpeckerCIProvider = Substitute.For(); // When - var result = Record.Exception(() => new BuildSystem(appVeyorProvider, null, myGetProvider, bambooProvider, continuaCIProvider, jenkinsProvider, bitriseProvider, travisCIProvider, bitbucketPipelinesProvider, goCDProvider, gitLabCIProvider, gitHubActionsProvider, azurePipelinesProvider)); + var result = Record.Exception(() => new BuildSystem(appVeyorProvider, null, myGetProvider, bambooProvider, continuaCIProvider, jenkinsProvider, bitriseProvider, travisCIProvider, bitbucketPipelinesProvider, goCDProvider, gitLabCIProvider, gitHubActionsProvider, azurePipelinesProvider, woodpeckerCIProvider)); // Then AssertEx.IsArgumentNullException(result, "teamCityProvider"); @@ -90,9 +93,10 @@ public void Should_Throw_If_MyGet_Is_Null() var gitLabCIProvider = Substitute.For(); var gitHubActionsProvider = Substitute.For(); var azurePipelinesProvider = Substitute.For(); + var woodpeckerCIProvider = Substitute.For(); // When - var result = Record.Exception(() => new BuildSystem(appVeyorProvider, teamCityProvider, null, bambooProvider, continuaCIProvider, jenkinsProvider, bitriseProvider, travisCIProvider, bitbucketPipelinesProvider, goCDProvider, gitLabCIProvider, gitHubActionsProvider, azurePipelinesProvider)); + var result = Record.Exception(() => new BuildSystem(appVeyorProvider, teamCityProvider, null, bambooProvider, continuaCIProvider, jenkinsProvider, bitriseProvider, travisCIProvider, bitbucketPipelinesProvider, goCDProvider, gitLabCIProvider, gitHubActionsProvider, azurePipelinesProvider, woodpeckerCIProvider)); // Then AssertEx.IsArgumentNullException(result, "myGetProvider"); @@ -114,9 +118,10 @@ public void Should_Throw_If_Bamboo_Is_Null() var gitLabCIProvider = Substitute.For(); var gitHubActionsProvider = Substitute.For(); var azurePipelinesProvider = Substitute.For(); + var woodpeckerCIProvider = Substitute.For(); // When - var result = Record.Exception(() => new BuildSystem(appVeyorProvider, teamCityProvider, myGetProvider, null, continuaCIProvider, jenkinsProvider, bitriseProvider, travisCIProvider, bitbucketPipelinesProvider, goCDProvider, gitLabCIProvider, gitHubActionsProvider, azurePipelinesProvider)); + var result = Record.Exception(() => new BuildSystem(appVeyorProvider, teamCityProvider, myGetProvider, null, continuaCIProvider, jenkinsProvider, bitriseProvider, travisCIProvider, bitbucketPipelinesProvider, goCDProvider, gitLabCIProvider, gitHubActionsProvider, azurePipelinesProvider, woodpeckerCIProvider)); // Then AssertEx.IsArgumentNullException(result, "bambooProvider"); @@ -138,9 +143,10 @@ public void Should_Throw_If_ContinuaCI_Is_Null() var gitLabCIProvider = Substitute.For(); var gitHubActionsProvider = Substitute.For(); var azurePipelinesProvider = Substitute.For(); + var woodpeckerCIProvider = Substitute.For(); // When - var result = Record.Exception(() => new BuildSystem(appVeyorProvider, teamCityProvider, myGetProvider, bambooProvider, null, jenkinsProvider, bitriseProvider, travisCIProvider, bitbucketPipelinesProvider, goCDProvider, gitLabCIProvider, gitHubActionsProvider, azurePipelinesProvider)); + var result = Record.Exception(() => new BuildSystem(appVeyorProvider, teamCityProvider, myGetProvider, bambooProvider, null, jenkinsProvider, bitriseProvider, travisCIProvider, bitbucketPipelinesProvider, goCDProvider, gitLabCIProvider, gitHubActionsProvider, azurePipelinesProvider, woodpeckerCIProvider)); // Then AssertEx.IsArgumentNullException(result, "continuaCIProvider"); @@ -162,9 +168,10 @@ public void Should_Throw_If_Jenkins_Is_Null() var gitLabCIProvider = Substitute.For(); var gitHubActionsProvider = Substitute.For(); var azurePipelinesProvider = Substitute.For(); + var woodpeckerCIProvider = Substitute.For(); // When - var result = Record.Exception(() => new BuildSystem(appVeyorProvider, teamCityProvider, myGetProvider, bambooProvider, continuaCIProvider, null, bitriseProvider, travisCIProvider, bitbucketPipelinesProvider, goCDProvider, gitLabCIProvider, gitHubActionsProvider, azurePipelinesProvider)); + var result = Record.Exception(() => new BuildSystem(appVeyorProvider, teamCityProvider, myGetProvider, bambooProvider, continuaCIProvider, null, bitriseProvider, travisCIProvider, bitbucketPipelinesProvider, goCDProvider, gitLabCIProvider, gitHubActionsProvider, azurePipelinesProvider, woodpeckerCIProvider)); // Then AssertEx.IsArgumentNullException(result, "jenkinsProvider"); @@ -186,9 +193,10 @@ public void Should_Throw_If_Bitrise_Is_Null() var gitLabCIProvider = Substitute.For(); var gitHubActionsProvider = Substitute.For(); var azurePipelinesProvider = Substitute.For(); + var woodpeckerCIProvider = Substitute.For(); // When - var result = Record.Exception(() => new BuildSystem(appVeyorProvider, teamCityProvider, myGetProvider, bambooProvider, continuaCIProvider, jenkinsProvider, null, travisCIProvider, bitbucketPipelinesProvider, goCDProvider, gitLabCIProvider, gitHubActionsProvider, azurePipelinesProvider)); + var result = Record.Exception(() => new BuildSystem(appVeyorProvider, teamCityProvider, myGetProvider, bambooProvider, continuaCIProvider, jenkinsProvider, null, travisCIProvider, bitbucketPipelinesProvider, goCDProvider, gitLabCIProvider, gitHubActionsProvider, azurePipelinesProvider, woodpeckerCIProvider)); // Then AssertEx.IsArgumentNullException(result, "bitriseProvider"); @@ -210,9 +218,10 @@ public void Should_Throw_If_TravisCI_Is_Null() var gitLabCIProvider = Substitute.For(); var gitHubActionsProvider = Substitute.For(); var azurePipelinesProvider = Substitute.For(); + var woodpeckerCIProvider = Substitute.For(); // When - var result = Record.Exception(() => new BuildSystem(appVeyorProvider, teamCityProvider, myGetProvider, bambooProvider, continuaCIProvider, jenkinsProvider, bitriseProvider, null, bitbucketPipelinesProvider, goCDProvider, gitLabCIProvider, gitHubActionsProvider, azurePipelinesProvider)); + var result = Record.Exception(() => new BuildSystem(appVeyorProvider, teamCityProvider, myGetProvider, bambooProvider, continuaCIProvider, jenkinsProvider, bitriseProvider, null, bitbucketPipelinesProvider, goCDProvider, gitLabCIProvider, gitHubActionsProvider, azurePipelinesProvider, woodpeckerCIProvider)); // Then AssertEx.IsArgumentNullException(result, "travisCIProvider"); @@ -234,9 +243,10 @@ public void Should_Throw_If_BitbucketPipelines_Is_Null() var gitLabCIProvider = Substitute.For(); var gitHubActionsProvider = Substitute.For(); var azurePipelinesProvider = Substitute.For(); + var woodpeckerCIProvider = Substitute.For(); // When - var result = Record.Exception(() => new BuildSystem(appVeyorProvider, teamCityProvider, myGetProvider, bambooProvider, continuaCIProvider, jenkinsProvider, bitriseProvider, travisCIProvider, null, goCDProvider, gitLabCIProvider, gitHubActionsProvider, azurePipelinesProvider)); + var result = Record.Exception(() => new BuildSystem(appVeyorProvider, teamCityProvider, myGetProvider, bambooProvider, continuaCIProvider, jenkinsProvider, bitriseProvider, travisCIProvider, null, goCDProvider, gitLabCIProvider, gitHubActionsProvider, azurePipelinesProvider, woodpeckerCIProvider)); // Then AssertEx.IsArgumentNullException(result, "bitbucketPipelinesProvider"); @@ -258,9 +268,10 @@ public void Should_Throw_If_GoCD_Is_Null() var gitLabCIProvider = Substitute.For(); var gitHubActionsProvider = Substitute.For(); var azurePipelinesProvider = Substitute.For(); + var woodpeckerCIProvider = Substitute.For(); // When - var result = Record.Exception(() => new BuildSystem(appVeyorProvider, teamCityProvider, myGetProvider, bambooProvider, continuaCIProvider, jenkinsProvider, bitriseProvider, travisCIProvider, bitbucketPipelinesProvider, null, gitLabCIProvider, gitHubActionsProvider, azurePipelinesProvider)); + var result = Record.Exception(() => new BuildSystem(appVeyorProvider, teamCityProvider, myGetProvider, bambooProvider, continuaCIProvider, jenkinsProvider, bitriseProvider, travisCIProvider, bitbucketPipelinesProvider, null, gitLabCIProvider, gitHubActionsProvider, azurePipelinesProvider, woodpeckerCIProvider)); // Then AssertEx.IsArgumentNullException(result, "goCDProvider"); @@ -282,9 +293,10 @@ public void Should_Throw_If_GitLabCI_Is_Null() var goCDProvider = Substitute.For(); var gitHubActionsProvider = Substitute.For(); var azurePipelinesProvider = Substitute.For(); + var woodpeckerCIProvider = Substitute.For(); // When - var result = Record.Exception(() => new BuildSystem(appVeyorProvider, teamCityProvider, myGetProvider, bambooProvider, continuaCIProvider, jenkinsProvider, bitriseProvider, travisCIProvider, bitbucketPipelinesProvider, goCDProvider, null, gitHubActionsProvider, azurePipelinesProvider)); + var result = Record.Exception(() => new BuildSystem(appVeyorProvider, teamCityProvider, myGetProvider, bambooProvider, continuaCIProvider, jenkinsProvider, bitriseProvider, travisCIProvider, bitbucketPipelinesProvider, goCDProvider, null, gitHubActionsProvider, azurePipelinesProvider, woodpeckerCIProvider)); // Then AssertEx.IsArgumentNullException(result, "gitLabCIProvider"); @@ -306,9 +318,10 @@ public void Should_Throw_If_AzurePipelines_Is_Null() var goCDProvider = Substitute.For(); var gitLabCIProvider = Substitute.For(); var gitHubActionsProvider = Substitute.For(); + var woodpeckerCIProvider = Substitute.For(); // When - var result = Record.Exception(() => new BuildSystem(appVeyorProvider, teamCityProvider, myGetProvider, bambooProvider, continuaCIProvider, jenkinsProvider, bitriseProvider, travisCIProvider, bitbucketPipelinesProvider, goCDProvider, gitLabCIProvider, gitHubActionsProvider, null)); + var result = Record.Exception(() => new BuildSystem(appVeyorProvider, teamCityProvider, myGetProvider, bambooProvider, continuaCIProvider, jenkinsProvider, bitriseProvider, travisCIProvider, bitbucketPipelinesProvider, goCDProvider, gitLabCIProvider, gitHubActionsProvider, null, woodpeckerCIProvider)); // Then AssertEx.IsArgumentNullException(result, "azurePipelinesProvider"); @@ -330,13 +343,39 @@ public void Should_Throw_If_GitHubActions_Is_Null() var goCDProvider = Substitute.For(); var gitLabCIProvider = Substitute.For(); var azurePipelinesProvider = Substitute.For(); + var woodpeckerCIProvider = Substitute.For(); // When - var result = Record.Exception(() => new BuildSystem(appVeyorProvider, teamCityProvider, myGetProvider, bambooProvider, continuaCIProvider, jenkinsProvider, bitriseProvider, travisCIProvider, bitbucketPipelinesProvider, goCDProvider, gitLabCIProvider, null, azurePipelinesProvider)); + var result = Record.Exception(() => new BuildSystem(appVeyorProvider, teamCityProvider, myGetProvider, bambooProvider, continuaCIProvider, jenkinsProvider, bitriseProvider, travisCIProvider, bitbucketPipelinesProvider, goCDProvider, gitLabCIProvider, null, azurePipelinesProvider, woodpeckerCIProvider)); // Then AssertEx.IsArgumentNullException(result, "gitHubActionsProvider"); } + + [Fact] + public void Should_Throw_If_WoodpeckerCI_Is_Null() + { + // Given + var appVeyorProvider = Substitute.For(); + var teamCityProvider = Substitute.For(); + var myGetProvider = Substitute.For(); + var bambooProvider = Substitute.For(); + var continuaCIProvider = Substitute.For(); + var jenkinsProvider = Substitute.For(); + var bitriseProvider = Substitute.For(); + var travisCIProvider = Substitute.For(); + var bitbucketPipelinesProvider = Substitute.For(); + var goCDProvider = Substitute.For(); + var gitLabCIProvider = Substitute.For(); + var gitHubActionsProvider = Substitute.For(); + var azurePipelinesProvider = Substitute.For(); + + // When + var result = Record.Exception(() => new BuildSystem(appVeyorProvider, teamCityProvider, myGetProvider, bambooProvider, continuaCIProvider, jenkinsProvider, bitriseProvider, travisCIProvider, bitbucketPipelinesProvider, goCDProvider, gitLabCIProvider, gitHubActionsProvider, azurePipelinesProvider, null)); + + // Then + AssertEx.IsArgumentNullException(result, "woodpeckerCIProvider"); + } } public sealed class TheIsRunningOnAppVeyorProperty @@ -359,12 +398,13 @@ public void Should_Return_True_If_Running_On_AppVeyor() var gitLabCIProvider = Substitute.For(); var gitHubActionsProvider = Substitute.For(); var azurePipelinesProvider = Substitute.For(); + var woodpeckerCIProvider = Substitute.For(); appVeyorProvider.IsRunningOnAppVeyor.Returns(true); appVeyorProvider.Environment.Returns(appVeyorEnvironment); // When - var buildSystem = new BuildSystem(appVeyorProvider, teamCityProvider, myGetProvider, bambooProvider, continuaCIProvider, jenkinsProvider, bitriseProvider, travisCIProvider, bitbucketPipelinesProvider, goCDProvider, gitLabCIProvider, gitHubActionsProvider, azurePipelinesProvider); + var buildSystem = new BuildSystem(appVeyorProvider, teamCityProvider, myGetProvider, bambooProvider, continuaCIProvider, jenkinsProvider, bitriseProvider, travisCIProvider, bitbucketPipelinesProvider, goCDProvider, gitLabCIProvider, gitHubActionsProvider, azurePipelinesProvider, woodpeckerCIProvider); // Then Assert.True(buildSystem.IsRunningOnAppVeyor); @@ -391,12 +431,13 @@ public void Should_Return_True_If_Running_On_TeamCity() var gitLabCIProvider = Substitute.For(); var gitHubActionsProvider = Substitute.For(); var azurePipelinesProvider = Substitute.For(); + var woodpeckerCIProvider = Substitute.For(); teamCityProvider.IsRunningOnTeamCity.Returns(true); teamCityProvider.Environment.Returns(teamCityEnvironment); // When - var buildSystem = new BuildSystem(appVeyorProvider, teamCityProvider, myGetProvider, bambooProvider, continuaCIProvider, jenkinsProvider, bitriseProvider, travisCIProvider, bitbucketPipelinesProvider, goCDProvider, gitLabCIProvider, gitHubActionsProvider, azurePipelinesProvider); + var buildSystem = new BuildSystem(appVeyorProvider, teamCityProvider, myGetProvider, bambooProvider, continuaCIProvider, jenkinsProvider, bitriseProvider, travisCIProvider, bitbucketPipelinesProvider, goCDProvider, gitLabCIProvider, gitHubActionsProvider, azurePipelinesProvider, woodpeckerCIProvider); // Then Assert.True(buildSystem.IsRunningOnTeamCity); @@ -422,11 +463,12 @@ public void Should_Return_True_If_Running_On_MyGet() var gitLabCIProvider = Substitute.For(); var gitHubActionsProvider = Substitute.For(); var azurePipelinesProvider = Substitute.For(); + var woodpeckerCIProvider = Substitute.For(); myGetProvider.IsRunningOnMyGet.Returns(true); // When - var buildSystem = new BuildSystem(appVeyorProvider, teamCityProvider, myGetProvider, bambooProvider, continuaCIProvider, jenkinsProvider, bitriseProvider, travisCIProvider, bitbucketPipelinesProvider, goCDProvider, gitLabCIProvider, gitHubActionsProvider, azurePipelinesProvider); + var buildSystem = new BuildSystem(appVeyorProvider, teamCityProvider, myGetProvider, bambooProvider, continuaCIProvider, jenkinsProvider, bitriseProvider, travisCIProvider, bitbucketPipelinesProvider, goCDProvider, gitLabCIProvider, gitHubActionsProvider, azurePipelinesProvider, woodpeckerCIProvider); // Then Assert.True(buildSystem.IsRunningOnMyGet); @@ -452,11 +494,12 @@ public void Should_Return_True_If_Running_On_Bamboo() var gitLabCIProvider = Substitute.For(); var gitHubActionsProvider = Substitute.For(); var azurePipelinesProvider = Substitute.For(); + var woodpeckerCIProvider = Substitute.For(); bambooProvider.IsRunningOnBamboo.Returns(true); // When - var buildSystem = new BuildSystem(appVeyorProvider, teamCityProvider, myGetProvider, bambooProvider, continuaCIProvider, jenkinsProvider, bitriseProvider, travisCIProvider, bitbucketPipelinesProvider, goCDProvider, gitLabCIProvider, gitHubActionsProvider, azurePipelinesProvider); + var buildSystem = new BuildSystem(appVeyorProvider, teamCityProvider, myGetProvider, bambooProvider, continuaCIProvider, jenkinsProvider, bitriseProvider, travisCIProvider, bitbucketPipelinesProvider, goCDProvider, gitLabCIProvider, gitHubActionsProvider, azurePipelinesProvider, woodpeckerCIProvider); // Then Assert.True(buildSystem.IsRunningOnBamboo); @@ -482,11 +525,12 @@ public void Should_Return_True_If_Running_On_ContinuaCI() var gitLabCIProvider = Substitute.For(); var gitHubActionsProvider = Substitute.For(); var azurePipelinesProvider = Substitute.For(); + var woodpeckerCIProvider = Substitute.For(); continuaCIProvider.IsRunningOnContinuaCI.Returns(true); // When - var buildSystem = new BuildSystem(appVeyorProvider, teamCityProvider, myGetProvider, bambooProvider, continuaCIProvider, jenkinsProvider, bitriseProvider, travisCIProvider, bitbucketPipelinesProvider, goCDProvider, gitLabCIProvider, gitHubActionsProvider, azurePipelinesProvider); + var buildSystem = new BuildSystem(appVeyorProvider, teamCityProvider, myGetProvider, bambooProvider, continuaCIProvider, jenkinsProvider, bitriseProvider, travisCIProvider, bitbucketPipelinesProvider, goCDProvider, gitLabCIProvider, gitHubActionsProvider, azurePipelinesProvider, woodpeckerCIProvider); // Then Assert.True(buildSystem.IsRunningOnContinuaCI); @@ -513,12 +557,13 @@ public void Should_Return_True_If_Running_On_Jenkins() var gitLabCIProvider = Substitute.For(); var gitHubActionsProvider = Substitute.For(); var azurePipelinesProvider = Substitute.For(); + var woodpeckerCIProvider = Substitute.For(); jenkinsProvider.IsRunningOnJenkins.Returns(true); jenkinsProvider.Environment.Returns(jenkinsEnvironment); // When - var buildSystem = new BuildSystem(appVeyorProvider, teamCityProvider, myGetProvider, bambooProvider, continuaCIProvider, jenkinsProvider, bitriseProvider, travisCIProvider, bitbucketPipelinesProvider, goCDProvider, gitLabCIProvider, gitHubActionsProvider, azurePipelinesProvider); + var buildSystem = new BuildSystem(appVeyorProvider, teamCityProvider, myGetProvider, bambooProvider, continuaCIProvider, jenkinsProvider, bitriseProvider, travisCIProvider, bitbucketPipelinesProvider, goCDProvider, gitLabCIProvider, gitHubActionsProvider, azurePipelinesProvider, woodpeckerCIProvider); // Then Assert.True(buildSystem.IsRunningOnJenkins); @@ -545,12 +590,13 @@ public void Should_Return_True_If_Running_On_Bitrise() var gitLabCIProvider = Substitute.For(); var gitHubActionsProvider = Substitute.For(); var azurePipelinesProvider = Substitute.For(); + var woodpeckerCIProvider = Substitute.For(); bitriseProvider.IsRunningOnBitrise.Returns(true); bitriseProvider.Environment.Returns(bitriseEnvironment); // When - var buildSystem = new BuildSystem(appVeyorProvider, teamCityProvider, myGetProvider, bambooProvider, continuaCIProvider, jenkinsProvider, bitriseProvider, travisCIProvider, bitbucketPipelinesProvider, goCDProvider, gitLabCIProvider, gitHubActionsProvider, azurePipelinesProvider); + var buildSystem = new BuildSystem(appVeyorProvider, teamCityProvider, myGetProvider, bambooProvider, continuaCIProvider, jenkinsProvider, bitriseProvider, travisCIProvider, bitbucketPipelinesProvider, goCDProvider, gitLabCIProvider, gitHubActionsProvider, azurePipelinesProvider, woodpeckerCIProvider); // Then Assert.True(buildSystem.IsRunningOnBitrise); @@ -577,12 +623,13 @@ public void Should_Return_True_If_Running_On_TravisCI() var gitLabCIProvider = Substitute.For(); var gitHubActionsProvider = Substitute.For(); var azurePipelinesProvider = Substitute.For(); + var woodpeckerCIProvider = Substitute.For(); travisCIProvider.IsRunningOnTravisCI.Returns(true); travisCIProvider.Environment.Returns(travisCIEnvironment); // When - var buildSystem = new BuildSystem(appVeyorProvider, teamCityProvider, myGetProvider, bambooProvider, continuaCIProvider, jenkinsProvider, bitriseProvider, travisCIProvider, bitbucketPipelinesProvider, goCDProvider, gitLabCIProvider, gitHubActionsProvider, azurePipelinesProvider); + var buildSystem = new BuildSystem(appVeyorProvider, teamCityProvider, myGetProvider, bambooProvider, continuaCIProvider, jenkinsProvider, bitriseProvider, travisCIProvider, bitbucketPipelinesProvider, goCDProvider, gitLabCIProvider, gitHubActionsProvider, azurePipelinesProvider, woodpeckerCIProvider); // Then Assert.True(buildSystem.IsRunningOnTravisCI); @@ -609,12 +656,13 @@ public void Should_Return_True_If_Running_On_BitbucketPipelines() var gitLabCIProvider = Substitute.For(); var gitHubActionsProvider = Substitute.For(); var azurePipelinesProvider = Substitute.For(); + var woodpeckerCIProvider = Substitute.For(); bitbucketPipelinesProvider.IsRunningOnBitbucketPipelines.Returns(true); bitbucketPipelinesProvider.Environment.Returns(bitbucketPipelinesEnvironment); // When - var buildSystem = new BuildSystem(appVeyorProvider, teamCityProvider, myGetProvider, bambooProvider, continuaCIProvider, jenkinsProvider, bitriseProvider, travisCIProvider, bitbucketPipelinesProvider, goCDProvider, gitLabCIProvider, gitHubActionsProvider, azurePipelinesProvider); + var buildSystem = new BuildSystem(appVeyorProvider, teamCityProvider, myGetProvider, bambooProvider, continuaCIProvider, jenkinsProvider, bitriseProvider, travisCIProvider, bitbucketPipelinesProvider, goCDProvider, gitLabCIProvider, gitHubActionsProvider, azurePipelinesProvider, woodpeckerCIProvider); // Then Assert.True(buildSystem.IsRunningOnBitbucketPipelines); @@ -640,11 +688,12 @@ public void Should_Return_True_If_Running_On_GoCD() var gitLabCIProvider = Substitute.For(); var gitHubActionsProvider = Substitute.For(); var azurePipelinesProvider = Substitute.For(); + var woodpeckerCIProvider = Substitute.For(); goCDProvider.IsRunningOnGoCD.Returns(true); // When - var buildSystem = new BuildSystem(appVeyorProvider, teamCityProvider, myGetProvider, bambooProvider, continuaCIProvider, jenkinsProvider, bitriseProvider, travisCIProvider, bitbucketPipelinesProvider, goCDProvider, gitLabCIProvider, gitHubActionsProvider, azurePipelinesProvider); + var buildSystem = new BuildSystem(appVeyorProvider, teamCityProvider, myGetProvider, bambooProvider, continuaCIProvider, jenkinsProvider, bitriseProvider, travisCIProvider, bitbucketPipelinesProvider, goCDProvider, gitLabCIProvider, gitHubActionsProvider, azurePipelinesProvider, woodpeckerCIProvider); // Then Assert.True(buildSystem.IsRunningOnGoCD); @@ -671,12 +720,13 @@ public void Should_Return_True_If_Running_On_GitLabCI() var gitLabCIEnvironment = new GitLabCIInfoFixture().CreateEnvironmentInfo(); var gitHubActionsProvider = Substitute.For(); var azurePipelinesProvider = Substitute.For(); + var woodpeckerCIProvider = Substitute.For(); gitLabCIProvider.IsRunningOnGitLabCI.Returns(true); gitLabCIProvider.Environment.Returns(gitLabCIEnvironment); // When - var buildSystem = new BuildSystem(appVeyorProvider, teamCityProvider, myGetProvider, bambooProvider, continuaCIProvider, jenkinsProvider, bitriseProvider, travisCIProvider, bitbucketPipelinesProvider, goCDProvider, gitLabCIProvider, gitHubActionsProvider, azurePipelinesProvider); + var buildSystem = new BuildSystem(appVeyorProvider, teamCityProvider, myGetProvider, bambooProvider, continuaCIProvider, jenkinsProvider, bitriseProvider, travisCIProvider, bitbucketPipelinesProvider, goCDProvider, gitLabCIProvider, gitHubActionsProvider, azurePipelinesProvider, woodpeckerCIProvider); // Then Assert.True(buildSystem.IsRunningOnGitLabCI); @@ -703,12 +753,13 @@ public void Should_Return_True_If_Running_On_AzurePipelines() var gitHubActionsProvider = Substitute.For(); var azurePipelinesProvider = Substitute.For(); var azurePipelinesEnvironment = new AzurePipelinesInfoFixture().CreateEnvironmentInfo(); + var woodpeckerCIProvider = Substitute.For(); azurePipelinesProvider.IsRunningOnAzurePipelines.Returns(true); azurePipelinesProvider.Environment.Returns(azurePipelinesEnvironment); // When - var buildSystem = new BuildSystem(appVeyorProvider, teamCityProvider, myGetProvider, bambooProvider, continuaCIProvider, jenkinsProvider, bitriseProvider, travisCIProvider, bitbucketPipelinesProvider, goCDProvider, gitLabCIProvider, gitHubActionsProvider, azurePipelinesProvider); + var buildSystem = new BuildSystem(appVeyorProvider, teamCityProvider, myGetProvider, bambooProvider, continuaCIProvider, jenkinsProvider, bitriseProvider, travisCIProvider, bitbucketPipelinesProvider, goCDProvider, gitLabCIProvider, gitHubActionsProvider, azurePipelinesProvider, woodpeckerCIProvider); // Then Assert.True(buildSystem.IsRunningOnAzurePipelines); @@ -735,12 +786,13 @@ public void Should_Return_True_If_Running_On_GitHubActions() var azurePipelinesProvider = Substitute.For(); var gitHubActionsProvider = Substitute.For(); var gitHubActionsEnvironment = new GitHubActionsInfoFixture().CreateEnvironmentInfo(); + var woodpeckerCIProvider = Substitute.For(); gitHubActionsProvider.IsRunningOnGitHubActions.Returns(true); gitHubActionsProvider.Environment.Returns(gitHubActionsEnvironment); // When - var buildSystem = new BuildSystem(appVeyorProvider, teamCityProvider, myGetProvider, bambooProvider, continuaCIProvider, jenkinsProvider, bitriseProvider, travisCIProvider, bitbucketPipelinesProvider, goCDProvider, gitLabCIProvider, gitHubActionsProvider, azurePipelinesProvider); + var buildSystem = new BuildSystem(appVeyorProvider, teamCityProvider, myGetProvider, bambooProvider, continuaCIProvider, jenkinsProvider, bitriseProvider, travisCIProvider, bitbucketPipelinesProvider, goCDProvider, gitLabCIProvider, gitHubActionsProvider, azurePipelinesProvider, woodpeckerCIProvider); // Then Assert.True(buildSystem.IsRunningOnGitHubActions); @@ -750,21 +802,22 @@ public void Should_Return_True_If_Running_On_GitHubActions() public sealed class TheProviderProperty { [Theory] - [InlineData(false, false, false, false, false, false, false, false, false, false, false, false, false, BuildProvider.Local)] - [InlineData(true, false, false, false, false, false, false, false, false, false, false, false, false, BuildProvider.AppVeyor)] - [InlineData(false, true, false, false, false, false, false, false, false, false, false, false, false, BuildProvider.TeamCity)] - [InlineData(false, false, true, false, false, false, false, false, false, false, false, false, false, BuildProvider.MyGet)] - [InlineData(false, false, false, true, false, false, false, false, false, false, false, false, false, BuildProvider.Bamboo)] - [InlineData(false, false, false, false, true, false, false, false, false, false, false, false, false, BuildProvider.ContinuaCI)] - [InlineData(false, false, false, false, false, true, false, false, false, false, false, false, false, BuildProvider.Jenkins)] - [InlineData(false, false, false, false, false, false, true, false, false, false, false, false, false, BuildProvider.Bitrise)] - [InlineData(false, false, false, false, false, false, false, true, false, false, false, false, false, BuildProvider.TravisCI)] - [InlineData(false, false, false, false, false, false, false, false, true, false, false, false, false, BuildProvider.BitbucketPipelines)] - [InlineData(false, false, false, false, false, false, false, false, false, true, false, false, false, BuildProvider.GoCD)] - [InlineData(false, false, false, false, false, false, false, false, false, false, true, false, false, BuildProvider.GitLabCI)] - [InlineData(false, false, false, false, false, false, false, false, false, false, false, true, false, BuildProvider.AzurePipelines)] - [InlineData(false, false, false, false, false, false, false, false, false, false, false, false, true, BuildProvider.GitHubActions)] - public void Should_Return_Provider_If_Running_On_Provider(bool appVeyor, bool teamCity, bool myGet, bool bamboo, bool continuaCI, bool jenkins, bool bitrise, bool travisCI, bool bitbucketPipelines, bool goCD, bool gitLabCI, bool azurePipelines, bool gitHubActions, BuildProvider provider) + [InlineData(false, false, false, false, false, false, false, false, false, false, false, false, false, false, BuildProvider.Local)] + [InlineData(true, false, false, false, false, false, false, false, false, false, false, false, false, false, BuildProvider.AppVeyor)] + [InlineData(false, true, false, false, false, false, false, false, false, false, false, false, false, false, BuildProvider.TeamCity)] + [InlineData(false, false, true, false, false, false, false, false, false, false, false, false, false, false, BuildProvider.MyGet)] + [InlineData(false, false, false, true, false, false, false, false, false, false, false, false, false, false, BuildProvider.Bamboo)] + [InlineData(false, false, false, false, true, false, false, false, false, false, false, false, false, false, BuildProvider.ContinuaCI)] + [InlineData(false, false, false, false, false, true, false, false, false, false, false, false, false, false, BuildProvider.Jenkins)] + [InlineData(false, false, false, false, false, false, true, false, false, false, false, false, false, false, BuildProvider.Bitrise)] + [InlineData(false, false, false, false, false, false, false, true, false, false, false, false, false, false, BuildProvider.TravisCI)] + [InlineData(false, false, false, false, false, false, false, false, true, false, false, false, false, false, BuildProvider.BitbucketPipelines)] + [InlineData(false, false, false, false, false, false, false, false, false, true, false, false, false, false, BuildProvider.GoCD)] + [InlineData(false, false, false, false, false, false, false, false, false, false, true, false, false, false, BuildProvider.GitLabCI)] + [InlineData(false, false, false, false, false, false, false, false, false, false, false, true, false, false, BuildProvider.AzurePipelines)] + [InlineData(false, false, false, false, false, false, false, false, false, false, false, false, true, false, BuildProvider.GitHubActions)] + [InlineData(false, false, false, false, false, false, false, false, false, false, false, false, false, true, BuildProvider.WoodpeckerCI)] + public void Should_Return_Provider_If_Running_On_Provider(bool appVeyor, bool teamCity, bool myGet, bool bamboo, bool continuaCI, bool jenkins, bool bitrise, bool travisCI, bool bitbucketPipelines, bool goCD, bool gitLabCI, bool azurePipelines, bool gitHubActions, bool woodpeckerCI, BuildProvider provider) { // Given var appVeyorProvider = Substitute.For(); @@ -812,9 +865,13 @@ public void Should_Return_Provider_If_Running_On_Provider(bool appVeyor, bool te gitHubActionsProvider.Environment.Returns(gitHubActionsEnvironment); azurePipelinesProvider.IsRunningOnAzurePipelines.Returns(azurePipelines); azurePipelinesProvider.Environment.Returns(azurePipelinesEnvironment); + var woodpeckerCIProvider = Substitute.For(); + var woodpeckerCIEnvironment = new WoodpeckerCIInfoFixture().CreateEnvironmentInfo(); + woodpeckerCIProvider.IsRunningOnWoodpeckerCI.Returns(woodpeckerCI); + woodpeckerCIProvider.Environment.Returns(woodpeckerCIEnvironment); // When - var buildSystem = new BuildSystem(appVeyorProvider, teamCityProvider, myGetProvider, bambooProvider, continuaCIProvider, jenkinsProvider, bitriseProvider, travisCIProvider, bitbucketPipelinesProvider, goCDProvider, gitLabCIProvider, gitHubActionsProvider, azurePipelinesProvider); + var buildSystem = new BuildSystem(appVeyorProvider, teamCityProvider, myGetProvider, bambooProvider, continuaCIProvider, jenkinsProvider, bitriseProvider, travisCIProvider, bitbucketPipelinesProvider, goCDProvider, gitLabCIProvider, gitHubActionsProvider, azurePipelinesProvider, woodpeckerCIProvider); // Then Assert.Equal(provider, buildSystem.Provider); @@ -824,21 +881,22 @@ public void Should_Return_Provider_If_Running_On_Provider(bool appVeyor, bool te public sealed class TheIsLocalBuildProperty { [Theory] - [InlineData(false, false, false, false, false, false, false, false, false, false, false, false, false, true)] - [InlineData(true, false, false, false, false, false, false, false, false, false, false, false, false, false)] - [InlineData(false, true, false, false, false, false, false, false, false, false, false, false, false, false)] - [InlineData(false, false, true, false, false, false, false, false, false, false, false, false, false, false)] - [InlineData(false, false, false, true, false, false, false, false, false, false, false, false, false, false)] - [InlineData(false, false, false, false, true, false, false, false, false, false, false, false, false, false)] - [InlineData(false, false, false, false, false, true, false, false, false, false, false, false, false, false)] - [InlineData(false, false, false, false, false, false, true, false, false, false, false, false, false, false)] - [InlineData(false, false, false, false, false, false, false, true, false, false, false, false, false, false)] - [InlineData(false, false, false, false, false, false, false, false, true, false, false, false, false, false)] - [InlineData(false, false, false, false, false, false, false, false, false, true, false, false, false, false)] - [InlineData(false, false, false, false, false, false, false, false, false, false, true, false, false, false)] - [InlineData(false, false, false, false, false, false, false, false, false, false, false, true, false, false)] - [InlineData(false, false, false, false, false, false, false, false, false, false, false, false, true, false)] - public void Should_Return_Whether_Or_Not_Running_On_Provider(bool appVeyor, bool teamCity, bool myGet, bool bamboo, bool continuaCI, bool jenkins, bool bitrise, bool travisCI, bool bitbucketPipelines, bool goCD, bool gitLabCI, bool azurePipelines, bool gitHubActions, bool isLocalBuild) + [InlineData(false, false, false, false, false, false, false, false, false, false, false, false, false, false, true)] + [InlineData(true, false, false, false, false, false, false, false, false, false, false, false, false, false, false)] + [InlineData(false, true, false, false, false, false, false, false, false, false, false, false, false, false, false)] + [InlineData(false, false, true, false, false, false, false, false, false, false, false, false, false, false, false)] + [InlineData(false, false, false, true, false, false, false, false, false, false, false, false, false, false, false)] + [InlineData(false, false, false, false, true, false, false, false, false, false, false, false, false, false, false)] + [InlineData(false, false, false, false, false, true, false, false, false, false, false, false, false, false, false)] + [InlineData(false, false, false, false, false, false, true, false, false, false, false, false, false, false, false)] + [InlineData(false, false, false, false, false, false, false, true, false, false, false, false, false, false, false)] + [InlineData(false, false, false, false, false, false, false, false, true, false, false, false, false, false, false)] + [InlineData(false, false, false, false, false, false, false, false, false, true, false, false, false, false, false)] + [InlineData(false, false, false, false, false, false, false, false, false, false, true, false, false, false, false)] + [InlineData(false, false, false, false, false, false, false, false, false, false, false, true, false, false, false)] + [InlineData(false, false, false, false, false, false, false, false, false, false, false, false, true, false, false)] + [InlineData(false, false, false, false, false, false, false, false, false, false, false, false, false, true, false)] + public void Should_Return_Whether_Or_Not_Running_On_Provider(bool appVeyor, bool teamCity, bool myGet, bool bamboo, bool continuaCI, bool jenkins, bool bitrise, bool travisCI, bool bitbucketPipelines, bool goCD, bool gitLabCI, bool azurePipelines, bool gitHubActions, bool woodpeckerCI, bool isLocalBuild) { // Given var appVeyorProvider = Substitute.For(); @@ -886,34 +944,72 @@ public void Should_Return_Whether_Or_Not_Running_On_Provider(bool appVeyor, bool gitHubActionsProvider.Environment.Returns(gitHubActionsEnvironment); azurePipelinesProvider.IsRunningOnAzurePipelines.Returns(azurePipelines); azurePipelinesProvider.Environment.Returns(azurePipelinesEnvironment); + var woodpeckerCIProvider = Substitute.For(); + var woodpeckerCIEnvironment = new WoodpeckerCIInfoFixture().CreateEnvironmentInfo(); + woodpeckerCIProvider.IsRunningOnWoodpeckerCI.Returns(woodpeckerCI); + woodpeckerCIProvider.Environment.Returns(woodpeckerCIEnvironment); // When System.Console.WriteLine(jenkinsProvider); - var buildSystem = new BuildSystem(appVeyorProvider, teamCityProvider, myGetProvider, bambooProvider, continuaCIProvider, jenkinsProvider, bitriseProvider, travisCIProvider, bitbucketPipelinesProvider, goCDProvider, gitLabCIProvider, gitHubActionsProvider, azurePipelinesProvider); + var buildSystem = new BuildSystem(appVeyorProvider, teamCityProvider, myGetProvider, bambooProvider, continuaCIProvider, jenkinsProvider, bitriseProvider, travisCIProvider, bitbucketPipelinesProvider, goCDProvider, gitLabCIProvider, gitHubActionsProvider, azurePipelinesProvider, woodpeckerCIProvider); // Then Assert.Equal(isLocalBuild, buildSystem.IsLocalBuild); } } + public sealed class TheIsRunningOnWoodpeckerCIProperty + { + [Fact] + public void Should_Return_True_If_Running_On_WoodpeckerCI() + { + // Given + var appVeyorProvider = Substitute.For(); + var teamCityProvider = Substitute.For(); + var myGetProvider = Substitute.For(); + var bambooProvider = Substitute.For(); + var continuaCIProvider = Substitute.For(); + var jenkinsProvider = Substitute.For(); + var bitriseProvider = Substitute.For(); + var travisCIProvider = Substitute.For(); + var bitbucketPipelinesProvider = Substitute.For(); + var goCDProvider = Substitute.For(); + var gitLabCIProvider = Substitute.For(); + var gitHubActionsProvider = Substitute.For(); + var azurePipelinesProvider = Substitute.For(); + var woodpeckerCIProvider = Substitute.For(); + var woodpeckerCIEnvironment = new WoodpeckerCIInfoFixture().CreateEnvironmentInfo(); + + woodpeckerCIProvider.IsRunningOnWoodpeckerCI.Returns(true); + woodpeckerCIProvider.Environment.Returns(woodpeckerCIEnvironment); + + // When + var buildSystem = new BuildSystem(appVeyorProvider, teamCityProvider, myGetProvider, bambooProvider, continuaCIProvider, jenkinsProvider, bitriseProvider, travisCIProvider, bitbucketPipelinesProvider, goCDProvider, gitLabCIProvider, gitHubActionsProvider, azurePipelinesProvider, woodpeckerCIProvider); + + // Then + Assert.True(buildSystem.IsRunningOnWoodpeckerCI); + } + } + public sealed class TheIsPullRequestProperty { [Theory] - [InlineData(false, false, false, false, false, false, false, false, false, false, false, false, false, false)] // none - [InlineData(true, false, false, false, false, false, false, false, false, false, false, false, false, true)] // appveyor - [InlineData(false, true, false, false, false, false, false, false, false, false, false, false, false, true)] // teamcity - [InlineData(false, false, true, false, false, false, false, false, false, false, false, false, false, false)] // myget - [InlineData(false, false, false, true, false, false, false, false, false, false, false, false, false, false)] // bamboo - [InlineData(false, false, false, false, true, false, false, false, false, false, false, false, false, false)] // continua - [InlineData(false, false, false, false, false, true, false, false, false, false, false, false, false, true)] // jenkins - [InlineData(false, false, false, false, false, false, true, false, false, false, false, false, false, true)] // bitrise - [InlineData(false, false, false, false, false, false, false, true, false, false, false, false, false, true)] // travis - [InlineData(false, false, false, false, false, false, false, false, true, false, false, false, false, true)] // bitbucket - [InlineData(false, false, false, false, false, false, false, false, false, true, false, false, false, false)] // gocd - [InlineData(false, false, false, false, false, false, false, false, false, false, true, false, false, true)] // gitlab - [InlineData(false, false, false, false, false, false, false, false, false, false, false, true, false, true)] // az pipelines - [InlineData(false, false, false, false, false, false, false, false, false, false, false, false, true, true)] // gh actions - public void Should_Return_True_If_Running_On_Supported_Provider(bool appVeyor, bool teamCity, bool myGet, bool bamboo, bool continuaCI, bool jenkins, bool bitrise, bool travisCI, bool bitbucketPipelines, bool goCD, bool gitLabCI, bool azurePipelines, bool gitHubActions, bool isPullRequest) + [InlineData(false, false, false, false, false, false, false, false, false, false, false, false, false, false, false)] // none + [InlineData(true, false, false, false, false, false, false, false, false, false, false, false, false, false, true)] // appveyor + [InlineData(false, true, false, false, false, false, false, false, false, false, false, false, false, false, true)] // teamcity + [InlineData(false, false, true, false, false, false, false, false, false, false, false, false, false, false, false)] // myget + [InlineData(false, false, false, true, false, false, false, false, false, false, false, false, false, false, false)] // bamboo + [InlineData(false, false, false, false, true, false, false, false, false, false, false, false, false, false, false)] // continua + [InlineData(false, false, false, false, false, true, false, false, false, false, false, false, false, false, true)] // jenkins + [InlineData(false, false, false, false, false, false, true, false, false, false, false, false, false, false, true)] // bitrise + [InlineData(false, false, false, false, false, false, false, true, false, false, false, false, false, false, true)] // travis + [InlineData(false, false, false, false, false, false, false, false, true, false, false, false, false, false, true)] // bitbucket + [InlineData(false, false, false, false, false, false, false, false, false, true, false, false, false, false, false)] // gocd + [InlineData(false, false, false, false, false, false, false, false, false, false, true, false, false, false, true)] // gitlab + [InlineData(false, false, false, false, false, false, false, false, false, false, false, true, false, false, true)] // az pipelines + [InlineData(false, false, false, false, false, false, false, false, false, false, false, false, true, false, true)] // gh actions + [InlineData(false, false, false, false, false, false, false, false, false, false, false, false, false, true, true)] // woodpecker + public void Should_Return_True_If_Running_On_Supported_Provider(bool appVeyor, bool teamCity, bool myGet, bool bamboo, bool continuaCI, bool jenkins, bool bitrise, bool travisCI, bool bitbucketPipelines, bool goCD, bool gitLabCI, bool azurePipelines, bool gitHubActions, bool woodpeckerCI, bool isPullRequest) { // Given var appVeyorProvider = Substitute.For(); @@ -961,9 +1057,13 @@ public void Should_Return_True_If_Running_On_Supported_Provider(bool appVeyor, b gitHubActionsProvider.Environment.Returns(gitHubActionsEnvironment); azurePipelinesProvider.IsRunningOnAzurePipelines.Returns(azurePipelines); azurePipelinesProvider.Environment.Returns(azurePipelinesEnvironment); + var woodpeckerCIProvider = Substitute.For(); + var woodpeckerCIEnvironment = new WoodpeckerCIInfoFixture().CreateEnvironmentInfo(); + woodpeckerCIProvider.IsRunningOnWoodpeckerCI.Returns(woodpeckerCI); + woodpeckerCIProvider.Environment.Returns(woodpeckerCIEnvironment); // When - var buildSystem = new BuildSystem(appVeyorProvider, teamCityProvider, myGetProvider, bambooProvider, continuaCIProvider, jenkinsProvider, bitriseProvider, travisCIProvider, bitbucketPipelinesProvider, goCDProvider, gitLabCIProvider, gitHubActionsProvider, azurePipelinesProvider); + var buildSystem = new BuildSystem(appVeyorProvider, teamCityProvider, myGetProvider, bambooProvider, continuaCIProvider, jenkinsProvider, bitriseProvider, travisCIProvider, bitbucketPipelinesProvider, goCDProvider, gitLabCIProvider, gitHubActionsProvider, azurePipelinesProvider, woodpeckerCIProvider); // Then Assert.Equal(isPullRequest, buildSystem.IsPullRequest); diff --git a/src/Cake.Common.Tests/Unit/Build/WoodpeckerCI/Commands/WoodpeckerCICommandsTests.cs b/src/Cake.Common.Tests/Unit/Build/WoodpeckerCI/Commands/WoodpeckerCICommandsTests.cs new file mode 100644 index 0000000000..1ce5658c34 --- /dev/null +++ b/src/Cake.Common.Tests/Unit/Build/WoodpeckerCI/Commands/WoodpeckerCICommandsTests.cs @@ -0,0 +1,161 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Cake.Common.Tests.Fixtures.Build; +using Cake.Testing; +using Xunit; + +namespace Cake.Common.Tests.Unit.Build.WoodpeckerCI.Commands +{ + public sealed class WoodpeckerCICommandsTests + { + public sealed class TheSetEnvironmentVariableMethod + { + [Fact] + public void Should_Throw_If_Name_Is_Null() + { + // Given + var commands = new WoodpeckerCICommandsFixture().CreateWoodpeckerCICommands(); + + // When + var result = Record.Exception(() => commands.SetEnvironmentVariable(null, "value")); + + // Then + AssertEx.IsArgumentException(result, "name", "Environment variable name cannot be null or empty."); + } + + [Fact] + public void Should_Throw_If_Name_Is_Empty() + { + // Given + var commands = new WoodpeckerCICommandsFixture().CreateWoodpeckerCICommands(); + + // When + var result = Record.Exception(() => commands.SetEnvironmentVariable(string.Empty, "value")); + + // Then + AssertEx.IsArgumentException(result, "name", "Environment variable name cannot be null or empty."); + } + + [Fact] + public void Should_Throw_If_Name_Is_WhiteSpace() + { + // Given + var commands = new WoodpeckerCICommandsFixture().CreateWoodpeckerCICommands(); + + // When + var result = Record.Exception(() => commands.SetEnvironmentVariable(" ", "value")); + + // Then + AssertEx.IsArgumentException(result, "name", "Environment variable name cannot be null or empty."); + } + + [Fact] + public void Should_SetEnvironmentVariable() + { + // Given + var fixture = new WoodpeckerCICommandsFixture(); + var commands = fixture.CreateWoodpeckerCICommands(); + var name = "MY_VAR"; + var value = "my_value"; + + // When + commands.SetEnvironmentVariable(name, value); + + // Then + Assert.Equal( + "MY_VAR=my_value\n", + ((FakeFile)fixture.FileSystem.GetFile("/woodpecker/src/git.example.com/john-doe/my-repo/.woodpecker/env")).GetTextContent()); + } + + [Fact] + public void Should_Append_To_Existing_Environment_File() + { + // Given + var fixture = new WoodpeckerCICommandsFixture(); + var commands = fixture.CreateWoodpeckerCICommands(); + var envFile = (FakeFile)fixture.FileSystem.GetFile("/woodpecker/src/git.example.com/john-doe/my-repo/.woodpecker/env"); + envFile.SetContent("EXISTING_VAR=existing_value\n"); + + // When + commands.SetEnvironmentVariable("NEW_VAR", "new_value"); + + // Then + Assert.Equal( + "EXISTING_VAR=existing_value\nNEW_VAR=new_value\n", + envFile.GetTextContent()); + } + } + + public sealed class TheGetEnvironmentVariableMethod + { + [Fact] + public void Should_Throw_If_Name_Is_Null() + { + // Given + var commands = new WoodpeckerCICommandsFixture().CreateWoodpeckerCICommands(); + + // When + var result = Record.Exception(() => commands.GetEnvironmentVariable(null)); + + // Then + AssertEx.IsArgumentException(result, "name", "Environment variable name cannot be null or empty."); + } + + [Fact] + public void Should_Throw_If_Name_Is_Empty() + { + // Given + var commands = new WoodpeckerCICommandsFixture().CreateWoodpeckerCICommands(); + + // When + var result = Record.Exception(() => commands.GetEnvironmentVariable(string.Empty)); + + // Then + AssertEx.IsArgumentException(result, "name", "Environment variable name cannot be null or empty."); + } + + [Fact] + public void Should_Throw_If_Name_Is_WhiteSpace() + { + // Given + var commands = new WoodpeckerCICommandsFixture().CreateWoodpeckerCICommands(); + + // When + var result = Record.Exception(() => commands.GetEnvironmentVariable(" ")); + + // Then + AssertEx.IsArgumentException(result, "name", "Environment variable name cannot be null or empty."); + } + + [Fact] + public void Should_Return_Environment_Variable_Value() + { + // Given + var fixture = new WoodpeckerCICommandsFixture(); + ((FakeEnvironment)fixture.Environment).SetEnvironmentVariable("TEST_VAR", "test_value"); + var commands = fixture.CreateWoodpeckerCICommands(); + + // When + var result = commands.GetEnvironmentVariable("TEST_VAR"); + + // Then + Assert.Equal("test_value", result); + } + + [Fact] + public void Should_Return_Null_If_Environment_Variable_Not_Found() + { + // Given + var commands = new WoodpeckerCICommandsFixture().CreateWoodpeckerCICommands(); + + // When + var result = commands.GetEnvironmentVariable("NONEXISTENT_VAR"); + + // Then + Assert.Null(result); + } + } + } +} diff --git a/src/Cake.Common.Tests/Unit/Build/WoodpeckerCI/Data/WoodpeckerCIEnvironmentInfoTests.cs b/src/Cake.Common.Tests/Unit/Build/WoodpeckerCI/Data/WoodpeckerCIEnvironmentInfoTests.cs new file mode 100644 index 0000000000..d8334ba5b0 --- /dev/null +++ b/src/Cake.Common.Tests/Unit/Build/WoodpeckerCI/Data/WoodpeckerCIEnvironmentInfoTests.cs @@ -0,0 +1,196 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Cake.Common.Build.WoodpeckerCI.Data; +using Cake.Common.Tests.Fixtures.Build; +using Cake.Core.IO; +using Xunit; + +namespace Cake.Common.Tests.Unit.Build.WoodpeckerCI.Data +{ + public sealed class WoodpeckerCIEnvironmentInfoTests + { + public sealed class TheCIProperty + { + [Fact] + public void Should_Return_Correct_Value() + { + // Given + var info = new WoodpeckerCIInfoFixture().CreateEnvironmentInfo(); + + // When + var result = info.CI; + + // Then + Assert.Equal("woodpecker", result); + } + } + + public sealed class TheWorkspaceProperty + { + [Fact] + public void Should_Return_Correct_DirectoryPath_For_Valid_Path() + { + // Given + var info = new WoodpeckerCIInfoFixture().CreateEnvironmentInfo(); + + // When + var result = info.Workspace; + + // Then + Assert.NotNull(result); + Assert.Equal("/woodpecker/src/git.example.com/john-doe/my-repo", result.FullPath); + } + + [Fact] + public void Should_Return_Null_For_Empty_Path() + { + // Given + var fixture = new WoodpeckerCIInfoFixture(); + fixture.SetEnvironmentVariable("CI_WORKSPACE", ""); + var info = fixture.CreateEnvironmentInfo(); + + // When + var result = info.Workspace; + + // Then + Assert.Null(result); + } + + [Fact] + public void Should_Return_Null_For_Missing_Path() + { + // Given + var fixture = new WoodpeckerCIInfoFixture(); + fixture.SetEnvironmentVariable("CI_WORKSPACE", null); + var info = fixture.CreateEnvironmentInfo(); + + // When + var result = info.Workspace; + + // Then + Assert.Null(result); + } + } + + public sealed class TheRepositoryProperty + { + [Fact] + public void Should_Return_Repository_Info() + { + // Given + var info = new WoodpeckerCIInfoFixture().CreateEnvironmentInfo(); + + // When + var result = info.Repository; + + // Then + Assert.NotNull(result); + Assert.Equal("john-doe/my-repo", result.Repo); + } + } + + public sealed class TheCommitProperty + { + [Fact] + public void Should_Return_Commit_Info() + { + // Given + var info = new WoodpeckerCIInfoFixture().CreateEnvironmentInfo(); + + // When + var result = info.Commit; + + // Then + Assert.NotNull(result); + Assert.Equal("eba09b46064473a1d345da7abf28b477468e8dbd", result.Sha); + } + } + + public sealed class ThePipelineProperty + { + [Fact] + public void Should_Return_Pipeline_Info() + { + // Given + var info = new WoodpeckerCIInfoFixture().CreateEnvironmentInfo(); + + // When + var result = info.Pipeline; + + // Then + Assert.NotNull(result); + Assert.Equal(8, result.Number); + } + } + + public sealed class TheWorkflowProperty + { + [Fact] + public void Should_Return_Workflow_Info() + { + // Given + var info = new WoodpeckerCIInfoFixture().CreateEnvironmentInfo(); + + // When + var result = info.Workflow; + + // Then + Assert.NotNull(result); + Assert.Equal("release", result.Name); + } + } + + public sealed class TheStepProperty + { + [Fact] + public void Should_Return_Step_Info() + { + // Given + var info = new WoodpeckerCIInfoFixture().CreateEnvironmentInfo(); + + // When + var result = info.Step; + + // Then + Assert.NotNull(result); + Assert.Equal("build package", result.Name); + } + } + + public sealed class TheSystemProperty + { + [Fact] + public void Should_Return_System_Info() + { + // Given + var info = new WoodpeckerCIInfoFixture().CreateEnvironmentInfo(); + + // When + var result = info.System; + + // Then + Assert.NotNull(result); + Assert.Equal("woodpecker", result.Name); + } + } + + public sealed class TheForgeProperty + { + [Fact] + public void Should_Return_Forge_Info() + { + // Given + var info = new WoodpeckerCIInfoFixture().CreateEnvironmentInfo(); + + // When + var result = info.Forge; + + // Then + Assert.NotNull(result); + Assert.Equal(WoodpeckerCIForgeType.GitHub, result.Type); + } + } + } +} diff --git a/src/Cake.Common.Tests/Unit/Build/WoodpeckerCI/Data/WoodpeckerCIForgeInfoTests.cs b/src/Cake.Common.Tests/Unit/Build/WoodpeckerCI/Data/WoodpeckerCIForgeInfoTests.cs new file mode 100644 index 0000000000..0e2d04074f --- /dev/null +++ b/src/Cake.Common.Tests/Unit/Build/WoodpeckerCI/Data/WoodpeckerCIForgeInfoTests.cs @@ -0,0 +1,146 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Cake.Common.Build.WoodpeckerCI.Data; +using Cake.Common.Tests.Fixtures.Build; +using Xunit; + +namespace Cake.Common.Tests.Unit.Build.WoodpeckerCI.Data +{ + public sealed class WoodpeckerCIForgeInfoTests + { + public sealed class TheTypeProperty + { + [Fact] + public void Should_Return_Correct_Forge_Type() + { + // Given + var fixture = new WoodpeckerCIInfoFixture(); + fixture.SetEnvironmentVariable("CI_FORGE_TYPE", "github"); + var forgeInfo = fixture.CreateForgeInfo(); + + // When + var result = forgeInfo.Type; + + // Then + Assert.Equal(WoodpeckerCIForgeType.GitHub, result); + } + + [Fact] + public void Should_Return_Unknown_For_Invalid_Forge_Type() + { + // Given + var fixture = new WoodpeckerCIInfoFixture(); + fixture.SetEnvironmentVariable("CI_FORGE_TYPE", "invalid"); + var forgeInfo = fixture.CreateForgeInfo(); + + // When + var result = forgeInfo.Type; + + // Then + Assert.Equal(WoodpeckerCIForgeType.Unknown, result); + } + + [Fact] + public void Should_Return_Unknown_For_Empty_Forge_Type() + { + // Given + var fixture = new WoodpeckerCIInfoFixture(); + fixture.SetEnvironmentVariable("CI_FORGE_TYPE", ""); + var forgeInfo = fixture.CreateForgeInfo(); + + // When + var result = forgeInfo.Type; + + // Then + Assert.Equal(WoodpeckerCIForgeType.Unknown, result); + } + + [Theory] + [InlineData("bitbucket", WoodpeckerCIForgeType.Bitbucket)] + [InlineData("bitbucket_dc", WoodpeckerCIForgeType.BitbucketDC)] + [InlineData("forgejo", WoodpeckerCIForgeType.Forgejo)] + [InlineData("gitea", WoodpeckerCIForgeType.Gitea)] + [InlineData("github", WoodpeckerCIForgeType.GitHub)] + [InlineData("gitlab", WoodpeckerCIForgeType.GitLab)] + public void Should_Parse_All_Valid_Forge_Types(string forgeType, WoodpeckerCIForgeType expected) + { + // Given + var fixture = new WoodpeckerCIInfoFixture(); + fixture.SetEnvironmentVariable("CI_FORGE_TYPE", forgeType); + var forgeInfo = fixture.CreateForgeInfo(); + + // When + var result = forgeInfo.Type; + + // Then + Assert.Equal(expected, result); + } + } + + public sealed class TheUrlProperty + { + [Fact] + public void Should_Return_Correct_Uri_For_Valid_Url() + { + // Given + var fixture = new WoodpeckerCIInfoFixture(); + fixture.SetEnvironmentVariable("CI_FORGE_URL", "https://github.com"); + var forgeInfo = fixture.CreateForgeInfo(); + + // When + var result = forgeInfo.Url; + + // Then + Assert.NotNull(result); + Assert.Equal("https://github.com/", result.ToString()); + } + + [Fact] + public void Should_Return_Null_For_Invalid_Url() + { + // Given + var fixture = new WoodpeckerCIInfoFixture(); + fixture.SetEnvironmentVariable("CI_FORGE_URL", "not-a-valid-url"); + var forgeInfo = fixture.CreateForgeInfo(); + + // When + var result = forgeInfo.Url; + + // Then + Assert.Null(result); + } + + [Fact] + public void Should_Return_Null_For_Empty_Url() + { + // Given + var fixture = new WoodpeckerCIInfoFixture(); + fixture.SetEnvironmentVariable("CI_FORGE_URL", ""); + var forgeInfo = fixture.CreateForgeInfo(); + + // When + var result = forgeInfo.Url; + + // Then + Assert.Null(result); + } + + [Fact] + public void Should_Return_Null_For_Missing_Url() + { + // Given + var fixture = new WoodpeckerCIInfoFixture(); + fixture.SetEnvironmentVariable("CI_FORGE_URL", null); + var forgeInfo = fixture.CreateForgeInfo(); + + // When + var result = forgeInfo.Url; + + // Then + Assert.Null(result); + } + } + } +} diff --git a/src/Cake.Common.Tests/Unit/Build/WoodpeckerCI/Data/WoodpeckerCIForgeTypeTests.cs b/src/Cake.Common.Tests/Unit/Build/WoodpeckerCI/Data/WoodpeckerCIForgeTypeTests.cs new file mode 100644 index 0000000000..378392949b --- /dev/null +++ b/src/Cake.Common.Tests/Unit/Build/WoodpeckerCI/Data/WoodpeckerCIForgeTypeTests.cs @@ -0,0 +1,57 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Cake.Common.Build.WoodpeckerCI.Data; +using Xunit; + +namespace Cake.Common.Tests.Unit.Build.WoodpeckerCI.Data +{ + public sealed class WoodpeckerCIForgeTypeTests + { + public sealed class TheParseForgeTypeMethod + { + [Theory] + [InlineData(null, WoodpeckerCIForgeType.Unknown)] + [InlineData("", WoodpeckerCIForgeType.Unknown)] + [InlineData(" ", WoodpeckerCIForgeType.Unknown)] + [InlineData("unknown", WoodpeckerCIForgeType.Unknown)] + public void Should_Return_Unknown_For_Invalid_Values(string value, WoodpeckerCIForgeType expected) + { + // When + var result = WoodpeckerCIForgeTypeExtensions.ParseForgeType(value); + + // Then + Assert.Equal(expected, result); + } + + [Theory] + [InlineData("bitbucket", WoodpeckerCIForgeType.Bitbucket)] + [InlineData("BITBUCKET", WoodpeckerCIForgeType.Bitbucket)] + [InlineData("Bitbucket", WoodpeckerCIForgeType.Bitbucket)] + [InlineData("bitbucket_dc", WoodpeckerCIForgeType.BitbucketDC)] + [InlineData("BITBUCKET_DC", WoodpeckerCIForgeType.BitbucketDC)] + [InlineData("Bitbucket_DC", WoodpeckerCIForgeType.BitbucketDC)] + [InlineData("forgejo", WoodpeckerCIForgeType.Forgejo)] + [InlineData("FORGEJO", WoodpeckerCIForgeType.Forgejo)] + [InlineData("Forgejo", WoodpeckerCIForgeType.Forgejo)] + [InlineData("gitea", WoodpeckerCIForgeType.Gitea)] + [InlineData("GITEA", WoodpeckerCIForgeType.Gitea)] + [InlineData("Gitea", WoodpeckerCIForgeType.Gitea)] + [InlineData("github", WoodpeckerCIForgeType.GitHub)] + [InlineData("GITHUB", WoodpeckerCIForgeType.GitHub)] + [InlineData("GitHub", WoodpeckerCIForgeType.GitHub)] + [InlineData("gitlab", WoodpeckerCIForgeType.GitLab)] + [InlineData("GITLAB", WoodpeckerCIForgeType.GitLab)] + [InlineData("GitLab", WoodpeckerCIForgeType.GitLab)] + public void Should_Parse_Valid_Forge_Types(string value, WoodpeckerCIForgeType expected) + { + // When + var result = WoodpeckerCIForgeTypeExtensions.ParseForgeType(value); + + // Then + Assert.Equal(expected, result); + } + } + } +} diff --git a/src/Cake.Common.Tests/Unit/Build/WoodpeckerCI/Data/WoodpeckerCIPipelineInfoTests.cs b/src/Cake.Common.Tests/Unit/Build/WoodpeckerCI/Data/WoodpeckerCIPipelineInfoTests.cs new file mode 100644 index 0000000000..972422adf5 --- /dev/null +++ b/src/Cake.Common.Tests/Unit/Build/WoodpeckerCI/Data/WoodpeckerCIPipelineInfoTests.cs @@ -0,0 +1,205 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using Cake.Common.Tests.Fixtures.Build; +using Xunit; + +namespace Cake.Common.Tests.Unit.Build.WoodpeckerCI.Data +{ + public sealed class WoodpeckerCIPipelineInfoTests + { + public sealed class TheNumberProperty + { + [Fact] + public void Should_Return_Correct_Value() + { + // Given + var info = new WoodpeckerCIInfoFixture().CreatePipelineInfo(); + + // When + var result = info.Number; + + // Then + Assert.Equal(8, result); + } + } + + public sealed class TheCreatedProperty + { + [Fact] + public void Should_Return_Correct_DateTimeOffset_For_Valid_Timestamp() + { + // Given + var info = new WoodpeckerCIInfoFixture().CreatePipelineInfo(); + + // When + var result = info.Created; + + // Then + Assert.NotEqual(DateTimeOffset.MinValue, result); + Assert.Equal(DateTimeOffset.FromUnixTimeSeconds(1722617519), result); + } + + [Fact] + public void Should_Return_MinValue_For_Invalid_Timestamp() + { + // Given + var fixture = new WoodpeckerCIInfoFixture(); + fixture.SetEnvironmentVariable("CI_PIPELINE_CREATED", "0"); + var info = fixture.CreatePipelineInfo(); + + // When + var result = info.Created; + + // Then + Assert.Equal(DateTimeOffset.MinValue, result); + } + } + + public sealed class TheStartedProperty + { + [Fact] + public void Should_Return_Correct_DateTimeOffset_For_Valid_Timestamp() + { + // Given + var info = new WoodpeckerCIInfoFixture().CreatePipelineInfo(); + + // When + var result = info.Started; + + // Then + Assert.NotEqual(DateTimeOffset.MinValue, result); + Assert.Equal(DateTimeOffset.FromUnixTimeSeconds(1722617519), result); + } + + [Fact] + public void Should_Return_MinValue_For_Invalid_Timestamp() + { + // Given + var fixture = new WoodpeckerCIInfoFixture(); + fixture.SetEnvironmentVariable("CI_PIPELINE_STARTED", "0"); + var info = fixture.CreatePipelineInfo(); + + // When + var result = info.Started; + + // Then + Assert.Equal(DateTimeOffset.MinValue, result); + } + } + + public sealed class TheEventProperty + { + [Fact] + public void Should_Return_Correct_Value() + { + // Given + var info = new WoodpeckerCIInfoFixture().CreatePipelineInfo(); + + // When + var result = info.Event; + + // Then + Assert.Equal("push", result); + } + } + + public sealed class TheUrlProperty + { + [Fact] + public void Should_Return_Correct_Uri_For_Valid_Url() + { + // Given + var info = new WoodpeckerCIInfoFixture().CreatePipelineInfo(); + + // When + var result = info.Url; + + // Then + Assert.NotNull(result); + Assert.Equal("https://ci.example.com/repos/john-doe/my-repo/pipeline/123", result.ToString()); + } + + [Fact] + public void Should_Return_Null_For_Invalid_Url() + { + // Given + var fixture = new WoodpeckerCIInfoFixture(); + fixture.SetEnvironmentVariable("CI_PIPELINE_URL", "not-a-valid-url"); + var info = fixture.CreatePipelineInfo(); + + // When + var result = info.Url; + + // Then + Assert.Null(result); + } + } + + public sealed class TheForgeUrlProperty + { + [Fact] + public void Should_Return_Correct_Uri_For_Valid_Url() + { + // Given + var info = new WoodpeckerCIInfoFixture().CreatePipelineInfo(); + + // When + var result = info.ForgeUrl; + + // Then + Assert.NotNull(result); + Assert.Equal("https://git.example.com/john-doe/my-repo/commit/abc123", result.ToString()); + } + + [Fact] + public void Should_Return_Null_For_Invalid_Url() + { + // Given + var fixture = new WoodpeckerCIInfoFixture(); + fixture.SetEnvironmentVariable("CI_PIPELINE_FORGE_URL", "not-a-valid-url"); + var info = fixture.CreatePipelineInfo(); + + // When + var result = info.ForgeUrl; + + // Then + Assert.Null(result); + } + } + + public sealed class TheAvatarProperty + { + [Fact] + public void Should_Return_Correct_Uri_For_Valid_Url() + { + // Given + var info = new WoodpeckerCIInfoFixture().CreatePipelineInfo(); + + // When + var result = info.Avatar; + + // Then + Assert.NotNull(result); + Assert.Equal("https://git.example.com/avatars/john-doe", result.ToString()); + } + + [Fact] + public void Should_Return_Null_For_Invalid_Url() + { + // Given + var fixture = new WoodpeckerCIInfoFixture(); + fixture.SetEnvironmentVariable("CI_PIPELINE_AVATAR", "not-a-valid-url"); + var info = fixture.CreatePipelineInfo(); + + // When + var result = info.Avatar; + + // Then + Assert.Null(result); + } + } + } +} diff --git a/src/Cake.Common.Tests/Unit/Build/WoodpeckerCI/Data/WoodpeckerCIRepositoryInfoTests.cs b/src/Cake.Common.Tests/Unit/Build/WoodpeckerCI/Data/WoodpeckerCIRepositoryInfoTests.cs new file mode 100644 index 0000000000..edf8bd15cb --- /dev/null +++ b/src/Cake.Common.Tests/Unit/Build/WoodpeckerCI/Data/WoodpeckerCIRepositoryInfoTests.cs @@ -0,0 +1,157 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Cake.Common.Tests.Fixtures.Build; +using Xunit; + +namespace Cake.Common.Tests.Unit.Build.WoodpeckerCI.Data +{ + public sealed class WoodpeckerCIRepositoryInfoTests + { + public sealed class TheRepoProperty + { + [Fact] + public void Should_Return_Correct_Value() + { + // Given + var info = new WoodpeckerCIInfoFixture().CreateRepositoryInfo(); + + // When + var result = info.Repo; + + // Then + Assert.Equal("john-doe/my-repo", result); + } + } + + public sealed class TheRepoOwnerProperty + { + [Fact] + public void Should_Return_Correct_Value() + { + // Given + var info = new WoodpeckerCIInfoFixture().CreateRepositoryInfo(); + + // When + var result = info.RepoOwner; + + // Then + Assert.Equal("john-doe", result); + } + } + + public sealed class TheRepoNameProperty + { + [Fact] + public void Should_Return_Correct_Value() + { + // Given + var info = new WoodpeckerCIInfoFixture().CreateRepositoryInfo(); + + // When + var result = info.RepoName; + + // Then + Assert.Equal("my-repo", result); + } + } + + public sealed class TheRepoUrlProperty + { + [Fact] + public void Should_Return_Correct_Uri_For_Valid_Url() + { + // Given + var info = new WoodpeckerCIInfoFixture().CreateRepositoryInfo(); + + // When + var result = info.RepoUrl; + + // Then + Assert.NotNull(result); + Assert.Equal("https://git.example.com/john-doe/my-repo", result.ToString()); + } + + [Fact] + public void Should_Return_Null_For_Invalid_Url() + { + // Given + var fixture = new WoodpeckerCIInfoFixture(); + fixture.SetEnvironmentVariable("CI_REPO_URL", "not-a-valid-url"); + var info = fixture.CreateRepositoryInfo(); + + // When + var result = info.RepoUrl; + + // Then + Assert.Null(result); + } + } + + public sealed class TheRepoCloneUrlProperty + { + [Fact] + public void Should_Return_Correct_Uri_For_Valid_Url() + { + // Given + var info = new WoodpeckerCIInfoFixture().CreateRepositoryInfo(); + + // When + var result = info.RepoCloneUrl; + + // Then + Assert.NotNull(result); + Assert.Equal("https://git.example.com/john-doe/my-repo.git", result.ToString()); + } + + [Fact] + public void Should_Return_Null_For_Invalid_Url() + { + // Given + var fixture = new WoodpeckerCIInfoFixture(); + fixture.SetEnvironmentVariable("CI_REPO_CLONE_URL", "not-a-valid-url"); + var info = fixture.CreateRepositoryInfo(); + + // When + var result = info.RepoCloneUrl; + + // Then + Assert.Null(result); + } + } + + public sealed class TheRepoCloneSshUrlProperty + { + [Fact] + public void Should_Return_Correct_Uri_For_Valid_Url() + { + // Given + var info = new WoodpeckerCIInfoFixture().CreateRepositoryInfo(); + + // When + var result = info.RepoCloneSshUrl; + + // Then + Assert.NotNull(result); + Assert.Equal("git@git.example.com:john-doe/my-repo.git", result.ToString()); + } + } + + public sealed class TheRepoPrivateProperty + { + [Fact] + public void Should_Return_Correct_Value() + { + // Given + var info = new WoodpeckerCIInfoFixture().CreateRepositoryInfo(); + + // When + var result = info.RepoPrivate; + + // Then + Assert.True(result); + } + } + } +} diff --git a/src/Cake.Common.Tests/Unit/Build/WoodpeckerCI/Data/WoodpeckerCIStepInfoTests.cs b/src/Cake.Common.Tests/Unit/Build/WoodpeckerCI/Data/WoodpeckerCIStepInfoTests.cs new file mode 100644 index 0000000000..ceef52b69d --- /dev/null +++ b/src/Cake.Common.Tests/Unit/Build/WoodpeckerCI/Data/WoodpeckerCIStepInfoTests.cs @@ -0,0 +1,109 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using Cake.Common.Tests.Fixtures.Build; +using Xunit; + +namespace Cake.Common.Tests.Unit.Build.WoodpeckerCI.Data +{ + public sealed class WoodpeckerCIStepInfoTests + { + public sealed class TheNameProperty + { + [Fact] + public void Should_Return_Correct_Value() + { + // Given + var info = new WoodpeckerCIInfoFixture().CreateStepInfo(); + + // When + var result = info.Name; + + // Then + Assert.Equal("build package", result); + } + } + + public sealed class TheNumberProperty + { + [Fact] + public void Should_Return_Correct_Value() + { + // Given + var info = new WoodpeckerCIInfoFixture().CreateStepInfo(); + + // When + var result = info.Number; + + // Then + Assert.Equal(0, result); + } + } + + public sealed class TheStartedProperty + { + [Fact] + public void Should_Return_Correct_DateTimeOffset_For_Valid_Timestamp() + { + // Given + var info = new WoodpeckerCIInfoFixture().CreateStepInfo(); + + // When + var result = info.Started; + + // Then + Assert.NotEqual(DateTimeOffset.MinValue, result); + Assert.Equal(DateTimeOffset.FromUnixTimeSeconds(1722617519), result); + } + + [Fact] + public void Should_Return_MinValue_For_Invalid_Timestamp() + { + // Given + var fixture = new WoodpeckerCIInfoFixture(); + fixture.SetEnvironmentVariable("CI_STEP_STARTED", "0"); + var info = fixture.CreateStepInfo(); + + // When + var result = info.Started; + + // Then + Assert.Equal(DateTimeOffset.MinValue, result); + } + } + + public sealed class TheUrlProperty + { + [Fact] + public void Should_Return_Correct_Uri_For_Valid_Url() + { + // Given + var info = new WoodpeckerCIInfoFixture().CreateStepInfo(); + + // When + var result = info.Url; + + // Then + Assert.NotNull(result); + Assert.Equal("https://ci.example.com/repos/7/pipeline/8", result.ToString()); + } + + [Fact] + public void Should_Return_Null_For_Invalid_Url() + { + // Given + var fixture = new WoodpeckerCIInfoFixture(); + fixture.SetEnvironmentVariable("CI_STEP_URL", "not-a-valid-url"); + var info = fixture.CreateStepInfo(); + + // When + var result = info.Url; + + // Then + Assert.Null(result); + } + } + } +} diff --git a/src/Cake.Common.Tests/Unit/Build/WoodpeckerCI/WoodpeckerCIProviderTests.cs b/src/Cake.Common.Tests/Unit/Build/WoodpeckerCI/WoodpeckerCIProviderTests.cs new file mode 100644 index 0000000000..490aedee05 --- /dev/null +++ b/src/Cake.Common.Tests/Unit/Build/WoodpeckerCI/WoodpeckerCIProviderTests.cs @@ -0,0 +1,97 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Cake.Common.Build.WoodpeckerCI; +using Cake.Common.Tests.Fixtures.Build; +using Cake.Core; +using Cake.Core.IO; +using NSubstitute; +using Xunit; + +namespace Cake.Common.Tests.Unit.Build.WoodpeckerCI +{ + public sealed class WoodpeckerCIProviderTests + { + public sealed class TheIsRunningOnWoodpeckerCIProperty + { + [Fact] + public void Should_Return_True_When_CI_Environment_Variable_Is_Set_To_Woodpecker() + { + // Given + var fixture = new WoodpeckerCIInfoFixture(); + var provider = new WoodpeckerCIProvider(fixture.Environment, Substitute.For()); + + // When + var result = provider.IsRunningOnWoodpeckerCI; + + // Then + Assert.True(result); + } + + [Fact] + public void Should_Return_False_When_CI_Environment_Variable_Is_Not_Set() + { + // Given + var environment = Substitute.For(); + environment.GetEnvironmentVariable("CI").Returns((string)null); + var provider = new WoodpeckerCIProvider(environment, Substitute.For()); + + // When + var result = provider.IsRunningOnWoodpeckerCI; + + // Then + Assert.False(result); + } + + [Fact] + public void Should_Return_False_When_CI_Environment_Variable_Is_Set_To_Something_Else() + { + // Given + var environment = Substitute.For(); + environment.GetEnvironmentVariable("CI").Returns("github"); + var provider = new WoodpeckerCIProvider(environment, Substitute.For()); + + // When + var result = provider.IsRunningOnWoodpeckerCI; + + // Then + Assert.False(result); + } + } + + public sealed class TheEnvironmentProperty + { + [Fact] + public void Should_Return_Non_Null_Environment() + { + // Given + var fixture = new WoodpeckerCIInfoFixture(); + var provider = new WoodpeckerCIProvider(fixture.Environment, Substitute.For()); + + // When + var result = provider.Environment; + + // Then + Assert.NotNull(result); + } + } + + public sealed class TheCommandsProperty + { + [Fact] + public void Should_Return_Non_Null_Commands() + { + // Given + var fixture = new WoodpeckerCIInfoFixture(); + var provider = new WoodpeckerCIProvider(fixture.Environment, Substitute.For()); + + // When + var result = provider.Commands; + + // Then + Assert.NotNull(result); + } + } + } +} diff --git a/src/Cake.Common/Build/BuildProvider.cs b/src/Cake.Common/Build/BuildProvider.cs index 5515b17f84..6db517b7c0 100644 --- a/src/Cake.Common/Build/BuildProvider.cs +++ b/src/Cake.Common/Build/BuildProvider.cs @@ -80,6 +80,11 @@ public enum BuildProvider /// /// GitHubActions build provider. /// - GitHubActions = 8192 + GitHubActions = 8192, + + /// + /// WoodpeckerCI build provider. + /// + WoodpeckerCI = 16384 } } \ No newline at end of file diff --git a/src/Cake.Common/Build/BuildSystem.cs b/src/Cake.Common/Build/BuildSystem.cs index 2410db5f6a..7d7c19848d 100644 --- a/src/Cake.Common/Build/BuildSystem.cs +++ b/src/Cake.Common/Build/BuildSystem.cs @@ -16,6 +16,7 @@ using Cake.Common.Build.MyGet; using Cake.Common.Build.TeamCity; using Cake.Common.Build.TravisCI; +using Cake.Common.Build.WoodpeckerCI; namespace Cake.Common.Build { @@ -41,6 +42,7 @@ public sealed class BuildSystem /// The GitLab CI provider. /// The GitHub Actions provider. /// The Azure Pipelines provider. + /// The WoodpeckerCI provider. public BuildSystem( IAppVeyorProvider appVeyorProvider, ITeamCityProvider teamCityProvider, @@ -54,7 +56,8 @@ public BuildSystem( IGoCDProvider goCDProvider, IGitLabCIProvider gitLabCIProvider, IGitHubActionsProvider gitHubActionsProvider, - IAzurePipelinesProvider azurePipelinesProvider) + IAzurePipelinesProvider azurePipelinesProvider, + IWoodpeckerCIProvider woodpeckerCIProvider) { if (appVeyorProvider == null) { @@ -108,6 +111,10 @@ public BuildSystem( { throw new ArgumentNullException(nameof(azurePipelinesProvider)); } + if (woodpeckerCIProvider == null) + { + throw new ArgumentNullException(nameof(woodpeckerCIProvider)); + } AppVeyor = appVeyorProvider; TeamCity = teamCityProvider; @@ -122,6 +129,7 @@ public BuildSystem( GitLabCI = gitLabCIProvider; GitHubActions = gitHubActionsProvider; AzurePipelines = azurePipelinesProvider; + WoodpeckerCI = woodpeckerCIProvider; Provider = (AppVeyor.IsRunningOnAppVeyor ? BuildProvider.AppVeyor : BuildProvider.Local) | (TeamCity.IsRunningOnTeamCity ? BuildProvider.TeamCity : BuildProvider.Local) @@ -135,7 +143,8 @@ public BuildSystem( | (GoCD.IsRunningOnGoCD ? BuildProvider.GoCD : BuildProvider.Local) | (GitLabCI.IsRunningOnGitLabCI ? BuildProvider.GitLabCI : BuildProvider.Local) | (GitHubActions.IsRunningOnGitHubActions ? BuildProvider.GitHubActions : BuildProvider.Local) - | (AzurePipelines.IsRunningOnAzurePipelines ? BuildProvider.AzurePipelines : BuildProvider.Local); + | (AzurePipelines.IsRunningOnAzurePipelines ? BuildProvider.AzurePipelines : BuildProvider.Local) + | (WoodpeckerCI.IsRunningOnWoodpeckerCI ? BuildProvider.WoodpeckerCI : BuildProvider.Local); IsLocalBuild = Provider == BuildProvider.Local; @@ -147,6 +156,7 @@ public BuildSystem( || ((Provider & BuildProvider.GitLabCI) != 0 && GitLabCI.Environment.PullRequest.IsPullRequest) || ((Provider & BuildProvider.AzurePipelines) != 0 && AzurePipelines.Environment.PullRequest.IsPullRequest) || ((Provider & BuildProvider.GitHubActions) != 0 && GitHubActions.Environment.PullRequest.IsPullRequest) + || ((Provider & BuildProvider.WoodpeckerCI) != 0 && !string.IsNullOrWhiteSpace(WoodpeckerCI.Environment.Commit.PullRequest)) || ((Provider & BuildProvider.Jenkins) != 0 && Jenkins.Environment.Change.IsPullRequest); } @@ -559,6 +569,37 @@ public BuildSystem( /// public IGitHubActionsProvider GitHubActions { get; } + /// + /// Gets a value indicating whether this instance is running on WoodpeckerCI. + /// + /// + /// + /// if (BuildSystem.IsRunningOnWoodpeckerCI) + /// { + /// // Get the commit SHA. + /// var commitSha = BuildSystem.WoodpeckerCI.Environment.Commit.Sha; + /// } + /// + /// + /// + /// true if this instance is running on WoodpeckerCI; otherwise, false. + /// + public bool IsRunningOnWoodpeckerCI => WoodpeckerCI.IsRunningOnWoodpeckerCI; + + /// + /// Gets the WoodpeckerCI Provider. + /// + /// + /// + /// if (BuildSystem.IsRunningOnWoodpeckerCI) + /// { + /// // Get the commit SHA. + /// var commitSha = BuildSystem.WoodpeckerCI.Environment.Commit.Sha; + /// } + /// + /// + public IWoodpeckerCIProvider WoodpeckerCI { get; } + /// /// Gets the current build provider. /// diff --git a/src/Cake.Common/Build/BuildSystemAliases.cs b/src/Cake.Common/Build/BuildSystemAliases.cs index 22bba8ae1e..b2b90782e4 100644 --- a/src/Cake.Common/Build/BuildSystemAliases.cs +++ b/src/Cake.Common/Build/BuildSystemAliases.cs @@ -16,6 +16,7 @@ using Cake.Common.Build.MyGet; using Cake.Common.Build.TeamCity; using Cake.Common.Build.TravisCI; +using Cake.Common.Build.WoodpeckerCI; using Cake.Core; using Cake.Core.Annotations; @@ -59,8 +60,9 @@ public static BuildSystem BuildSystem(this ICakeContext context) var gitLabCIProvider = new GitLabCIProvider(context.Environment, context.FileSystem); var gitHubActionsProvider = new GitHubActionsProvider(context.Environment, context.FileSystem, new BuildSystemServiceMessageWriter()); var azurePipelinesProvider = new AzurePipelinesProvider(context.Environment, new BuildSystemServiceMessageWriter()); + var woodpeckerCIProvider = new WoodpeckerCIProvider(context.Environment, context.FileSystem); - return new BuildSystem(appVeyorProvider, teamCityProvider, myGetProvider, bambooProvider, continuaCIProvider, jenkinsProvider, bitriseProvider, travisCIProvider, bitbucketPipelinesProvider, goCDProvider, gitLabCIProvider, gitHubActionsProvider, azurePipelinesProvider); + return new BuildSystem(appVeyorProvider, teamCityProvider, myGetProvider, bambooProvider, continuaCIProvider, jenkinsProvider, bitriseProvider, travisCIProvider, bitbucketPipelinesProvider, goCDProvider, gitLabCIProvider, gitHubActionsProvider, azurePipelinesProvider, woodpeckerCIProvider); } /// @@ -385,5 +387,30 @@ public static IAzurePipelinesProvider AzurePipelines(this ICakeContext context) var buildSystem = context.BuildSystem(); return buildSystem.AzurePipelines; } + + /// + /// Gets a instance that can be used to + /// obtain information from the WoodpeckerCI environment. + /// + /// + /// + /// var isWoodpeckerCIBuild = WoodpeckerCI.IsRunningOnWoodpeckerCI; + /// + /// + /// The context. + /// A instance. + [CakePropertyAlias(Cache = true)] + [CakeNamespaceImport("Cake.Common.Build.WoodpeckerCI")] + [CakeNamespaceImport("Cake.Common.Build.WoodpeckerCI.Data")] + public static IWoodpeckerCIProvider WoodpeckerCI(this ICakeContext context) + { + if (context == null) + { + throw new ArgumentNullException(nameof(context)); + } + + var buildSystem = context.BuildSystem(); + return buildSystem.WoodpeckerCI; + } } } \ No newline at end of file diff --git a/src/Cake.Common/Build/WoodpeckerCI/Commands/WoodpeckerCICommands.cs b/src/Cake.Common/Build/WoodpeckerCI/Commands/WoodpeckerCICommands.cs new file mode 100644 index 0000000000..d453f13ab9 --- /dev/null +++ b/src/Cake.Common/Build/WoodpeckerCI/Commands/WoodpeckerCICommands.cs @@ -0,0 +1,96 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.IO; +using Cake.Common.Build.WoodpeckerCI.Data; +using Cake.Core; +using Cake.Core.IO; + +namespace Cake.Common.Build.WoodpeckerCI.Commands +{ + /// + /// Provides WoodpeckerCI commands for a current build. + /// + public sealed class WoodpeckerCICommands + { + private readonly ICakeEnvironment _environment; + private readonly IFileSystem _fileSystem; + private readonly WoodpeckerCIEnvironmentInfo _woodpeckerEnvironment; + + /// + /// Initializes a new instance of the class. + /// + /// The environment. + /// The file system. + /// The WoodpeckerCI environment. + public WoodpeckerCICommands( + ICakeEnvironment environment, + IFileSystem fileSystem, + WoodpeckerCIEnvironmentInfo woodpeckerEnvironment) + { + _environment = environment ?? throw new ArgumentNullException(nameof(environment)); + _fileSystem = fileSystem ?? throw new ArgumentNullException(nameof(fileSystem)); + _woodpeckerEnvironment = woodpeckerEnvironment ?? throw new ArgumentNullException(nameof(woodpeckerEnvironment)); + } + + /// + /// Sets an environment variable that will be available to subsequent steps. + /// + /// The environment variable name. + /// The environment variable value. + /// + /// + /// if (BuildSystem.WoodpeckerCI.IsRunningOnWoodpeckerCI) + /// { + /// WoodpeckerCI.Commands.SetEnvironmentVariable("MY_VAR", "my_value"); + /// } + /// + /// + public void SetEnvironmentVariable(string name, string value) + { + if (string.IsNullOrWhiteSpace(name)) + { + throw new ArgumentException("Environment variable name cannot be null or empty.", nameof(name)); + } + + // Write to the WoodpeckerCI environment file for persistence between steps + var envFile = _woodpeckerEnvironment.Workspace?.CombineWithFilePath(".woodpecker/env"); + if (envFile != null) + { + var file = _fileSystem.GetFile(envFile); + using var stream = file.Open(FileMode.Append, FileAccess.Write, FileShare.None); + using var writer = new StreamWriter(stream); + writer.Write(name); + writer.Write("="); + writer.Write(value); + writer.Write("\n"); + } + } + + /// + /// Gets an environment variable that was set by a previous step. + /// + /// The environment variable name. + /// The environment variable value, or null if not found. + /// + /// + /// if (BuildSystem.WoodpeckerCI.IsRunningOnWoodpeckerCI) + /// { + /// var value = WoodpeckerCI.Commands.GetEnvironmentVariable("MY_VAR"); + /// Information("MY_VAR = {0}", value); + /// } + /// + /// + public string GetEnvironmentVariable(string name) + { + if (string.IsNullOrWhiteSpace(name)) + { + throw new ArgumentException("Environment variable name cannot be null or empty.", nameof(name)); + } + + return _environment.GetEnvironmentVariable(name); + } + } +} diff --git a/src/Cake.Common/Build/WoodpeckerCI/Data/WoodpeckerCICommitInfo.cs b/src/Cake.Common/Build/WoodpeckerCI/Data/WoodpeckerCICommitInfo.cs new file mode 100644 index 0000000000..00229e3997 --- /dev/null +++ b/src/Cake.Common/Build/WoodpeckerCI/Data/WoodpeckerCICommitInfo.cs @@ -0,0 +1,159 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Cake.Core; + +namespace Cake.Common.Build.WoodpeckerCI.Data +{ + /// + /// Provides WoodpeckerCI commit information for the current build. + /// + public class WoodpeckerCICommitInfo : WoodpeckerCIInfo + { + /// + /// Initializes a new instance of the class. + /// + /// The environment. + public WoodpeckerCICommitInfo(ICakeEnvironment environment) + : base(environment) + { + } + + /// + /// Gets the commit SHA. + /// + /// + /// The commit SHA. + /// + /// Via BuildSystem. + /// + /// + /// if (BuildSystem.WoodpeckerCI.IsRunningOnWoodpeckerCI) + /// { + /// Information( + /// @"Commit SHA: {0}", + /// BuildSystem.WoodpeckerCI.Environment.Commit.Sha + /// ); + /// } + /// else + /// { + /// Information("Not running on WoodpeckerCI"); + /// } + /// + /// + /// Via WoodpeckerCI. + /// + /// + /// if (WoodpeckerCI.IsRunningOnWoodpeckerCI) + /// { + /// Information( + /// @"Commit SHA: {0}", + /// WoodpeckerCI.Environment.Commit.Sha + /// ); + /// } + /// else + /// { + /// Information("Not running on WoodpeckerCI"); + /// } + /// + /// + public string Sha => GetEnvironmentString("CI_COMMIT_SHA"); + + /// + /// Gets the commit ref. + /// + /// + /// The commit ref. + /// + public string Ref => GetEnvironmentString("CI_COMMIT_REF"); + + /// + /// Gets the commit ref spec. + /// + /// + /// The commit ref spec. + /// + public string Refspec => GetEnvironmentString("CI_COMMIT_REFSPEC"); + + /// + /// Gets the commit branch. + /// + /// + /// The commit branch. + /// + public string Branch => GetEnvironmentString("CI_COMMIT_BRANCH"); + + /// + /// Gets the commit source branch. + /// + /// + /// The commit source branch. + /// + public string SourceBranch => GetEnvironmentString("CI_COMMIT_SOURCE_BRANCH"); + + /// + /// Gets the commit target branch. + /// + /// + /// The commit target branch. + /// + public string TargetBranch => GetEnvironmentString("CI_COMMIT_TARGET_BRANCH"); + + /// + /// Gets the commit tag name. + /// + /// + /// The commit tag name. + /// + public string Tag => GetEnvironmentString("CI_COMMIT_TAG"); + + /// + /// Gets the commit pull request number. + /// + /// + /// The commit pull request number. + /// + public string PullRequest => GetEnvironmentString("CI_COMMIT_PULL_REQUEST"); + + /// + /// Gets the commit pull request labels. + /// + /// + /// The commit pull request labels. + /// + public string PullRequestLabels => GetEnvironmentString("CI_COMMIT_PULL_REQUEST_LABELS"); + + /// + /// Gets the commit message. + /// + /// + /// The commit message. + /// + public string Message => GetEnvironmentString("CI_COMMIT_MESSAGE"); + + /// + /// Gets the commit author username. + /// + /// + /// The commit author username. + /// + public string Author => GetEnvironmentString("CI_COMMIT_AUTHOR"); + + /// + /// Gets the commit author email address. + /// + /// + /// The commit author email address. + /// + public string AuthorEmail => GetEnvironmentString("CI_COMMIT_AUTHOR_EMAIL"); + + /// + /// Gets a value indicating whether the release is a pre-release. + /// + /// + /// true if the release is a pre-release; otherwise, false. + /// + public bool PreRelease => GetEnvironmentBoolean("CI_COMMIT_PRERELEASE"); + } +} diff --git a/src/Cake.Common/Build/WoodpeckerCI/Data/WoodpeckerCIEnvironmentInfo.cs b/src/Cake.Common/Build/WoodpeckerCI/Data/WoodpeckerCIEnvironmentInfo.cs new file mode 100644 index 0000000000..838f753806 --- /dev/null +++ b/src/Cake.Common/Build/WoodpeckerCI/Data/WoodpeckerCIEnvironmentInfo.cs @@ -0,0 +1,441 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Cake.Core; +using Cake.Core.IO; + +namespace Cake.Common.Build.WoodpeckerCI.Data +{ + /// + /// Provides WoodpeckerCI environment information for the current build. + /// + public sealed class WoodpeckerCIEnvironmentInfo : WoodpeckerCIInfo + { + /// + /// Initializes a new instance of the class. + /// + /// The environment. + public WoodpeckerCIEnvironmentInfo(ICakeEnvironment environment) + : base(environment) + { + Repository = new WoodpeckerCIRepositoryInfo(environment); + Commit = new WoodpeckerCICommitInfo(environment); + Pipeline = new WoodpeckerCIPipelineInfo(environment); + Workflow = new WoodpeckerCIWorkflowInfo(environment); + Step = new WoodpeckerCIStepInfo(environment); + System = new WoodpeckerCISystemInfo(environment); + Forge = new WoodpeckerCIForgeInfo(environment); + } + + /// + /// Gets the CI environment name. + /// + /// + /// The CI environment name. + /// + /// Via BuildSystem. + /// + /// + /// if (BuildSystem.WoodpeckerCI.IsRunningOnWoodpeckerCI) + /// { + /// Information( + /// @"CI Environment: {0}", + /// BuildSystem.WoodpeckerCI.Environment.CI + /// ); + /// } + /// else + /// { + /// Information("Not running on WoodpeckerCI"); + /// } + /// + /// + /// Via WoodpeckerCI. + /// + /// + /// if (WoodpeckerCI.IsRunningOnWoodpeckerCI) + /// { + /// Information( + /// @"CI Environment: {0}", + /// WoodpeckerCI.Environment.CI + /// ); + /// } + /// else + /// { + /// Information("Not running on WoodpeckerCI"); + /// } + /// + /// + public string CI => GetEnvironmentString("CI"); + + /// + /// Gets the workspace path. + /// + /// + /// The workspace path. + /// + /// Via BuildSystem. + /// + /// + /// if (BuildSystem.WoodpeckerCI.IsRunningOnWoodpeckerCI) + /// { + /// Information( + /// @"Workspace: {0}", + /// BuildSystem.WoodpeckerCI.Environment.Workspace + /// ); + /// } + /// else + /// { + /// Information("Not running on WoodpeckerCI"); + /// } + /// + /// + /// Via WoodpeckerCI. + /// + /// + /// if (WoodpeckerCI.IsRunningOnWoodpeckerCI) + /// { + /// Information( + /// @"Workspace: {0}", + /// WoodpeckerCI.Environment.Workspace + /// ); + /// } + /// else + /// { + /// Information("Not running on WoodpeckerCI"); + /// } + /// + /// + public DirectoryPath Workspace => GetEnvironmentDirectoryPath("CI_WORKSPACE"); + + /// + /// Gets WoodpeckerCI repository information. + /// + /// + /// The WoodpeckerCI repository information. + /// + /// Via BuildSystem. + /// + /// + /// if (BuildSystem.WoodpeckerCI.IsRunningOnWoodpeckerCI) + /// { + /// Information( + /// @"Repository: + /// Repo: {0} + /// Owner: {1} + /// Name: {2}", + /// BuildSystem.WoodpeckerCI.Environment.Repository.Repo, + /// BuildSystem.WoodpeckerCI.Environment.Repository.RepoOwner, + /// BuildSystem.WoodpeckerCI.Environment.Repository.RepoName + /// ); + /// } + /// else + /// { + /// Information("Not running on WoodpeckerCI"); + /// } + /// + /// + /// Via WoodpeckerCI. + /// + /// + /// if (WoodpeckerCI.IsRunningOnWoodpeckerCI) + /// { + /// Information( + /// @"Repository: + /// Repo: {0} + /// Owner: {1} + /// Name: {2}", + /// WoodpeckerCI.Environment.Repository.Repo, + /// WoodpeckerCI.Environment.Repository.RepoOwner, + /// WoodpeckerCI.Environment.Repository.RepoName + /// ); + /// } + /// else + /// { + /// Information("Not running on WoodpeckerCI"); + /// } + /// + /// + public WoodpeckerCIRepositoryInfo Repository { get; } + + /// + /// Gets WoodpeckerCI commit information. + /// + /// + /// The WoodpeckerCI commit information. + /// + /// Via BuildSystem. + /// + /// + /// if (BuildSystem.WoodpeckerCI.IsRunningOnWoodpeckerCI) + /// { + /// Information( + /// @"Commit: + /// SHA: {0} + /// Branch: {1} + /// Message: {2}", + /// BuildSystem.WoodpeckerCI.Environment.Commit.Sha, + /// BuildSystem.WoodpeckerCI.Environment.Commit.Branch, + /// BuildSystem.WoodpeckerCI.Environment.Commit.Message + /// ); + /// } + /// else + /// { + /// Information("Not running on WoodpeckerCI"); + /// } + /// + /// + /// Via WoodpeckerCI. + /// + /// + /// if (WoodpeckerCI.IsRunningOnWoodpeckerCI) + /// { + /// Information( + /// @"Commit: + /// SHA: {0} + /// Branch: {1} + /// Message: {2}", + /// WoodpeckerCI.Environment.Commit.Sha, + /// WoodpeckerCI.Environment.Commit.Branch, + /// WoodpeckerCI.Environment.Commit.Message + /// ); + /// } + /// else + /// { + /// Information("Not running on WoodpeckerCI"); + /// } + /// + /// + public WoodpeckerCICommitInfo Commit { get; } + + /// + /// Gets WoodpeckerCI pipeline information. + /// + /// + /// The WoodpeckerCI pipeline information. + /// + /// Via BuildSystem. + /// + /// + /// if (BuildSystem.WoodpeckerCI.IsRunningOnWoodpeckerCI) + /// { + /// Information( + /// @"Pipeline: + /// Number: {0} + /// Event: {1}", + /// BuildSystem.WoodpeckerCI.Environment.Pipeline.Number, + /// BuildSystem.WoodpeckerCI.Environment.Pipeline.Event + /// ); + /// } + /// else + /// { + /// Information("Not running on WoodpeckerCI"); + /// } + /// + /// + /// Via WoodpeckerCI. + /// + /// + /// if (WoodpeckerCI.IsRunningOnWoodpeckerCI) + /// { + /// Information( + /// @"Pipeline: + /// Number: {0} + /// Event: {1}", + /// WoodpeckerCI.Environment.Pipeline.Number, + /// WoodpeckerCI.Environment.Pipeline.Event + /// ); + /// } + /// else + /// { + /// Information("Not running on WoodpeckerCI"); + /// } + /// + /// + public WoodpeckerCIPipelineInfo Pipeline { get; } + + /// + /// Gets WoodpeckerCI workflow information. + /// + /// + /// The WoodpeckerCI workflow information. + /// + /// Via BuildSystem. + /// + /// + /// if (BuildSystem.WoodpeckerCI.IsRunningOnWoodpeckerCI) + /// { + /// Information( + /// @"Workflow: {0}", + /// BuildSystem.WoodpeckerCI.Environment.Workflow.Name + /// ); + /// } + /// else + /// { + /// Information("Not running on WoodpeckerCI"); + /// } + /// + /// + /// Via WoodpeckerCI. + /// + /// + /// if (WoodpeckerCI.IsRunningOnWoodpeckerCI) + /// { + /// Information( + /// @"Workflow: {0}", + /// WoodpeckerCI.Environment.Workflow.Name + /// ); + /// } + /// else + /// { + /// Information("Not running on WoodpeckerCI"); + /// } + /// + /// + public WoodpeckerCIWorkflowInfo Workflow { get; } + + /// + /// Gets WoodpeckerCI step information. + /// + /// + /// The WoodpeckerCI step information. + /// + /// Via BuildSystem. + /// + /// + /// if (BuildSystem.WoodpeckerCI.IsRunningOnWoodpeckerCI) + /// { + /// Information( + /// @"Step: + /// Name: {0} + /// Number: {1}", + /// BuildSystem.WoodpeckerCI.Environment.Step.Name, + /// BuildSystem.WoodpeckerCI.Environment.Step.Number + /// ); + /// } + /// else + /// { + /// Information("Not running on WoodpeckerCI"); + /// } + /// + /// + /// Via WoodpeckerCI. + /// + /// + /// if (WoodpeckerCI.IsRunningOnWoodpeckerCI) + /// { + /// Information( + /// @"Step: + /// Name: {0} + /// Number: {1}", + /// WoodpeckerCI.Environment.Step.Name, + /// WoodpeckerCI.Environment.Step.Number + /// ); + /// } + /// else + /// { + /// Information("Not running on WoodpeckerCI"); + /// } + /// + /// + public WoodpeckerCIStepInfo Step { get; } + + /// + /// Gets WoodpeckerCI system information. + /// + /// + /// The WoodpeckerCI system information. + /// + /// Via BuildSystem. + /// + /// + /// if (BuildSystem.WoodpeckerCI.IsRunningOnWoodpeckerCI) + /// { + /// Information( + /// @"System: + /// Name: {0} + /// Version: {1}", + /// BuildSystem.WoodpeckerCI.Environment.System.Name, + /// BuildSystem.WoodpeckerCI.Environment.System.Version + /// ); + /// } + /// else + /// { + /// Information("Not running on WoodpeckerCI"); + /// } + /// + /// + /// Via WoodpeckerCI. + /// + /// + /// if (WoodpeckerCI.IsRunningOnWoodpeckerCI) + /// { + /// Information( + /// @"System: + /// Name: {0} + /// Version: {1}", + /// WoodpeckerCI.Environment.System.Name, + /// WoodpeckerCI.Environment.System.Version + /// ); + /// } + /// else + /// { + /// Information("Not running on WoodpeckerCI"); + /// } + /// + /// + public WoodpeckerCISystemInfo System { get; } + + /// + /// Gets WoodpeckerCI forge information. + /// + /// + /// The WoodpeckerCI forge information. + /// + /// Via BuildSystem. + /// + /// + /// if (BuildSystem.WoodpeckerCI.IsRunningOnWoodpeckerCI) + /// { + /// Information( + /// @"Forge: + /// Type: {0} + /// URL: {1}", + /// BuildSystem.WoodpeckerCI.Environment.Forge.Type, + /// BuildSystem.WoodpeckerCI.Environment.Forge.Url + /// ); + /// } + /// else + /// { + /// Information("Not running on WoodpeckerCI"); + /// } + /// + /// + /// Via WoodpeckerCI. + /// + /// + /// if (WoodpeckerCI.IsRunningOnWoodpeckerCI) + /// { + /// Information( + /// @"Forge: + /// Type: {0} + /// URL: {1}", + /// WoodpeckerCI.Environment.Forge.Type, + /// WoodpeckerCI.Environment.Forge.Url + /// ); + /// } + /// else + /// { + /// Information("Not running on WoodpeckerCI"); + /// } + /// + /// + public WoodpeckerCIForgeInfo Forge { get; } + + private DirectoryPath GetEnvironmentDirectoryPath(string variable) + { + var value = GetEnvironmentString(variable); + return !string.IsNullOrWhiteSpace(value) ? new DirectoryPath(value) : null; + } + } +} diff --git a/src/Cake.Common/Build/WoodpeckerCI/Data/WoodpeckerCIForgeInfo.cs b/src/Cake.Common/Build/WoodpeckerCI/Data/WoodpeckerCIForgeInfo.cs new file mode 100644 index 0000000000..ed21d1c2c6 --- /dev/null +++ b/src/Cake.Common/Build/WoodpeckerCI/Data/WoodpeckerCIForgeInfo.cs @@ -0,0 +1,72 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using Cake.Core; + +namespace Cake.Common.Build.WoodpeckerCI.Data +{ + /// + /// Provides WoodpeckerCI forge information for the current build. + /// + public class WoodpeckerCIForgeInfo : WoodpeckerCIInfo + { + /// + /// Initializes a new instance of the class. + /// + /// The environment. + public WoodpeckerCIForgeInfo(ICakeEnvironment environment) + : base(environment) + { + } + + /// + /// Gets the forge type. + /// + /// + /// The forge type. + /// + /// Via BuildSystem. + /// + /// + /// if (BuildSystem.WoodpeckerCI.IsRunningOnWoodpeckerCI) + /// { + /// Information( + /// @"Forge Type: {0}", + /// BuildSystem.WoodpeckerCI.Environment.Forge.Type + /// ); + /// } + /// else + /// { + /// Information("Not running on WoodpeckerCI"); + /// } + /// + /// + /// Via WoodpeckerCI. + /// + /// + /// if (WoodpeckerCI.IsRunningOnWoodpeckerCI) + /// { + /// Information( + /// @"Forge Type: {0}", + /// WoodpeckerCI.Environment.Forge.Type + /// ); + /// } + /// else + /// { + /// Information("Not running on WoodpeckerCI"); + /// } + /// + /// + public WoodpeckerCIForgeType Type => WoodpeckerCIForgeTypeExtensions.ParseForgeType(GetEnvironmentString("CI_FORGE_TYPE")); + + /// + /// Gets the forge URL. + /// + /// + /// The forge URL. + /// + public Uri Url => GetEnvironmentUri("CI_FORGE_URL"); + } +} diff --git a/src/Cake.Common/Build/WoodpeckerCI/Data/WoodpeckerCIForgeType.cs b/src/Cake.Common/Build/WoodpeckerCI/Data/WoodpeckerCIForgeType.cs new file mode 100644 index 0000000000..85944bc66c --- /dev/null +++ b/src/Cake.Common/Build/WoodpeckerCI/Data/WoodpeckerCIForgeType.cs @@ -0,0 +1,87 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; + +namespace Cake.Common.Build.WoodpeckerCI.Data +{ + /// + /// Represents the type of forge used by WoodpeckerCI. + /// + public enum WoodpeckerCIForgeType + { + /// + /// Unknown forge type. + /// + Unknown = 0, + + /// + /// Bitbucket forge. + /// + Bitbucket = 1, + + /// + /// Bitbucket Data Center forge. + /// + BitbucketDC = 2, + + /// + /// Forgejo forge. + /// + Forgejo = 3, + + /// + /// Gitea forge. + /// + Gitea = 4, + + /// + /// GitHub forge. + /// + GitHub = 5, + + /// + /// GitLab forge. + /// + GitLab = 6 + } + + /// + /// Extension methods for . + /// + public static class WoodpeckerCIForgeTypeExtensions + { + /// + /// Parses a string value to a enum value. + /// + /// The string value to parse. + /// The parsed enum value, or if parsing fails. + public static WoodpeckerCIForgeType ParseForgeType(string value) + { + if (string.IsNullOrWhiteSpace(value)) + { + return WoodpeckerCIForgeType.Unknown; + } + + // Try to parse case-insensitively + if (Enum.TryParse(value, true, out var result)) + { + return result; + } + + // Handle special cases for known values that don't match enum names exactly + var normalizedValue = value.ToLowerInvariant(); + return normalizedValue switch + { + "bitbucket" => WoodpeckerCIForgeType.Bitbucket, + "bitbucket_dc" => WoodpeckerCIForgeType.BitbucketDC, + "forgejo" => WoodpeckerCIForgeType.Forgejo, + "gitea" => WoodpeckerCIForgeType.Gitea, + "github" => WoodpeckerCIForgeType.GitHub, + "gitlab" => WoodpeckerCIForgeType.GitLab, + _ => WoodpeckerCIForgeType.Unknown + }; + } + } +} diff --git a/src/Cake.Common/Build/WoodpeckerCI/Data/WoodpeckerCIPipelineInfo.cs b/src/Cake.Common/Build/WoodpeckerCI/Data/WoodpeckerCIPipelineInfo.cs new file mode 100644 index 0000000000..1d7b27239a --- /dev/null +++ b/src/Cake.Common/Build/WoodpeckerCI/Data/WoodpeckerCIPipelineInfo.cs @@ -0,0 +1,152 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using Cake.Core; + +namespace Cake.Common.Build.WoodpeckerCI.Data +{ + /// + /// Provides WoodpeckerCI pipeline information for the current build. + /// + public class WoodpeckerCIPipelineInfo : WoodpeckerCIInfo + { + /// + /// Initializes a new instance of the class. + /// + /// The environment. + public WoodpeckerCIPipelineInfo(ICakeEnvironment environment) + : base(environment) + { + } + + /// + /// Gets the pipeline number. + /// + /// + /// The pipeline number. + /// + /// Via BuildSystem. + /// + /// + /// if (BuildSystem.WoodpeckerCI.IsRunningOnWoodpeckerCI) + /// { + /// Information( + /// @"Pipeline Number: {0}", + /// BuildSystem.WoodpeckerCI.Environment.Pipeline.Number + /// ); + /// } + /// else + /// { + /// Information("Not running on WoodpeckerCI"); + /// } + /// + /// + /// Via WoodpeckerCI. + /// + /// + /// if (WoodpeckerCI.IsRunningOnWoodpeckerCI) + /// { + /// Information( + /// @"Pipeline Number: {0}", + /// WoodpeckerCI.Environment.Pipeline.Number + /// ); + /// } + /// else + /// { + /// Information("Not running on WoodpeckerCI"); + /// } + /// + /// + public int Number => GetEnvironmentInteger("CI_PIPELINE_NUMBER"); + + /// + /// Gets the pipeline parent number. + /// + /// + /// The pipeline parent number. + /// + public int Parent => GetEnvironmentInteger("CI_PIPELINE_PARENT"); + + /// + /// Gets the pipeline event. + /// + /// + /// The pipeline event. + /// + public string Event => GetEnvironmentString("CI_PIPELINE_EVENT"); + + /// + /// Gets the pipeline URL. + /// + /// + /// The pipeline URL. + /// + public Uri Url => GetEnvironmentUri("CI_PIPELINE_URL"); + + /// + /// Gets the pipeline forge URL. + /// + /// + /// The pipeline forge URL. + /// + public Uri ForgeUrl => GetEnvironmentUri("CI_PIPELINE_FORGE_URL"); + + /// + /// Gets the pipeline deploy target. + /// + /// + /// The pipeline deploy target. + /// + public string DeployTarget => GetEnvironmentString("CI_PIPELINE_DEPLOY_TARGET"); + + /// + /// Gets the pipeline deploy task. + /// + /// + /// The pipeline deploy task. + /// + public string DeployTask => GetEnvironmentString("CI_PIPELINE_DEPLOY_TASK"); + + /// + /// Gets the pipeline created timestamp. + /// + /// + /// The pipeline created timestamp. + /// + public DateTimeOffset Created => GetEnvironmentDateTimeOffset("CI_PIPELINE_CREATED"); + + /// + /// Gets the pipeline started timestamp. + /// + /// + /// The pipeline started timestamp. + /// + public DateTimeOffset Started => GetEnvironmentDateTimeOffset("CI_PIPELINE_STARTED"); + + /// + /// Gets the pipeline files. + /// + /// + /// The pipeline files. + /// + public string Files => GetEnvironmentString("CI_PIPELINE_FILES"); + + /// + /// Gets the pipeline author username. + /// + /// + /// The pipeline author username. + /// + public string Author => GetEnvironmentString("CI_PIPELINE_AUTHOR"); + + /// + /// Gets the pipeline author avatar. + /// + /// + /// The pipeline author avatar. + /// + public Uri Avatar => GetEnvironmentUri("CI_PIPELINE_AVATAR"); + } +} diff --git a/src/Cake.Common/Build/WoodpeckerCI/Data/WoodpeckerCIRepositoryInfo.cs b/src/Cake.Common/Build/WoodpeckerCI/Data/WoodpeckerCIRepositoryInfo.cs new file mode 100644 index 0000000000..832a2710f3 --- /dev/null +++ b/src/Cake.Common/Build/WoodpeckerCI/Data/WoodpeckerCIRepositoryInfo.cs @@ -0,0 +1,152 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using Cake.Core; + +namespace Cake.Common.Build.WoodpeckerCI.Data +{ + /// + /// Provides WoodpeckerCI repository information for the current build. + /// + public class WoodpeckerCIRepositoryInfo : WoodpeckerCIInfo + { + /// + /// Initializes a new instance of the class. + /// + /// The environment. + public WoodpeckerCIRepositoryInfo(ICakeEnvironment environment) + : base(environment) + { + } + + /// + /// Gets the repository full name. + /// + /// + /// The repository full name. + /// + /// Via BuildSystem. + /// + /// + /// if (BuildSystem.WoodpeckerCI.IsRunningOnWoodpeckerCI) + /// { + /// Information( + /// @"Repository: {0}", + /// BuildSystem.WoodpeckerCI.Environment.Repository.Repo + /// ); + /// } + /// else + /// { + /// Information("Not running on WoodpeckerCI"); + /// } + /// + /// + /// Via WoodpeckerCI. + /// + /// + /// if (WoodpeckerCI.IsRunningOnWoodpeckerCI) + /// { + /// Information( + /// @"Repository: {0}", + /// WoodpeckerCI.Environment.Repository.Repo + /// ); + /// } + /// else + /// { + /// Information("Not running on WoodpeckerCI"); + /// } + /// + /// + public string Repo => GetEnvironmentString("CI_REPO"); + + /// + /// Gets the repository owner. + /// + /// + /// The repository owner. + /// + public string RepoOwner => GetEnvironmentString("CI_REPO_OWNER"); + + /// + /// Gets the repository name. + /// + /// + /// The repository name. + /// + public string RepoName => GetEnvironmentString("CI_REPO_NAME"); + + /// + /// Gets the repository remote ID. + /// + /// + /// The repository remote ID. + /// + public string RepoRemoteId => GetEnvironmentString("CI_REPO_REMOTE_ID"); + + /// + /// Gets the repository URL. + /// + /// + /// The repository URL. + /// + public Uri RepoUrl => GetEnvironmentUri("CI_REPO_URL"); + + /// + /// Gets the repository clone URL. + /// + /// + /// The repository clone URL. + /// + public Uri RepoCloneUrl => GetEnvironmentUri("CI_REPO_CLONE_URL"); + + /// + /// Gets the repository SSH clone URL. + /// + /// + /// The repository SSH clone URL. + /// + public string RepoCloneSshUrl => GetEnvironmentString("CI_REPO_CLONE_SSH_URL"); + + /// + /// Gets the repository default branch. + /// + /// + /// The repository default branch. + /// + public string RepoDefaultBranch => GetEnvironmentString("CI_REPO_DEFAULT_BRANCH"); + + /// + /// Gets a value indicating whether the repository is private. + /// + /// + /// true if the repository is private; otherwise, false. + /// + public bool RepoPrivate => GetEnvironmentBoolean("CI_REPO_PRIVATE"); + + /// + /// Gets a value indicating whether the repository has trusted network access. + /// + /// + /// true if the repository has trusted network access; otherwise, false. + /// + public bool RepoTrustedNetwork => GetEnvironmentBoolean("CI_REPO_TRUSTED_NETWORK"); + + /// + /// Gets a value indicating whether the repository has trusted volumes access. + /// + /// + /// true if the repository has trusted volumes access; otherwise, false. + /// + public bool RepoTrustedVolumes => GetEnvironmentBoolean("CI_REPO_TRUSTED_VOLUMES"); + + /// + /// Gets a value indicating whether the repository has trusted security access. + /// + /// + /// true if the repository has trusted security access; otherwise, false. + /// + public bool RepoTrustedSecurity => GetEnvironmentBoolean("CI_REPO_TRUSTED_SECURITY"); + } +} diff --git a/src/Cake.Common/Build/WoodpeckerCI/Data/WoodpeckerCIStepInfo.cs b/src/Cake.Common/Build/WoodpeckerCI/Data/WoodpeckerCIStepInfo.cs new file mode 100644 index 0000000000..f9ae88c474 --- /dev/null +++ b/src/Cake.Common/Build/WoodpeckerCI/Data/WoodpeckerCIStepInfo.cs @@ -0,0 +1,88 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using Cake.Core; + +namespace Cake.Common.Build.WoodpeckerCI.Data +{ + /// + /// Provides WoodpeckerCI step information for the current build. + /// + public class WoodpeckerCIStepInfo : WoodpeckerCIInfo + { + /// + /// Initializes a new instance of the class. + /// + /// The environment. + public WoodpeckerCIStepInfo(ICakeEnvironment environment) + : base(environment) + { + } + + /// + /// Gets the step name. + /// + /// + /// The step name. + /// + /// Via BuildSystem. + /// + /// + /// if (BuildSystem.WoodpeckerCI.IsRunningOnWoodpeckerCI) + /// { + /// Information( + /// @"Step Name: {0}", + /// BuildSystem.WoodpeckerCI.Environment.Step.Name + /// ); + /// } + /// else + /// { + /// Information("Not running on WoodpeckerCI"); + /// } + /// + /// + /// Via WoodpeckerCI. + /// + /// + /// if (WoodpeckerCI.IsRunningOnWoodpeckerCI) + /// { + /// Information( + /// @"Step Name: {0}", + /// WoodpeckerCI.Environment.Step.Name + /// ); + /// } + /// else + /// { + /// Information("Not running on WoodpeckerCI"); + /// } + /// + /// + public string Name => GetEnvironmentString("CI_STEP_NAME"); + + /// + /// Gets the step number. + /// + /// + /// The step number. + /// + public int Number => GetEnvironmentInteger("CI_STEP_NUMBER"); + + /// + /// Gets the step started timestamp. + /// + /// + /// The step started timestamp. + /// + public DateTimeOffset Started => GetEnvironmentDateTimeOffset("CI_STEP_STARTED"); + + /// + /// Gets the step URL. + /// + /// + /// The step URL. + /// + public Uri Url => GetEnvironmentUri("CI_STEP_URL"); + } +} diff --git a/src/Cake.Common/Build/WoodpeckerCI/Data/WoodpeckerCISystemInfo.cs b/src/Cake.Common/Build/WoodpeckerCI/Data/WoodpeckerCISystemInfo.cs new file mode 100644 index 0000000000..28ea95e724 --- /dev/null +++ b/src/Cake.Common/Build/WoodpeckerCI/Data/WoodpeckerCISystemInfo.cs @@ -0,0 +1,87 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Cake.Core; + +namespace Cake.Common.Build.WoodpeckerCI.Data +{ + /// + /// Provides WoodpeckerCI system information for the current build. + /// + public class WoodpeckerCISystemInfo : WoodpeckerCIInfo + { + /// + /// Initializes a new instance of the class. + /// + /// The environment. + public WoodpeckerCISystemInfo(ICakeEnvironment environment) + : base(environment) + { + } + + /// + /// Gets the system name. + /// + /// + /// The system name. + /// + /// Via BuildSystem. + /// + /// + /// if (BuildSystem.WoodpeckerCI.IsRunningOnWoodpeckerCI) + /// { + /// Information( + /// @"System Name: {0}", + /// BuildSystem.WoodpeckerCI.Environment.System.Name + /// ); + /// } + /// else + /// { + /// Information("Not running on WoodpeckerCI"); + /// } + /// + /// + /// Via WoodpeckerCI. + /// + /// + /// if (WoodpeckerCI.IsRunningOnWoodpeckerCI) + /// { + /// Information( + /// @"System Name: {0}", + /// WoodpeckerCI.Environment.System.Name + /// ); + /// } + /// else + /// { + /// Information("Not running on WoodpeckerCI"); + /// } + /// + /// + public string Name => GetEnvironmentString("CI_SYSTEM_NAME"); + + /// + /// Gets the system URL. + /// + /// + /// The system URL. + /// + public string Url => GetEnvironmentString("CI_SYSTEM_URL"); + + /// + /// Gets the system host. + /// + /// + /// The system host. + /// + public string Host => GetEnvironmentString("CI_SYSTEM_HOST"); + + /// + /// Gets the system version. + /// + /// + /// The system version. + /// + public string Version => GetEnvironmentString("CI_SYSTEM_VERSION"); + } +} diff --git a/src/Cake.Common/Build/WoodpeckerCI/Data/WoodpeckerCIWorkflowInfo.cs b/src/Cake.Common/Build/WoodpeckerCI/Data/WoodpeckerCIWorkflowInfo.cs new file mode 100644 index 0000000000..77b9ff72a7 --- /dev/null +++ b/src/Cake.Common/Build/WoodpeckerCI/Data/WoodpeckerCIWorkflowInfo.cs @@ -0,0 +1,63 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Cake.Core; + +namespace Cake.Common.Build.WoodpeckerCI.Data +{ + /// + /// Provides WoodpeckerCI workflow information for the current build. + /// + public class WoodpeckerCIWorkflowInfo : WoodpeckerCIInfo + { + /// + /// Initializes a new instance of the class. + /// + /// The environment. + public WoodpeckerCIWorkflowInfo(ICakeEnvironment environment) + : base(environment) + { + } + + /// + /// Gets the workflow name. + /// + /// + /// The workflow name. + /// + /// Via BuildSystem. + /// + /// + /// if (BuildSystem.WoodpeckerCI.IsRunningOnWoodpeckerCI) + /// { + /// Information( + /// @"Workflow Name: {0}", + /// BuildSystem.WoodpeckerCI.Environment.Workflow.Name + /// ); + /// } + /// else + /// { + /// Information("Not running on WoodpeckerCI"); + /// } + /// + /// + /// Via WoodpeckerCI. + /// + /// + /// if (WoodpeckerCI.IsRunningOnWoodpeckerCI) + /// { + /// Information( + /// @"Workflow Name: {0}", + /// WoodpeckerCI.Environment.Workflow.Name + /// ); + /// } + /// else + /// { + /// Information("Not running on WoodpeckerCI"); + /// } + /// + /// + public string Name => GetEnvironmentString("CI_WORKFLOW_NAME"); + } +} diff --git a/src/Cake.Common/Build/WoodpeckerCI/IWoodpeckerCIProvider.cs b/src/Cake.Common/Build/WoodpeckerCI/IWoodpeckerCIProvider.cs new file mode 100644 index 0000000000..bd67f11b43 --- /dev/null +++ b/src/Cake.Common/Build/WoodpeckerCI/IWoodpeckerCIProvider.cs @@ -0,0 +1,39 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Cake.Common.Build.WoodpeckerCI.Commands; +using Cake.Common.Build.WoodpeckerCI.Data; + +namespace Cake.Common.Build.WoodpeckerCI +{ + /// + /// Represents a WoodpeckerCI provider. + /// + public interface IWoodpeckerCIProvider + { + /// + /// Gets a value indicating whether the current build is running on WoodpeckerCI. + /// + /// + /// true if the current build is running on WoodpeckerCI; otherwise, false. + /// + bool IsRunningOnWoodpeckerCI { get; } + + /// + /// Gets the WoodpeckerCI environment. + /// + /// + /// The WoodpeckerCI environment. + /// + WoodpeckerCIEnvironmentInfo Environment { get; } + + /// + /// Gets the WoodpeckerCI commands. + /// + /// + /// The WoodpeckerCI commands. + /// + WoodpeckerCICommands Commands { get; } + } +} diff --git a/src/Cake.Common/Build/WoodpeckerCI/WoodpeckerCIInfo.cs b/src/Cake.Common/Build/WoodpeckerCI/WoodpeckerCIInfo.cs new file mode 100644 index 0000000000..f2d8cfbe98 --- /dev/null +++ b/src/Cake.Common/Build/WoodpeckerCI/WoodpeckerCIInfo.cs @@ -0,0 +1,91 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using Cake.Core; + +namespace Cake.Common.Build.WoodpeckerCI +{ + /// + /// Base class used to provide information about the WoodpeckerCI environment. + /// + public abstract class WoodpeckerCIInfo + { + private readonly ICakeEnvironment _environment; + + /// + /// Initializes a new instance of the class. + /// + /// The environment. + protected WoodpeckerCIInfo(ICakeEnvironment environment) + { + _environment = environment; + } + + /// + /// Gets an environment variable as a . + /// + /// The environment variable name. + /// The environment variable. + protected string GetEnvironmentString(string variable) + { + return _environment.GetEnvironmentVariable(variable) ?? string.Empty; + } + + /// + /// Gets an environment variable as a . + /// + /// The environment variable name. + /// The environment variable. + protected int GetEnvironmentInteger(string variable) + { + var value = GetEnvironmentString(variable); + return !string.IsNullOrWhiteSpace(value) && int.TryParse(value, out var result) ? result : 0; + } + + /// + /// Gets an environment variable as a . + /// + /// The environment variable name. + /// The environment variable. + protected long GetEnvironmentLong(string variable) + { + var value = GetEnvironmentString(variable); + return !string.IsNullOrWhiteSpace(value) && long.TryParse(value, out var result) ? result : 0; + } + + /// + /// Gets an environment variable as a . + /// + /// The environment variable name. + /// The environment variable. + protected bool GetEnvironmentBoolean(string variable) + { + var value = GetEnvironmentString(variable); + return !string.IsNullOrWhiteSpace(value) && bool.TryParse(value, out var result) && result; + } + + /// + /// Gets an environment variable as a . + /// + /// The environment variable name. + /// The environment variable as a Uri, or null if the value is not a valid absolute URI. + protected Uri GetEnvironmentUri(string variable) + { + var value = GetEnvironmentString(variable); + return !string.IsNullOrWhiteSpace(value) && Uri.TryCreate(value, UriKind.Absolute, out var result) ? result : null; + } + + /// + /// Gets an environment variable as a from a Unix timestamp. + /// + /// The environment variable name. + /// The environment variable as a DateTimeOffset, or DateTimeOffset.MinValue if the value is not a valid Unix timestamp. + protected DateTimeOffset GetEnvironmentDateTimeOffset(string variable) + { + var timestamp = GetEnvironmentLong(variable); + return timestamp > 0 ? DateTimeOffset.FromUnixTimeSeconds(timestamp) : DateTimeOffset.MinValue; + } + } +} diff --git a/src/Cake.Common/Build/WoodpeckerCI/WoodpeckerCIProvider.cs b/src/Cake.Common/Build/WoodpeckerCI/WoodpeckerCIProvider.cs new file mode 100644 index 0000000000..4745181a56 --- /dev/null +++ b/src/Cake.Common/Build/WoodpeckerCI/WoodpeckerCIProvider.cs @@ -0,0 +1,42 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using Cake.Common.Build.WoodpeckerCI.Commands; +using Cake.Common.Build.WoodpeckerCI.Data; +using Cake.Core; +using Cake.Core.IO; + +namespace Cake.Common.Build.WoodpeckerCI +{ + /// + /// Responsible for communicating with WoodpeckerCI. + /// + public sealed class WoodpeckerCIProvider : IWoodpeckerCIProvider + { + private readonly ICakeEnvironment _environment; + + /// + /// Initializes a new instance of the class. + /// + /// The environment. + /// The file system. + public WoodpeckerCIProvider(ICakeEnvironment environment, IFileSystem fileSystem) + { + _environment = environment ?? throw new ArgumentNullException(nameof(environment)); + Environment = new WoodpeckerCIEnvironmentInfo(environment); + Commands = new WoodpeckerCICommands(environment, fileSystem, Environment); + } + + /// + public bool IsRunningOnWoodpeckerCI => !string.IsNullOrWhiteSpace(Environment.CI) && + Environment.CI.Equals("woodpecker", StringComparison.OrdinalIgnoreCase); + + /// + public WoodpeckerCIEnvironmentInfo Environment { get; } + + /// + public WoodpeckerCICommands Commands { get; } + } +} diff --git a/tests/integration/Cake.Common/Build/BuildSystemAliases.cake b/tests/integration/Cake.Common/Build/BuildSystemAliases.cake index 1bb353db17..1afccff5a2 100644 --- a/tests/integration/Cake.Common/Build/BuildSystemAliases.cake +++ b/tests/integration/Cake.Common/Build/BuildSystemAliases.cake @@ -1,5 +1,6 @@ #load "GitHubActions/GitHubActionsProvider.cake" #load "AzurePipelines/AzurePipelinesProvider.cake" +#load "WoodpeckerCI/WoodpeckerCIProvider.cake" Task("Cake.Common.Build.BuildSystemAliases.BuildProvider") .DoesForEach( @@ -12,4 +13,5 @@ Task("Cake.Common.Build.BuildSystemAliases.BuildProvider") Task("Cake.Common.Build.BuildSystemAliases") .IsDependentOn("Cake.Common.Build.BuildSystemAliases.BuildProvider") .IsDependentOn("Cake.Common.Build.GitHubActionsProvider") - .IsDependentOn("Cake.Common.Build.AzurePipelinesProvider"); \ No newline at end of file + .IsDependentOn("Cake.Common.Build.AzurePipelinesProvider") + .IsDependentOn("Cake.Common.Build.WoodpeckerCIProvider"); \ No newline at end of file diff --git a/tests/integration/Cake.Common/Build/WoodpeckerCI/WoodpeckerCIProvider.cake b/tests/integration/Cake.Common/Build/WoodpeckerCI/WoodpeckerCIProvider.cake new file mode 100644 index 0000000000..8c8034244b --- /dev/null +++ b/tests/integration/Cake.Common/Build/WoodpeckerCI/WoodpeckerCIProvider.cake @@ -0,0 +1,84 @@ +#load "WoodpeckerCIProvider.cake" + +Task("Cake.Common.Build.WoodpeckerCIProvider") + .Does(() => { + // Test WoodpeckerCI provider detection + Information("WoodpeckerCI Provider:"); + Information(" IsRunningOnWoodpeckerCI: {0}", BuildSystem.WoodpeckerCI.IsRunningOnWoodpeckerCI); + + if (BuildSystem.WoodpeckerCI.IsRunningOnWoodpeckerCI) + { + Information(" Environment:"); + Information(" CI: {0}", BuildSystem.WoodpeckerCI.Environment.CI); + Information(" Workspace: {0}", BuildSystem.WoodpeckerCI.Environment.Workspace); + + Information(" Repository:"); + Information(" Repo: {0}", BuildSystem.WoodpeckerCI.Environment.Repository.Repo); + Information(" Owner: {0}", BuildSystem.WoodpeckerCI.Environment.Repository.RepoOwner); + Information(" Name: {0}", BuildSystem.WoodpeckerCI.Environment.Repository.RepoName); + Information(" RepoUrl: {0}", BuildSystem.WoodpeckerCI.Environment.Repository.RepoUrl); + Information(" RepoCloneUrl: {0}", BuildSystem.WoodpeckerCI.Environment.Repository.RepoCloneUrl); + Information(" RepoCloneSshUrl: {0}", BuildSystem.WoodpeckerCI.Environment.Repository.RepoCloneSshUrl); + Information(" DefaultBranch: {0}", BuildSystem.WoodpeckerCI.Environment.Repository.RepoDefaultBranch); + Information(" Private: {0}", BuildSystem.WoodpeckerCI.Environment.Repository.RepoPrivate); + Information(" TrustedNetwork: {0}", BuildSystem.WoodpeckerCI.Environment.Repository.RepoTrustedNetwork); + Information(" TrustedVolumes: {0}", BuildSystem.WoodpeckerCI.Environment.Repository.RepoTrustedVolumes); + Information(" TrustedSecurity: {0}", BuildSystem.WoodpeckerCI.Environment.Repository.RepoTrustedSecurity); + + Information(" Commit:"); + Information(" Sha: {0}", BuildSystem.WoodpeckerCI.Environment.Commit.Sha); + Information(" Branch: {0}", BuildSystem.WoodpeckerCI.Environment.Commit.Branch); + Information(" Message: {0}", BuildSystem.WoodpeckerCI.Environment.Commit.Message); + Information(" Author: {0}", BuildSystem.WoodpeckerCI.Environment.Commit.Author); + Information(" AuthorEmail: {0}", BuildSystem.WoodpeckerCI.Environment.Commit.AuthorEmail); + + Information(" Pipeline:"); + Information(" Number: {0}", BuildSystem.WoodpeckerCI.Environment.Pipeline.Number); + Information(" Parent: {0}", BuildSystem.WoodpeckerCI.Environment.Pipeline.Parent); + Information(" Event: {0}", BuildSystem.WoodpeckerCI.Environment.Pipeline.Event); + Information(" Url: {0}", BuildSystem.WoodpeckerCI.Environment.Pipeline.Url); + Information(" ForgeUrl: {0}", BuildSystem.WoodpeckerCI.Environment.Pipeline.ForgeUrl); + Information(" DeployTarget: {0}", BuildSystem.WoodpeckerCI.Environment.Pipeline.DeployTarget); + Information(" DeployTask: {0}", BuildSystem.WoodpeckerCI.Environment.Pipeline.DeployTask); + Information(" Created: {0}", BuildSystem.WoodpeckerCI.Environment.Pipeline.Created); + Information(" Started: {0}", BuildSystem.WoodpeckerCI.Environment.Pipeline.Started); + Information(" Files: {0}", BuildSystem.WoodpeckerCI.Environment.Pipeline.Files); + Information(" Author: {0}", BuildSystem.WoodpeckerCI.Environment.Pipeline.Author); + Information(" Avatar: {0}", BuildSystem.WoodpeckerCI.Environment.Pipeline.Avatar); + + Information(" Workflow:"); + Information(" Name: {0}", BuildSystem.WoodpeckerCI.Environment.Workflow.Name); + + Information(" Step:"); + Information(" Name: {0}", BuildSystem.WoodpeckerCI.Environment.Step.Name); + Information(" Number: {0}", BuildSystem.WoodpeckerCI.Environment.Step.Number); + Information(" Started: {0}", BuildSystem.WoodpeckerCI.Environment.Step.Started); + Information(" Url: {0}", BuildSystem.WoodpeckerCI.Environment.Step.Url); + + Information(" System:"); + Information(" Name: {0}", BuildSystem.WoodpeckerCI.Environment.System.Name); + Information(" Version: {0}", BuildSystem.WoodpeckerCI.Environment.System.Version); + Information(" Host: {0}", BuildSystem.WoodpeckerCI.Environment.System.Host); + + Information(" Forge:"); + Information(" Type: {0}", BuildSystem.WoodpeckerCI.Environment.Forge.Type); + Information(" Url: {0}", BuildSystem.WoodpeckerCI.Environment.Forge.Url); + + // Test Commands + Information(" Commands:"); + try + { + BuildSystem.WoodpeckerCI.Commands.SetEnvironmentVariable("TEST_VAR", "test_value"); + var retrievedValue = BuildSystem.WoodpeckerCI.Commands.GetEnvironmentVariable("TEST_VAR"); + Information(" SetEnvironmentVariable/GetEnvironmentVariable: {0}", retrievedValue); + } + catch (Exception ex) + { + Information(" Commands test failed: {0}", ex.Message); + } + } + else + { + Information(" Not running on WoodpeckerCI"); + } + });