What is the canonical default workflow?

I noticed a LOT of variation / confusion over the first few lines of an action:

      - main

So I am thinking, what is the default? What should be the default?

Because I’ve also noticed a lot of people using something like if: github.ref == 'refs/heads/main' && github.event_name == 'push'. So I am thinking is on: redundant?

The simple answer is: it depends.

There is no canonical way of using GitHub Actions. It all depends on your project and your strategy.

If you decide using the feature branch model, there is a main branch and branches for features / changes. No commits are pushed directly to the main branch. They have to pass a code review via a Pull Request.
With your provided lines from a workflow, you will cover a feature branch model:

  • whenever someone creates a pull request, the workflow is run
  • when the pull request gets merged into main, the workflow is run

Sorry, what is the alternative to feature branch model, since I think that’s pretty much the standard workflow I’ve noticed.

Thank you for your time.

Here you find a list of alternatives:

Even within a feature branch strategy there can be different variations. You should think about the benefits of GitHub actions and you will know, what workflow do you want.

At the very basic, you want automated tests and checks (like coding styles, secrets etc.) whenever something changes.

But this is just one part of a repository. There can be other workflows, for example for releases.

Thank you @Zerotask, though the issue that I have with your alternatives is that they don’t spell out the structure of a Github action.

Just take the commonplace feature branch model. I find there is a lot of variation on how the build job (should happen on both pull_request and push), and the deploy job, should only happen on push.

Shouldn’t there be some good almost canonical minimal examples?

if isn’t valid syntax at the workflow level, so I assume you’re seeing it at the job level.

That, in essence, is the difference between it and on:

  • on declarations apply to the entire workflow and all jobs defined in it.
  • if conditionals apply only to the jobs in which they are declared.

(if conditionals can also be declared on steps within a job, but that’s not important for this discussion.)

That can lead to a blended approach, like the following:

name: both_on_and_if
on: [pull_request, push]
    if: github.event_name == 'push'
      [ ... ]

    if: github.event_name == 'pull_request' && github.event.pull_request.action == 'opened'
      [ ... ]