Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to cancel previous runs in the PR when you push new commits(update the current) in github-actions

When I push my commits to a PR my tests are triggered for this commit. After that, if I push additional commits to this PR, tests in Github Actions runs on both commits.

I need to cancel the previous run and run only on the most recent pushed commit.

How can I configure my yaml file to achieve that?

like image 500
Max Avatar asked Feb 23 '21 14:02

Max


People also ask

How do I stop an action from workflow in github?

Canceling a workflow runUnder your repository name, click Actions. In the left sidebar, click the workflow you want to see. From the list of workflow runs, click the name of the queued or in progress run that you want to cancel. In the upper-right corner of the workflow, click Cancel workflow.

What is Github workflow?

Workflows. A workflow is a configurable automated process that will run one or more jobs. Workflows are defined by a YAML file checked in to your repository and will run when triggered by an event in your repository, or they can be triggered manually, or at a defined schedule.

What happens when I push a specific branch in GitHub?

When you git push, this GitHub Action will capture the current Branch and SHA. It will query GitHub's API to find previous workflow runs that match the Branch but do not match the SHA.

How to only cancel in-progress runs of the same workflow?

To only cancel in-progress runs of the same workflow, you can use the github.workflow property to build the concurrency group: You can use jobs.<job_id>.outputs to create a map of outputs for a job. Job outputs are available to all downstream jobs that depend on this job. For more information on defining job dependencies, see jobs.<job_id>.needs.

Can a workflow cancel itself on the next push?

Read more about the Workflow Runs API. Typically, you will want to add this action as the first step in a workflow so it can cancel itself on the next push. In some cases, you may wish to avoid modifying all your workflows and instead create a new workflow that cancels your other workflows.

What is a GitHub action and how does it work?

This is a GitHub Action that will cancel any previous runs that are not completed for a given workflow. This includes runs with a status of queued or in_progress. How does it work? When you git push, this GitHub Action will capture the current Branch and SHA.


Video Answer


4 Answers

You can use Concurrency:

Concurrency ensures that only a single job or workflow using the same concurrency group will run at a time.

concurrency: 
  group: ${{ github.head_ref }}
  cancel-in-progress: true
like image 69
EmmanuelMess Avatar answered Oct 16 '22 20:10

EmmanuelMess


Update

This is no longer valid, GitHub Actions has improved this experience since. Check out the alternative answer first.

Old answer

Like we had "There's an app for that!", now it's "There's an Action for that!":

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - name: Cancel Previous Runs
        uses: styfle/[email protected]
        with:
          access_token: ${{ github.token }}
      #- name: Run Tests
      #  uses: actions/setup-node@v1
      #  run: node test.js
      # ... etc

https://github.com/styfle/cancel-workflow-action

like image 22
jessehouwing Avatar answered Oct 16 '22 20:10

jessehouwing


To cancel a currently running workflow from the same PR, branch or tag when a new workflow is triggered you can use:

name: Workflow X

on: # ...

concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
  cancel-in-progress: true

jobs: # ...

Explanation:

  • ${{ github.workflow }}: the workflow name is used to generate the concurrency group (e.g. Workflow 1). That allows you to have more than one different workflow (eg. workflow1.yaml and workflow2.yaml) triggered on the same event (e.g. a PR). Otherwise, workflow1.yaml would cancel workflow2.yaml or viceversa.
  • ${{ github.event.pull_request.number: when the trigger event is a PR, it will use the PR number to generate the concurrency group (e.g. workflow1-33).
  • || github.ref }}: when the trigger is not a PR but a push, it will use the branch or tag name to generate the concurrency group (e.g. workflow1-branch1).
  • cancel-in-progress: true: if cancel-in-progress is omitted or set to false, when a new workflow is triggered, the currently running workflow won't be cancelled, and the new workflow will be queued pending until the previous one is done.

Ref: https://docs.github.com/en/actions/using-jobs/using-concurrency

like image 22
David Miguel Avatar answered Oct 16 '22 20:10

David Miguel


You will also want to make sure you account for having multiple workflows in the same repository so that you only cancel in-progress runs of the same workflow.

Snippet from the Using concurrency GitHub docs:

concurrency: 
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

Full, working example (Source):

name: CI with in-progress cancellations

on:
  pull_request:
    branches: [ main ]
  workflow_dispatch:

# This is what will cancel the workflow
concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Print concurrency group
        run: echo '${{ github.workflow }}-${{ github.ref }}'
      - name: Sleep 15s
        run: sleep 15s
like image 2
Philip Avatar answered Oct 16 '22 19:10

Philip