Volume XXII, number 279Tuesday, October 6, 2026Latest message 43 minutes ago

The Git List

News and archive of git@vger.kernel.org, since April 2005

patchci: cancel stale pull request workflow runs

8 messages between Jul 31, 2026 and Aug 31, 2026, from Harald Nordgren via GitGitGadget, Harald Nordgren, Junio C Hamano.

Plain Markdown or JSON for tools and agents. Diffs are folded; open one to read it.

Harald Nordgren via GitGitGadgetJul 31, 2026, 10:10 UTC on lore
From: Harald Nordgren <haraldnordgren@gmail.com>

The CI workflow groups runs by commit hash, so every push to a pull request starts a separate workflow run. Group pull request runs by pull request number and cancel runs superseded by a newer push, while keeping push events grouped by commit hash for the skip-if-redundant behavior.

Signed-off-by: Harald Nordgren <haraldnordgren@gmail.com>
---
    ci: cancel stale pull request workflow runs
    
    Group CI workflow runs by pull request and cancel older revisions so
    only the latest push consumes runner capacity.
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-2369%2FHaraldNordgren%2Fcancel-stale-pr-ci-v1
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-2369/HaraldNordgren/cancel-stale-pr-ci-v1
Pull-Request: https://github.com/git/git/pull/2369
 .github/workflows/main.yml | 20 +++++++++++---------
 1 file changed, 11 insertions(+), 9 deletions(-)
Show changes to .github/workflows/main.yml +11 −9
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index 85cfedf5b0..1dc4ca121c 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -5,18 +5,20 @@ on: [push, pull_request]
 env:
   DEVELOPER: 1
 
-# If more than one workflow run is triggered for the very same commit hash
-# (which happens when multiple branches pointing to the same commit), only
-# the first one is allowed to run, the second will be kept in the "queued"
-# state. This allows a successful completion of the first run to be reused
-# in the second run via the `skip-if-redundant` logic in the `config` job.
+# For pull requests, only the latest workflow run is allowed to proceed.
+# Older runs are canceled when a new revision is pushed.
 #
-# The only caveat is that if a workflow run is triggered for the same commit
-# hash that another run is already being held, that latter run will be
-# canceled. For more details about the `concurrency` attribute, see:
+# For pushes, if more than one workflow run is triggered for the very same
+# commit hash (which happens when multiple branches point to the same commit),
+# only the first one is allowed to run. This allows a successful completion of
+# the first run to be reused in the second run via the `skip-if-redundant`
+# logic in the `config` job.
+#
+# For more details about the `concurrency` attribute, see:
 # https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#concurrency
 concurrency:
-  group: ${{ github.sha }}
+  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }}
+  cancel-in-progress: ${{ github.event_name == 'pull_request' }}
 
 jobs:
   ci-config:

base-commit: a97fcc37c2bc6340a8d7ce78dedf227aac4e9aa7
-- 
gitgitgadget
Harald NordgrenAug 21, 2026, 11:14 UTC in reply to Harald Nordgren via GitGitGadget on lore

Re: [PATCH] ci: cancel stale pull request workflow runs

Hi!
It would be nice to get some review here, this will save a lot of CI money.
Harald
Junio C HamanoAug 26, 2026, 19:54 UTC in reply to Harald Nordgren via GitGitGadget on lore

Re: [PATCH] ci: cancel stale pull request workflow runs

"Harald Nordgren via GitGitGadget" <gitgitgadget@gmail.com> writes:

Nobody seems interested in reviewing this patch, and I am not happy leaving too many topics in the "Needs review" state. So here is my attempt to think aloud, based primarily on what I read in the proposed commit log message. Consider any misunderstanding on my part a sign that the proposed log message is lacking.

> -  group: ${{ github.sha }}
> +  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }}
> +  cancel-in-progress: ${{ github.event_name == 'pull_request' }}

We used to assign each commit to its own group. For a pull-request event, the new configuration instead assigns it to the concurrency group <workflow>-<pull-request-number> (e.g., "main-workflow-42"), so if you are impatient and update an existing pull request before the CI working on it finishes, the new request will be placed in the same group.

For other events, <workflow>-<commit-object-name> is the group used for the commit, which differs from the original behavior, but arguably in a good way. If three or more workflows sharing the same concurrency group are triggered at the same time for the same commit, because there will be at most one active run and one pending run in the same group, we may see some workflows fail to run on the commit.

  NOTE NOTE NOTE: The previous paragraph is based on my incomplete
  understanding of how GitHub Actions works, gathered from skimming
  the documentation.  It needs to be verified, and if correct, it
  should be added to the commit log message.  If it is not correct,
  a revised description discussing how this change does NOT affect
  non-PR events negatively should be included in the commit log
  message instead.

The original configuration did not specify 'cancel-in-progress' at all, so these jobs did not cancel each other. Now, for pull-request events, an earlier run in the same group is canceled when another one is triggered. If you are impatient and update an existing pull request before the CI working on it finishes, the new request will cancel the currently running one and replace it.

For non pull-request events, it is as if no 'cancel-in-progress' were specified, as it defaults to false, so there is no regression there. We _might_ want to have two pushes back to back that causes the CI work on the same commit to drop one of them, but that can be left out as an independent issue.

Thanks.
Harald Nordgren via GitGitGadgetAug 30, 2026, 10:59 UTC in reply to Harald Nordgren via GitGitGadget on lore

[PATCH v2] ci: cancel stale pull request workflow runs

From: Harald Nordgren <haraldnordgren@gmail.com>

The CI workflow previously grouped all runs by commit hash using `group: ${{ github.sha }}`. This meant every push to a pull request started a separate workflow run, and all workflows triggered by the same commit shared the same concurrency group.

With this change, pull request runs are grouped by pull request number instead of commit hash, and runs superseded by a newer push are canceled. The concurrency group becomes `${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }}` and `cancel-in-progress` is set to true for pull request events.

For pull request events, the group is `<workflow>-<pull-request-number>` (e.g., "main-workflow-42"). If you push a new commit to an existing pull request before the CI working on it finishes, the new request will be placed in the same group and cancel the currently running run.

For non-pull-request events, the group is `${{ github.workflow }}-${{ github.sha }}` and `cancel-in-progress` defaults to false, so there is no regression in behavior.

Note that the previous configuration used `group: ${{ github.sha }}`, which meant all workflows sharing the same commit hash were in the same group. The new configuration includes the workflow name in the group, so each workflow has its own concurrency group per commit/PR.

Signed-off-by: Harald Nordgren <haraldnordgren@gmail.com>
---
    ci: cancel stale pull request workflow runs
    
    Group CI workflow runs by pull request and cancel older revisions so
    only the latest push consumes runner capacity.
    
    Changes in v2:
    
     * Explain behavior in commit message.
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-2369%2FHaraldNordgren%2Fcancel-stale-pr-ci-v2
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-2369/HaraldNordgren/cancel-stale-pr-ci-v2
Pull-Request: https://github.com/git/git/pull/2369
Range-diff vs v1:
 1:  a0a618d8cc ! 1:  2773cc5a84 ci: cancel stale pull request workflow runs
     @@ Metadata
       ## Commit message ##
          ci: cancel stale pull request workflow runs
      
     -    The CI workflow groups runs by commit hash, so every push to a pull
     -    request starts a separate workflow run. Group pull request runs by pull
     -    request number and cancel runs superseded by a newer push, while keeping
     -    push events grouped by commit hash for the skip-if-redundant behavior.
     +    The CI workflow previously grouped all runs by commit hash using
     +    `group: ${{ github.sha }}`.  This meant every push to a pull
     +    request started a separate workflow run, and all workflows
     +    triggered by the same commit shared the same concurrency group.
     +
     +    With this change, pull request runs are grouped by pull request
     +    number instead of commit hash, and runs superseded by a newer
     +    push are canceled.  The concurrency group becomes
     +    `${{ github.workflow }}-${{ github.event.pull_request.number ||
     +    github.sha }}` and `cancel-in-progress` is set to true for
     +    pull request events.
     +
     +    For pull request events, the group is `<workflow>-<pull-request-number>`
     +    (e.g., "main-workflow-42").  If you push a new commit to an
     +    existing pull request before the CI working on it finishes, the
     +    new request will be placed in the same group and cancel the
     +    currently running run.
     +
     +    For non-pull-request events, the group is `${{ github.workflow }}-${{
     +    github.sha }}` and `cancel-in-progress` defaults to false, so
     +    there is no regression in behavior.
     +
     +    Note that the previous configuration used `group: ${{ github.sha }}`,
     +    which meant all workflows sharing the same commit hash were in the
     +    same group.  The new configuration includes the workflow name in
     +    the group, so each workflow has its own concurrency group per
     +    commit/PR.
      
          Signed-off-by: Harald Nordgren <haraldnordgren@gmail.com>
      
 .github/workflows/main.yml | 20 +++++++++++---------
 1 file changed, 11 insertions(+), 9 deletions(-)
Show changes to .github/workflows/main.yml +11 −9
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index 205325eb33..4fff344874 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -5,18 +5,20 @@ on: [push, pull_request]
 env:
   DEVELOPER: 1
 
-# If more than one workflow run is triggered for the very same commit hash
-# (which happens when multiple branches pointing to the same commit), only
-# the first one is allowed to run, the second will be kept in the "queued"
-# state. This allows a successful completion of the first run to be reused
-# in the second run via the `skip-if-redundant` logic in the `config` job.
+# For pull requests, only the latest workflow run is allowed to proceed.
+# Older runs are canceled when a new revision is pushed.
 #
-# The only caveat is that if a workflow run is triggered for the same commit
-# hash that another run is already being held, that latter run will be
-# canceled. For more details about the `concurrency` attribute, see:
+# For pushes, if more than one workflow run is triggered for the very same
+# commit hash (which happens when multiple branches point to the same commit),
+# only the first one is allowed to run. This allows a successful completion of
+# the first run to be reused in the second run via the `skip-if-redundant`
+# logic in the `config` job.
+#
+# For more details about the `concurrency` attribute, see:
 # https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#concurrency
 concurrency:
-  group: ${{ github.sha }}
+  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }}
+  cancel-in-progress: ${{ github.event_name == 'pull_request' }}
 
 jobs:
   ci-config:

base-commit: c73e85354c275c9d409b26445089bc16940fc527
-- 
gitgitgadget
Junio C HamanoAug 30, 2026, 22:54 UTC in reply to Harald Nordgren via GitGitGadget on lore

Re: [PATCH v2] ci: cancel stale pull request workflow runs

"Harald Nordgren via GitGitGadget" <gitgitgadget@gmail.com> writes:
Show 6 quoted lines
> From: Harald Nordgren <haraldnordgren@gmail.com>
>
> The CI workflow previously grouped all runs by commit hash using
> `group: ${{ github.sha }}`.  This meant every push to a pull
> request started a separate workflow run, and all workflows
> triggered by the same commit shared the same concurrency group.

That's the current status that we normally describe in the present tense, no?

Show 9 quoted lines
> Signed-off-by: Harald Nordgren <haraldnordgren@gmail.com>
> ---
> ...
> +# For more details about the `concurrency` attribute, see:
>  # https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#concurrency
>  concurrency:
> -  group: ${{ github.sha }}
> +  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }}
> +  cancel-in-progress: ${{ github.event_name == 'pull_request' }}

If a user has CI enabled on their own repository, pushes a commit there, and opens a pull request, wouldn't GitHub Actions trigger two events for the same commit at the tip of the pushed branch?

Before this change, both events are assigned to the same concurrency group (the commit object name). One waits while the other runs, and the skip-if-redundant logic stops the second one early without wasting cycles on the same commit. With this change, the concurrency groups for these two events are separate. Would we end up building and testing the same commit twice in parallel?

I suspect this may not be a problem in practice given how our contributors use GitHub Actions in our official repositories (either those owned by gitgitgadget or git). They push to their own repositories where CI may not be enabled, so 'push' does not trigger. Still, I thought it better to bring this up before the change gets merged and wastes build cycles.

Harald NordgrenAug 31, 2026, 11:12 UTC in reply to Junio C Hamano on lore

Re: [PATCH v2] ci: cancel stale pull request workflow runs

Show 17 quoted lines
> If a user has CI enabled on their own repository, pushes a commit
> there, and opens a pull request, wouldn't GitHub Actions trigger
> two events for the same commit at the tip of the pushed branch?
>
> Before this change, both events are assigned to the same concurrency
> group (the commit object name).  One waits while the other runs, and
> the skip-if-redundant logic stops the second one early without
> wasting cycles on the same commit.  With this change, the
> concurrency groups for these two events are separate.  Would we end
> up building and testing the same commit twice in parallel?
>
> I suspect this may not be a problem in practice given how our
> contributors use GitHub Actions in our official repositories (either
> those owned by gitgitgadget or git).  They push to their own
> repositories where CI may not be enabled, so 'push' does not
> trigger.  Still, I thought it better to bring this up before the
> change gets merged and wastes build cycles.
Concurrency groups don't span repos, so I don't see a solution to that.
Harald
Junio C HamanoAug 31, 2026, 14:33 UTC in reply to Harald Nordgren on lore

Re: [PATCH v2] ci: cancel stale pull request workflow runs

Harald Nordgren <haraldnordgren@gmail.com> writes:
Show 19 quoted lines
>> If a user has CI enabled on their own repository, pushes a commit
>> there, and opens a pull request, wouldn't GitHub Actions trigger
>> two events for the same commit at the tip of the pushed branch?
>>
>> Before this change, both events are assigned to the same concurrency
>> group (the commit object name).  One waits while the other runs, and
>> the skip-if-redundant logic stops the second one early without
>> wasting cycles on the same commit.  With this change, the
>> concurrency groups for these two events are separate.  Would we end
>> up building and testing the same commit twice in parallel?
>>
>> I suspect this may not be a problem in practice given how our
>> contributors use GitHub Actions in our official repositories (either
>> those owned by gitgitgadget or git).  They push to their own
>> repositories where CI may not be enabled, so 'push' does not
>> trigger.  Still, I thought it better to bring this up before the
>> change gets merged and wastes build cycles.
>
> Concurrency groups don't span repos, so I don't see a solution to that.

OK, then I do not see a need for solution to begin with---it is not a problem, in other words ;-).

Thanks.
Harald Nordgren via GitGitGadgetAug 31, 2026, 16:18 UTC in reply to Harald Nordgren via GitGitGadget on lore

[PATCH v3] ci: cancel stale pull request workflow runs

From: Harald Nordgren <haraldnordgren@gmail.com>

The CI workflow groups all runs by commit hash using `group: ${{ github.sha }}`. This means every push to a pull request starts a separate workflow run, and all workflows triggered by the same commit share the same concurrency group.

With this change, pull request runs are grouped by pull request number instead of commit hash, and runs superseded by a newer push are canceled. The concurrency group becomes `${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }}` and `cancel-in-progress` is set to true for pull request events.

For pull request events, the group is `<workflow>-<pull-request-number>` (e.g., "main-workflow-42"). If you push a new commit to an existing pull request before the CI working on it finishes, the new request will be placed in the same group and cancel the currently running run.

For non-pull-request events, the group is `${{ github.workflow }}-${{ github.sha }}` and `cancel-in-progress` defaults to false, so there is no regression in behavior.

Note that the previous configuration used `group: ${{ github.sha }}`, which meant all workflows sharing the same commit hash were in the same group. The new configuration includes the workflow name in the group, so each workflow has its own concurrency group per commit/PR.

Signed-off-by: Harald Nordgren <haraldnordgren@gmail.com>
---
    ci: cancel stale pull request workflow runs
    
    Group CI workflow runs by pull request and cancel older revisions so
    only the latest push consumes runner capacity.
    
    Changes in v3:
    
     * Status quo in present tense in commit message.
    
    Changes in v2:
    
     * Explain behavior in commit message.
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-2369%2FHaraldNordgren%2Fcancel-stale-pr-ci-v3
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-2369/HaraldNordgren/cancel-stale-pr-ci-v3
Pull-Request: https://github.com/git/git/pull/2369
Range-diff vs v2:
 1:  2773cc5a84 ! 1:  61fb54612d ci: cancel stale pull request workflow runs
     @@ Metadata
       ## Commit message ##
          ci: cancel stale pull request workflow runs
      
     -    The CI workflow previously grouped all runs by commit hash using
     -    `group: ${{ github.sha }}`.  This meant every push to a pull
     -    request started a separate workflow run, and all workflows
     -    triggered by the same commit shared the same concurrency group.
     +    The CI workflow groups all runs by commit hash using
     +    `group: ${{ github.sha }}`.  This means every push to a pull
     +    request starts a separate workflow run, and all workflows
     +    triggered by the same commit share the same concurrency group.
      
          With this change, pull request runs are grouped by pull request
          number instead of commit hash, and runs superseded by a newer
 .github/workflows/main.yml | 20 +++++++++++---------
 1 file changed, 11 insertions(+), 9 deletions(-)
Show changes to .github/workflows/main.yml +11 −9
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index 205325eb33..4fff344874 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -5,18 +5,20 @@ on: [push, pull_request]
 env:
   DEVELOPER: 1
 
-# If more than one workflow run is triggered for the very same commit hash
-# (which happens when multiple branches pointing to the same commit), only
-# the first one is allowed to run, the second will be kept in the "queued"
-# state. This allows a successful completion of the first run to be reused
-# in the second run via the `skip-if-redundant` logic in the `config` job.
+# For pull requests, only the latest workflow run is allowed to proceed.
+# Older runs are canceled when a new revision is pushed.
 #
-# The only caveat is that if a workflow run is triggered for the same commit
-# hash that another run is already being held, that latter run will be
-# canceled. For more details about the `concurrency` attribute, see:
+# For pushes, if more than one workflow run is triggered for the very same
+# commit hash (which happens when multiple branches point to the same commit),
+# only the first one is allowed to run. This allows a successful completion of
+# the first run to be reused in the second run via the `skip-if-redundant`
+# logic in the `config` job.
+#
+# For more details about the `concurrency` attribute, see:
 # https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#concurrency
 concurrency:
-  group: ${{ github.sha }}
+  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }}
+  cancel-in-progress: ${{ github.event_name == 'pull_request' }}
 
 jobs:
   ci-config:

base-commit: c73e85354c275c9d409b26445089bc16940fc527
-- 
gitgitgadget

Back to recent threads