Prevent GitHub Actions from running twice when pushing to branch with open pull request

I’m facing an issue with my GitHub Actions workflow getting triggered multiple times. Right now my workflow runs every time I push code to any branch. This works fine when I’m pushing to branches without pull requests.

But here’s the problem: when I create a pull request and then push more commits to that same branch, my GitHub Actions run twice. Once for the push event and once for the pull request event. This is wasteful and I want to avoid it.

What I want to achieve:

  • When there’s an open PR and I push to that branch, only run the workflow once (preferably for the PR event)
  • When there’s no open PR and I push to a branch, run the workflow normally

I’ve been trying different conditional statements in my workflow but can’t get it right. Here’s what I have so far:

on:
  push:
    branches:
      - '**'
  pull_request:
    branches:
      - main
      - develop

jobs:
  test:
    if: |
      github.event_name == 'pull_request' ||
      (github.event_name == 'push' &&
      !contains(github.event.pull_request.html_url, 'https://github.com/'))
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Run tests
        run: echo "Running tests"

This condition isn’t working as expected. How can I properly configure the workflow to avoid duplicate runs?

Had this exact problem a few months ago and found a much cleaner fix. GitHub doesn’t expose PR info in push events, so your conditional will never work. I switched to using the concurrency key to cancel redundant runs instead of trying to block them:

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

Both events can trigger, but the push event gets auto-cancelled when the PR event starts. Way simpler than complex conditionals and handles edge cases better. Keep your push and pull_request triggers, just ditch that broken if condition.

Your conditional check isn’t working because github.event.pull_request.html_url doesn’t exist in push events. I’ve hit this exact issue before. Easiest fix: modify your workflow to check if the commit is already being tested in a PR context. Add this to your push jobs: if: github.event_name == 'pull_request' || (github.event_name == 'push' && !github.event.pull_request). You could also use paths-ignore or branches-ignore, but conditionals give you more control. The main thing to remember is that GitHub doesn’t automatically connect push events to existing PRs in the workflow context.

your condition logic’s messed up. drop the push trigger completely - just use pull_request and pull_request_target events. that’ll run once per pr update and stop the duplicate runs from push events.

Just split the workflows completely. Make one for push events (no PR checks) and another that only runs on pull_request events. Way cleaner than wrestling with broken conditionals.