From 43efb5c6270e6fc148fd9ec6416302b4498f9cae Mon Sep 17 00:00:00 2001 From: Marko Lahma Date: Wed, 3 Jul 2024 19:31:58 +0300 Subject: [PATCH] feat(cicd): add ConcurrencyGroup and ConcurrencyCancelInProgress to GitHubActionsAttribute (#1299) --- ...ribute=GitHubActionsAttribute.verified.txt | 10 +++++--- .../CI/ConfigurationGenerationTest.cs | 4 +++- .../GitHubActionsConfiguration.cs | 24 +++++++++++++++++++ .../GitHubActions/GitHubActionsAttribute.cs | 5 ++++ 4 files changed, 39 insertions(+), 4 deletions(-) diff --git a/source/Nuke.Common.Tests/CI/ConfigurationGenerationTest.Test_testName=detailed-triggers_attribute=GitHubActionsAttribute.verified.txt b/source/Nuke.Common.Tests/CI/ConfigurationGenerationTest.Test_testName=detailed-triggers_attribute=GitHubActionsAttribute.verified.txt index cba457564..b134fb2bf 100644 --- a/source/Nuke.Common.Tests/CI/ConfigurationGenerationTest.Test_testName=detailed-triggers_attribute=GitHubActionsAttribute.verified.txt +++ b/source/Nuke.Common.Tests/CI/ConfigurationGenerationTest.Test_testName=detailed-triggers_attribute=GitHubActionsAttribute.verified.txt @@ -44,13 +44,17 @@ on: schedule: - cron: '* 0 * * *' +concurrency: + group: ${{ github.workflow }} @ ${{ github.event.pull_request.head.label || github.head_ref || github.run_id }} + cancel-in-progress: true + jobs: macos-latest: name: macos-latest runs-on: macos-latest timeout-minutes: 30 concurrency: - group: ${{ github.workflow }} @ ${{ github.event.pull_request.head.label || github.head_ref || github.run_id }} + group: custom-job-group cancel-in-progress: true steps: - uses: actions/checkout@v4 @@ -95,7 +99,7 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 30 concurrency: - group: ${{ github.workflow }} @ ${{ github.event.pull_request.head.label || github.head_ref || github.run_id }} + group: custom-job-group cancel-in-progress: true steps: - uses: actions/checkout@v4 @@ -140,7 +144,7 @@ jobs: runs-on: windows-latest timeout-minutes: 30 concurrency: - group: ${{ github.workflow }} @ ${{ github.event.pull_request.head.label || github.head_ref || github.run_id }} + group: custom-job-group cancel-in-progress: true steps: - uses: actions/checkout@v4 diff --git a/source/Nuke.Common.Tests/CI/ConfigurationGenerationTest.cs b/source/Nuke.Common.Tests/CI/ConfigurationGenerationTest.cs index e9fd9704f..43776b80d 100644 --- a/source/Nuke.Common.Tests/CI/ConfigurationGenerationTest.cs +++ b/source/Nuke.Common.Tests/CI/ConfigurationGenerationTest.cs @@ -159,7 +159,9 @@ public class TestBuild : NukeBuild Progress = false, Filter = "tree:0", TimeoutMinutes = 30, - JobConcurrencyCancelInProgress = true + ConcurrencyCancelInProgress = true, + JobConcurrencyCancelInProgress = true, + JobConcurrencyGroup = "custom-job-group" } ); diff --git a/source/Nuke.Common/CI/GitHubActions/Configuration/GitHubActionsConfiguration.cs b/source/Nuke.Common/CI/GitHubActions/Configuration/GitHubActionsConfiguration.cs index bd1425827..72359ed6c 100644 --- a/source/Nuke.Common/CI/GitHubActions/Configuration/GitHubActionsConfiguration.cs +++ b/source/Nuke.Common/CI/GitHubActions/Configuration/GitHubActionsConfiguration.cs @@ -18,6 +18,8 @@ public class GitHubActionsConfiguration : ConfigurationEntity public GitHubActionsTrigger[] ShortTriggers { get; set; } public GitHubActionsDetailedTrigger[] DetailedTriggers { get; set; } public (GitHubActionsPermissions Type, string Permission)[] Permissions { get; set; } + public string ConcurrencyGroup { get; set; } + public bool ConcurrencyCancelInProgress { get; set; } public GitHubActionsJob[] Jobs { get; set; } public override void Write(CustomFileWriter writer) @@ -46,6 +48,28 @@ public override void Write(CustomFileWriter writer) } } + if (!ConcurrencyGroup.IsNullOrWhiteSpace() || ConcurrencyCancelInProgress) + { + writer.WriteLine(); + writer.WriteLine("concurrency:"); + using (writer.Indent()) + { + var group = ConcurrencyGroup; + if (group.IsNullOrWhiteSpace()) + { + // create a default value that only cancels in-progress runs of the same workflow + // we don't fall back to github.ref which would disable multiple runs in main/master which is usually what is wanted + group = "${{ github.workflow }} @ ${{ github.event.pull_request.head.label || github.head_ref || github.run_id }}"; + } + + writer.WriteLine($"group: {group}"); + if (ConcurrencyCancelInProgress) + { + writer.WriteLine("cancel-in-progress: true"); + } + } + } + writer.WriteLine(); writer.WriteLine("jobs:"); diff --git a/source/Nuke.Common/CI/GitHubActions/GitHubActionsAttribute.cs b/source/Nuke.Common/CI/GitHubActions/GitHubActionsAttribute.cs index 90c0a8ef5..8aef0f6fd 100644 --- a/source/Nuke.Common/CI/GitHubActions/GitHubActionsAttribute.cs +++ b/source/Nuke.Common/CI/GitHubActions/GitHubActionsAttribute.cs @@ -77,6 +77,9 @@ public GitHubActionsAttribute( public int TimeoutMinutes { get; set; } + public string ConcurrencyGroup { get; set; } + public bool ConcurrencyCancelInProgress { get; set; } + public string JobConcurrencyGroup { get; set; } public bool JobConcurrencyCancelInProgress { get; set; } @@ -126,6 +129,8 @@ public override ConfigurationEntity GetConfiguration(IReadOnlyCollection (x, "write")) .Concat(ReadPermissions.Select(x => (x, "read"))).ToArray(), + ConcurrencyGroup = ConcurrencyGroup, + ConcurrencyCancelInProgress = ConcurrencyCancelInProgress, Jobs = _images.Select(x => GetJobs(x, relevantTargets)).ToArray() };