ci: cancel stale pull request workflow runs
PATCH 1/1 ci: cancel stale pull request workflow runs
From: Harald Nordgren <[email protected]>
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.
---
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(-)
.github/workflows/main.yml +11 -9
@@ -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
Signature · 1 line
gitgitgadget
Hi!
It would be nice to get some review here, this will save a lot of CI money.
Harald
"Harald Nordgren via GitGitGadget" <[email protected]> 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.
.github/workflows/main.yml on: [push, pull_request] · line 21
Quoted 3 lines
.github/workflows/main.yml +2
-1- 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.
PATCH v2 1/1 ci: cancel stale pull request workflow runs
In reply to Harald Nordgren via GitGitGadgetFrom: Harald Nordgren <[email protected]>
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.
---
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.
.github/workflows/main.yml | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-)
.github/workflows/main.yml +11 -9
@@ -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
Signature · 1 line
gitgitgadget
Quoted 6 lines · Harald Nordgren via GitGitGadget
From: Harald Nordgren <[email protected]>
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?
.github/workflows/main.yml on: [push, pull_request] · line 21
Quoted 9 lines
Signed-off-by Harald Nordgren <[email protected]>---
....github/workflows/main.yml +3
-1+# 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.
Quoted 11 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?
Quoted 6 lines
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
Quoted 11 lines · Harald Nordgren
Quoted 11 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?
Quoted 8 lines
Quoted 6 lines
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.
PATCH v3 1/1 ci: cancel stale pull request workflow runs
In reply to Harald Nordgren via GitGitGadgetFrom: Harald Nordgren <[email protected]>
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.
---
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(-)
.github/workflows/main.yml +11 -9
@@ -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
Signature · 1 line
gitgitgadget