diff --git a/src/Cake.Common.Tests/Fixtures/Build/GitHubActionsInfoFixture.cs b/src/Cake.Common.Tests/Fixtures/Build/GitHubActionsInfoFixture.cs index 5df13154e8..ae0c6d04bb 100644 --- a/src/Cake.Common.Tests/Fixtures/Build/GitHubActionsInfoFixture.cs +++ b/src/Cake.Common.Tests/Fixtures/Build/GitHubActionsInfoFixture.cs @@ -26,6 +26,9 @@ public GitHubActionsInfoFixture() Environment.GetEnvironmentVariable("RUNNER_TEMP").Returns("/home/runner/work/_temp"); Environment.GetEnvironmentVariable("RUNNER_TOOL_CACHE").Returns("/opt/hostedtoolcache"); Environment.GetEnvironmentVariable("RUNNER_WORKSPACE").Returns("/home/runner/work/cake"); + Environment.GetEnvironmentVariable("ImageOS").Returns("ubuntu20"); + Environment.GetEnvironmentVariable("ImageVersion").Returns("20211209.3"); + Environment.GetEnvironmentVariable("RUNNER_USER").Returns("runner"); Environment.GetEnvironmentVariable("GITHUB_ACTION").Returns("run1"); Environment.GetEnvironmentVariable("GITHUB_ACTION_PATH").Returns("/path/to/action"); @@ -46,6 +49,9 @@ public GitHubActionsInfoFixture() Environment.GetEnvironmentVariable("GITHUB_SHA").Returns("d1e4f990f57349334368c8253382abc63be02d73"); Environment.GetEnvironmentVariable("GITHUB_WORKFLOW").Returns("Build"); Environment.GetEnvironmentVariable("GITHUB_WORKSPACE").Returns("/home/runner/work/cake/cake"); + Environment.GetEnvironmentVariable("GITHUB_RUN_ATTEMPT").Returns("2"); + Environment.GetEnvironmentVariable("GITHUB_REF_PROTECTED").Returns("true"); + Environment.GetEnvironmentVariable("GITHUB_REF_NAME").Returns("main"); Environment.GetEnvironmentVariable("ACTIONS_RUNTIME_TOKEN").Returns(ActionRuntimeToken); Environment.GetEnvironmentVariable("ACTIONS_RUNTIME_URL").Returns(ActionRuntimeUrl); @@ -54,13 +60,15 @@ public GitHubActionsInfoFixture() Environment.WorkingDirectory.Returns("/home/runner/work/cake/cake"); } - public GitHubActionsRunnerInfo CreateRunnerInfo() + public GitHubActionsRunnerInfo CreateRunnerInfo(string architecture = null) { + Environment.GetEnvironmentVariable("RUNNER_ARCH").Returns(architecture); return new GitHubActionsRunnerInfo(Environment); } - public GitHubActionsWorkflowInfo CreateWorkflowInfo() + public GitHubActionsWorkflowInfo CreateWorkflowInfo(string refType = null) { + Environment.GetEnvironmentVariable("GITHUB_REF_TYPE").Returns(refType); return new GitHubActionsWorkflowInfo(Environment); } diff --git a/src/Cake.Common.Tests/Unit/Build/GitHubActions/Data/GitHubActionsRunnerInfoTests.cs b/src/Cake.Common.Tests/Unit/Build/GitHubActions/Data/GitHubActionsRunnerInfoTests.cs index 85ae645a23..bca1252fa3 100644 --- a/src/Cake.Common.Tests/Unit/Build/GitHubActions/Data/GitHubActionsRunnerInfoTests.cs +++ b/src/Cake.Common.Tests/Unit/Build/GitHubActions/Data/GitHubActionsRunnerInfoTests.cs @@ -2,6 +2,7 @@ // 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.GitHubActions.Data; using Cake.Common.Tests.Fixtures.Build; using Xunit; @@ -89,5 +90,74 @@ public void Should_Return_Correct_Value() Assert.Equal("/home/runner/work/cake", result); } } + + public sealed class TheImageOSProperty + { + [Fact] + public void Should_Return_Correct_Value() + { + // Given + var info = new GitHubActionsInfoFixture().CreateRunnerInfo(); + + // When + var result = info.ImageOS; + + // Then + Assert.Equal("ubuntu20", result); + } + } + + public sealed class TheImageVersionProperty + { + [Fact] + public void Should_Return_Correct_Value() + { + // Given + var info = new GitHubActionsInfoFixture().CreateRunnerInfo(); + + // When + var result = info.ImageVersion; + + // Then + Assert.Equal("20211209.3", result); + } + } + + public sealed class TheUserProperty + { + [Fact] + public void Should_Return_Correct_Value() + { + // Given + var info = new GitHubActionsInfoFixture().CreateRunnerInfo(); + + // When + var result = info.User; + + // Then + Assert.Equal("runner", result); + } + } + + public sealed class TheArchitectureProperty + { + [Theory] + [InlineData("X86", GitHubActionsArchitecture.X86)] + [InlineData("X64", GitHubActionsArchitecture.X64)] + [InlineData("ARM", GitHubActionsArchitecture.ARM)] + [InlineData("ARM64", GitHubActionsArchitecture.ARM64)] + [InlineData("", GitHubActionsArchitecture.Unknown)] + public void Should_Return_Correct_Value(string value, GitHubActionsArchitecture expected) + { + // Given + var info = new GitHubActionsInfoFixture().CreateRunnerInfo(architecture: value); + + // When + var result = info.Architecture; + + // Then + Assert.Equal(expected, result); + } + } } } diff --git a/src/Cake.Common.Tests/Unit/Build/GitHubActions/Data/GitHubActionsWorkflowInfoTests.cs b/src/Cake.Common.Tests/Unit/Build/GitHubActions/Data/GitHubActionsWorkflowInfoTests.cs index 55924d6dad..fa523ba95a 100644 --- a/src/Cake.Common.Tests/Unit/Build/GitHubActions/Data/GitHubActionsWorkflowInfoTests.cs +++ b/src/Cake.Common.Tests/Unit/Build/GitHubActions/Data/GitHubActionsWorkflowInfoTests.cs @@ -2,6 +2,7 @@ // 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.GitHubActions.Data; using Cake.Common.Tests.Fixtures.Build; using Xunit; @@ -312,5 +313,72 @@ public void Should_Return_Correct_Value() Assert.Equal("/home/runner/work/cake/cake", result); } } + + public sealed class TheAttemptProperty + { + [Fact] + public void Should_Return_Correct_Value() + { + // Given + var info = new GitHubActionsInfoFixture().CreateWorkflowInfo(); + + // When + var result = info.Attempt; + + // Then + Assert.Equal(2, result); + } + } + + public sealed class TheRefProtectedProperty + { + [Fact] + public void Should_Return_Correct_Value() + { + // Given + var info = new GitHubActionsInfoFixture().CreateWorkflowInfo(); + + // When + var result = info.RefProtected; + + // Then + Assert.True(result); + } + } + + public sealed class TheRefNameProperty + { + [Fact] + public void Should_Return_Correct_Value() + { + // Given + var info = new GitHubActionsInfoFixture().CreateWorkflowInfo(); + + // When + var result = info.RefName; + + // Then + Assert.Equal("main", result); + } + } + + public sealed class TheRefTypeProperty + { + [Theory] + [InlineData("branch", GitHubActionsRefType.Branch)] + [InlineData("tag", GitHubActionsRefType.Tag)] + [InlineData("", GitHubActionsRefType.Unknown)] + public void Should_Return_Correct_Value(string value, GitHubActionsRefType expected) + { + // Given + var info = new GitHubActionsInfoFixture().CreateWorkflowInfo(refType: value); + + // When + var result = info.RefType; + + // Then + Assert.Equal(expected, result); + } + } } } diff --git a/src/Cake.Common/Build/GitHubActions/Data/GitHubActionsArchitecture.cs b/src/Cake.Common/Build/GitHubActions/Data/GitHubActionsArchitecture.cs new file mode 100644 index 0000000000..11cce1248b --- /dev/null +++ b/src/Cake.Common/Build/GitHubActions/Data/GitHubActionsArchitecture.cs @@ -0,0 +1,37 @@ +// 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. + +namespace Cake.Common.Build.GitHubActions.Data +{ + /// + /// The GitHub Actions Architecture. + /// + public enum GitHubActionsArchitecture + { + /// + /// Unknown. + /// + Unknown, + + /// + /// X86. + /// + X86, + + /// + /// X64. + /// + X64, + + /// + /// ARM. + /// + ARM, + + /// + /// ARM64. + /// + ARM64 + } +} diff --git a/src/Cake.Common/Build/GitHubActions/Data/GitHubActionsRefType.cs b/src/Cake.Common/Build/GitHubActions/Data/GitHubActionsRefType.cs new file mode 100644 index 0000000000..a87288777f --- /dev/null +++ b/src/Cake.Common/Build/GitHubActions/Data/GitHubActionsRefType.cs @@ -0,0 +1,27 @@ +// 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. + +namespace Cake.Common.Build.GitHubActions.Data +{ + /// + /// The GitHub Actions Ref Type. + /// + public enum GitHubActionsRefType + { + /// + /// Unknown. + /// + Unknown, + + /// + /// Branch. + /// + Branch, + + /// + /// Tag. + /// + Tag + } +} diff --git a/src/Cake.Common/Build/GitHubActions/Data/GitHubActionsRunnerInfo.cs b/src/Cake.Common/Build/GitHubActions/Data/GitHubActionsRunnerInfo.cs index 24431384d2..9361d59993 100644 --- a/src/Cake.Common/Build/GitHubActions/Data/GitHubActionsRunnerInfo.cs +++ b/src/Cake.Common/Build/GitHubActions/Data/GitHubActionsRunnerInfo.cs @@ -62,5 +62,45 @@ public GitHubActionsRunnerInfo(ICakeEnvironment environment) /// The runner workspace directory path. /// public DirectoryPath Workspace => GetEnvironmentDirectoryPath("RUNNER_WORKSPACE"); + + /// + /// Gets the runner image OS on hosted agents. + /// + /// + /// The runner image OS on hosted agents. + /// + public string ImageOS => GetEnvironmentString("ImageOS"); + + /// + /// Gets the runner image version on hosted agents. + /// + /// + /// The runner image version on hosted agents. + /// + public string ImageVersion => GetEnvironmentString("ImageVersion"); + + /// + /// Gets the runner user name. + /// + /// + /// The runner user name. + /// + public string User => GetEnvironmentString("RUNNER_USER"); + + /// + /// Gets the runner architecture of the runner executing the job. + /// + /// + /// The runner architecture of the runner executing the job. Possible values are X86, X64, ARM, and ARM64. + /// + public GitHubActionsArchitecture Architecture => GetEnvironmentString("RUNNER_ARCH") + ?.ToUpperInvariant() switch + { + "X86" => GitHubActionsArchitecture.X86, + "X64" => GitHubActionsArchitecture.X64, + "ARM" => GitHubActionsArchitecture.ARM, + "ARM64" => GitHubActionsArchitecture.ARM64, + _ => GitHubActionsArchitecture.Unknown + }; } } diff --git a/src/Cake.Common/Build/GitHubActions/Data/GitHubActionsWorkflowInfo.cs b/src/Cake.Common/Build/GitHubActions/Data/GitHubActionsWorkflowInfo.cs index b01c2ecfdd..aa89390058 100644 --- a/src/Cake.Common/Build/GitHubActions/Data/GitHubActionsWorkflowInfo.cs +++ b/src/Cake.Common/Build/GitHubActions/Data/GitHubActionsWorkflowInfo.cs @@ -172,5 +172,43 @@ public GitHubActionsWorkflowInfo(ICakeEnvironment environment) /// The GitHub workspace directory path. /// public DirectoryPath Workspace => GetEnvironmentDirectoryPath("GITHUB_WORKSPACE"); + + /// + /// Gets the number of attempts for current run. + /// + /// + /// The attempt number for current run. + /// + public int Attempt => GetEnvironmentInteger("GITHUB_RUN_ATTEMPT"); + + /// + /// Gets a value indicating whether if branch protections are configured for the ref that triggered the workflow run. + /// + /// + /// Value whether if branch protections are configured for the ref that triggered the workflow run. + /// + public bool RefProtected => GetEnvironmentBoolean("GITHUB_REF_PROTECTED"); + + /// + /// Gets the branch or tag name that triggered the workflow run. + /// + /// + /// The branch or tag name that triggered the workflow run. + /// + public string RefName => GetEnvironmentString("GITHUB_REF_NAME"); + + /// + /// Gets the type of ref that triggered the workflow run. + /// + /// + /// The type of ref that triggered the workflow run. Valid values are branch or tag. + /// + public GitHubActionsRefType RefType => GetEnvironmentString("GITHUB_REF_TYPE") + ?.ToLowerInvariant() switch + { + "branch" => GitHubActionsRefType.Branch, + "tag" => GitHubActionsRefType.Tag, + _ => GitHubActionsRefType.Unknown + }; } } diff --git a/tests/integration/Cake.Common/Build/GitHubActions/GitHubActionsProvider.cake b/tests/integration/Cake.Common/Build/GitHubActions/GitHubActionsProvider.cake index df76358646..3afb6799f4 100644 --- a/tests/integration/Cake.Common/Build/GitHubActions/GitHubActionsProvider.cake +++ b/tests/integration/Cake.Common/Build/GitHubActions/GitHubActionsProvider.cake @@ -42,13 +42,40 @@ Task("Cake.Common.Build.GitHubActionsProvider.Commands.UploadArtifact.Directory" .Does(async () => { // Given FilePath path = typeof(ICakeContext).GetTypeInfo().Assembly.Location; - string artifactName = $"Directory_{GitHubActions.Environment.Runner.OS}_{Context.Environment.Runtime.BuiltFramework.Identifier}_{Context.Environment.Runtime.BuiltFramework.Version}"; + string artifactName = $"Directory_{GitHubActions.Environment.Runner.ImageOS ?? GitHubActions.Environment.Runner.OS}_{Context.Environment.Runtime.BuiltFramework.Identifier}_{Context.Environment.Runtime.BuiltFramework.Version}"; // When await GitHubActions.Commands.UploadArtifact(path.GetDirectory(), artifactName); }); -var gitHubActionsProviderTask = Task("Cake.Common.Build.GitHubActionsProvider"); +Task("Cake.Common.Build.GitHubActionsProvider.Environment.Runner.Architecture") + .Does(() => { + // Given / When + var result = GitHubActions.Environment.Runner.Architecture switch { + GitHubActionsArchitecture.Unknown => !GitHubActions.IsRunningOnGitHubActions, + _=> GitHubActions.IsRunningOnGitHubActions + }; + + // Then + Assert.True(result); +}); + +Task("Cake.Common.Build.GitHubActionsProvider.Environment.Workflow.RefType") + .Does(() => { + // Given / When + var result = GitHubActions.Environment.Workflow.RefType switch { + GitHubActionsRefType.Unknown => !GitHubActions.IsRunningOnGitHubActions, + _=> GitHubActions.IsRunningOnGitHubActions + }; + + // Then + Assert.True(result); +}); + + +var gitHubActionsProviderTask = Task("Cake.Common.Build.GitHubActionsProvider") + .IsDependentOn("Cake.Common.Build.GitHubActionsProvider.Environment.Runner.Architecture") + .IsDependentOn("Cake.Common.Build.GitHubActionsProvider.Environment.Workflow.RefType"); if (GitHubActions.IsRunningOnGitHubActions) {