Why do I get a "push" event instead of a "pull_request" on a PR merge to master

Hello folks!

The problematic (may be an issue/bug) : When I merge a PR from a branch to master (default) or synch a branch from master, in my action workflow, I’m getting a “push” event, but I’m expecting the “pull_request” one

For you to get an overview of the git structure flow I’m using, here it is :

  • We have 3 branches, develop, staging and master (which is the default branch)
  • The merge flow is developstagingmaster
  • CI/CD triggers on closed and merged PR from developstaging, and also when PUSH on master (hotfix scenario), condition below :
job-name:
  if: (github.event.pull_request.merged == true && github.event.pull_request.head.ref == 'develop') || github.event_name == 'push'
  • CI/CD workflow automatically build docker images if files within a given directory are edited

So far, PRs from develop to staging (and reverse for sync) trigger the expected event and workflow job, I’m getting github.event_name : "pull_request" and github.head_ref : "develop" or "staging", depends if its a sync or not", which I use in my job condition (if)

But when it comes to PRs from staging to master, I’m expecting the same event (with github.event_name : "pull_request" and github.head_ref : "staging") but I’m getting “push” instead, which triggers the action also on master branch, which breaks my CI/CD control structure. It shouldn’t trigger, according to the condition (if) above and the expected event.

And “push” events doesn’t seem to include any value I can use to detect whether it comes from staging or master itself, except for the PR commit name but I don’t want to rely on names which can change over time.

Is every “pull_request” event followed by a “push” one? Because I’ve been trying the following and got two events, so two running workflow when PR staging to master :

on:
  pull_request:
    branches:
      - 'staging'
      - 'master'
    types:
      - closed
      - synchronize # Not used yet, but could be useful for pre-test checks
    paths:
      - '.github/workflows/generic-docker.yaml'
      - 'service-one/**'
      - 'service-two/**'
  # Hotfix process when pushing directly to master
  push:
    branches:
      - 'master'

Am I misunderstanding some points here, I’ve been searching documentation on this, but still no luck…

The workflow file :

on:
  # Clean process flow when merging branches
  pull_request:
    branches:
      - 'staging'
    types:
      - closed
      - synchronize # Not used yet, but could be useful for pre-test checks
    paths:
      - '.github/workflows/generic-docker.yaml'
      - 'service-one/**'
      - 'service-two/**'
  # Hotfix process when pushing directly to master
  push:
    branches:
      - 'master'
    paths:
      - '.github/workflows/generic-docker.yaml'
      - 'service-one/**'
      - 'service-two/**'

jobs:
  generic-docker:
    runs-on: ubuntu-latest
    if: (github.event.pull_request.merged == true && github.event.pull_request.head.ref == 'develop') || github.event_name == 'push'
    steps:
    	# Run specific steps depending on which files changed
    	# ...

Does anyone have a clue on how I could solve this, in a reliable way? Thanks for reading!

Thanks!

Just commenting briefly to say what you’re experiencing is expected. pull_request event triggers when a PR event occurs targeting the branches specified in the workflow. push event is triggered whenever a commit is pushed to the specified branches.

Since a PR merge is just a commit pushed to the target branch it will trigger push events as you’ve seen.

I can’t think of an easy way to accomplish what you want but one more complicated possibility would be to make an API call to see if the push commit is seen in any recent pull requests. If it’s not then you know it’s a hotfix push.

edit: clarified that your events don’t happen on open. Also, in the end you’ll probably want a workflow file similar to the one you tried where you list both staging and master in the pull_request section.

Hey @melink14! Thanks for the quick reply!

You just made my day :sun_with_face: I do now understand a bit more, is there any documentation about those behaviors? I already did search a lot, I may not be good at searching :upside_down_face:?

Anyway, I’m just answering briefly, I’m testing my new CI/CD workflow and it seems to work as expected! TL;DR; I’m filtering hotfixes on the base branch’s name, and instead of a push event I’m only using the pull_request one. And hotfixes need to have their own branches, from the base branch they’re aimed to fix.

This basically did the trick:

name: Generic docker
on:
  pull_request:
    branches:
      - 'staging'
      - 'master'
    types:
      - closed
      - synchronize
    paths:
      - '.github/workflows/generic-docker.yaml'
      - 'service-one/**'
      - 'service-two/**'
jobs:
  generic-docker-build-push:
    runs-on: ubuntu-latest
    if: github.event.pull_request.merged == true && ( github.event.pull_request.head.ref == 'develop' || startsWith(github.event.pull_request.head.ref, 'hotfix/') )
    steps:
        ...

I don’t like the fact of using the branch name in a job condition, but for time purposes, we’ll start with this alternative. I’ll dig into some more API documentation, or Github’s marketplace to found a more reliable way to achieve this :+1:

Thanks again! Cheers!

Don’t feel bad, I think the documentation is a bit lacking when it comes to details and worked examples. (For example, how pull request branch targeting works is not explained in the event trigger docs)

The only real place I could find this was a blurb in the GitHub action syntax docs where it talks about the syntax for adding branch restrictions to pull_request triggers:

(The part about the restrictions applying to the base)

Essentially the core of action documentation will come from experience, this forum, and various GitHub repo issue threads. :smiley:

Good luck! Glad you found a short term fix; at first, I thought you were implying that you wanted to push hotfixes directly to the main branch with no PR which would be even harder!

1 Like