How to trigger a GitHub action for a branch OR changes to a path?

I would like a GitHub action to kick off on a push or pull request to a specific branch or if it matches a path in any branch. So I wrote

on:
  push:
    branches: [develop]
    paths: ['**/pg.*']
  pull_request:
    branches: [develop]
    paths: ['**/pg.*']

But it only executes for pushes (or PRs presumably) to the “develop” branch. If I update lib/foo/pg.t in any other branch, it does not run. Presumably the branches and paths params have an AND relationship. Is there some way to make it an OR?

1 Like

Alas, it appears that the GitHub Actions on syntax lacks this flexibility. But it can be hacked in thanks to the dorny/paths-filter action (discovered thanks to this SO answer). Here’s how I set it up (source):

name: 🐘 Postgres
on: [push, pull_request]
jobs:
  filter:
    # No need to filter on develop or main.
    if: github.ref != 'refs/heads/develop' && github.ref != 'refs/heads/main'
    runs-on: ubuntu-latest
    name: 🔎 Detect Postgres Changes
    steps:
      - uses: actions/checkout@v2
      - uses: dorny/paths-filter@v2
        id: filter
        with: { filters: '{ pg: [ "**/pg.*", "**Engine**" ] }' }
  Postgres:
    # Run only on develop or main, or when a pg file has changed in the branch.
    if: github.ref == 'refs/heads/develop' || github.ref == 'refs/heads/main' || needs.filter.outputs.pg == 'true'
    # ....

This works nicely, though it does mean that jobs are added and shown as skipped rather than omitted altogether, but at least it does avoid the overhead of running unnecessary tests.

2 Likes

Actually, it turns out this wasn’t working as I thought. It in fact needs to be:

name: 🐘 Postgres
on: [push, pull_request]
jobs:
  filter:
    name: 🔎 Detect Postgres Changes
    runs-on: ubuntu-latest
    outputs:
      pg: ${{ steps.filter.outputs.pg }}
    steps:
      - uses: actions/checkout@v2
      - uses: dorny/paths-filter@v2
        id: filter
        with: { filters: '{ pg: [ "**/pg.*", "**Engine**" ] }' }
  Postgres:
    # Run only on develop or main, or when a pg file has changed in the branch.
    needs: filter
    if: github.ref == 'refs/heads/develop' || github.ref == 'refs/heads/main' || needs.filter.outputs.pg == 'true'
    # ....

Which means it must always run, even on the develop and main branches where it isn’t needed. I ended up abandoning this as overcomplicated in favor of a standard for branch naming:

name: 🐘 Postgres
on:
  push:
    branches: [main, develop, "**engine**", "**postgres**" ]
  pull_request:
    branches: [main, develop, "**engine**", "**postgres**" ]

Much simpler, and the branch just need to be named to match “Postgres”. And even if it doesn’t, it will run the tests once a pull request is made to develop.