Duplicate checks on "push" and "pull_request" simultaneous event

Hi, in an open source repo I’m working on, we’d like to achieve:

Trigger GH actions checks on :

* Any (internal) “push” event , OR

* Any (external / forked) “pull_request” event

Currently, the only way we found to achieve that, is to have the triggers set like:

on: [push, pull_request]

If we get a pull request from a forked repo, the CI runs correctly. The problem is, if we create a pull request ourselves, we get duplicated  checks on all items:

a00b7446ca

And if we just use the trigger as:

on: push

…then, we don’t get double checks in pull requests, and they also run on all internal  push events, but it won’t run on pull requests from forks and that’s also a problem…

Is there any possible way to make it work as we want? 

8 Likes

Hi @tmilar , 

>>If we create a pull request ourselves, we get  duplicated  checks on all items.

For this scenario, for example you have a pull request from feature to master.  The workflow run on push event is triggered by push to feature.  Please check the workflow yml file in the feature branch, is it with 

on: [push, pull_request]  ? 

If it is, then the double checks on push and on pull_request event are as expected. 

If you do not need to trigger a workflow on push to  feature branch, you could add branch filter for push event in your workflow yml file on both feature branch and master branch.  

on:
  push:
    branches:
      - master
  pull_request:
    branches:
      - master

 Hi @yanjingzhu ,

Thanks for your reply. 

Yes, the duplication happens when we have the config:

on: [push, pull_request]

I can understand that double checks might be expected, even though the docs states an “OR” for each event.

However our goal is to have checks, in both cases when:

  1. any project member does a _push _action, to any branch name, so that when a PR is created, the checks are already running (or hopefully finished) - which seems to be better than requiring a pull_request for the checks to start; OR

  2. when an external project  collaborator (whom is not always known beforehand) does a pull_request action from a fork of the repo, in which case the _push _event wouldn’t trigger at all since the fork where the pushes happen, is not our own repo without our GH actions set (as expected).

Is it possible to achieve this combination?

The only alternative we could find, for example, is a solution similar like yours - but it has the issue that if we have an scenario like you described, we would push to  feature  branch and the triggers would not happen. Only after a pull request is created.

3 Likes

Hi @tmilar , 

In your goal, the first one could not meet. Just let me explain more about the two checks (on push and on pull_request) , they are not duplicate.  

The workflow triggered by push and pull_request use different GITHUB_REF. When push to a branch ,the GITHUB_REF of workflow run triggered by push event is the current branch. And workflow run triggered by pull_request event uses refs/pull/:prNumber/merge as its GITHUB_REF. 

So two workflow runs are different. On push checks the branch code, and on pull_request checks the pre-merge code. 

3 Likes

I wanted this too. I want my tests to run on all branches in the repo, but not then be duplicated for internal PRs. I think I’ve managed to do it (hard to test without an external PR, but on a small isolated repo it seemed to work):

https://github.com/Dart-Code/Dart-Code/commit/612732d5879730608baa9622bf7f5e5b7b51ae65

Run for all pushes, but only PRs that aren’t from this repo

if: github.event_name == ‘push’ || github.event.pull_request.head.repo.full_name != ‘Dart-Code/Dart-Code’

6 Likes

I’ve been playing around with this configuration and it’s close but not perfect.

The skipped job shows up in the list of checks in the PR, which isn’t too much of a problem, except that if you’re using a matrix and interpolating values from the matrix into the job name then it shows up unprocessed. Screenshot below.

@dantup I did discover though you can use github.repository in place of a hardcoded repo name. It always gives you the name of the base repo, so it works with a PR from a forked repo.

3 Likes

@johnbillion wrote:

The skipped job shows up in the list of checks in the PR, which isn’t too much of a problem, except that if you’re using a matrix and interpolating values from the matrix into the job name then it shows up unprocessed.

Ah yes, I just noticed that on https://github.com/Dart-Code/Dart-Code/pull/2374. Still, fairly minor, I’ll take it! The doubled runs on my own PRs were really bad (my runs can take around an hour, as there’s a lot of integration tests and run on 3 OSes on both stable and nightly builds of VS Code).

@dantup I did discover though you can use github.repository in place of a hardcoded repo name. It always gives you the name of the base repo, so it works with a PR from a forked repo.

Aha! That’s great - it kinda bugged me hard-coding it like that. Thanks for the PR! 

While the github.repository suggestion is very useful, it do find the fact that the skipped jobs are still listed as skipped a very serious downside. One of the major reasons why I wanted to avoid duplication was to avoid cluttering the UI of checks that may confuse user, maling as easy as possible for the reader to find the ones that failed.

A skipped job does not help with with that at all. Keep in mind that projects that are not very basic can easily have have 10-20 or ever more jobs, duplicated all of these makes the navigation really hard.

Did anyone found a workaround that does not have this downsides?

I think can you add this pull_request synchronize event. Then you will no longer need the push event. I assume you have the PR opened and everytimes you push a commit to the branch, pull_request synchronize event will catch that.

That is not really true if you want to allow those that forked to use GHA on their own repos when they push. Basically the ideal situation would be only use pull-request events when repository is the original one and on forks to only run on pushes.

Sadly my experiments with using github.repository conditions to limit when jobs run or not did not work. Take a look at chore: avoid duplicate builds (internal) by ssbarnea · Pull Request #32 · ansible/ansible-language-server · GitHub maybe you spot what I did wrong. I even printed the github.repository to ensure that the string is what I was expected.

I wonder if we would discover that this is another home-grown-incomplete yaml parser bug.