Conditional Steps and Jobs

if: on a job or step decides whether it runs (the ${{ }} may be left out there). Every job and step has an implicit if: success(): run only if nothing before it failed. The status functions failure(), cancelled() and always() override that. The pr-note job uses a plain condition, if: github.event_name == 'pull_request'; the last job of fundamentals.yml uses a status function:

The report job of fundamentals.ymlYAML
  report:
    needs: [syntax, catalog]
    if: always()
    runs-on: ubuntu-24.04
    steps:
      - run: echo "syntax=${{ needs.syntax.result }} catalog=${{ needs.catalog.result }}"
      - if: contains(needs.*.result, 'failure')
        run: echo "::error::A job this report needs has failed" && exit 1

In the manual run with break-syntax=true (36130315657), the last step of syntax ran because its if was true, and failed the job. catalog was skipped because a job it needs failed; pr-note was skipped by its own condition, which is not a failure. report ran thanks to always(), printed syntax=failure catalog=skipped (a result is success, failure, cancelled or skipped), and failed on purpose.

The run page of 36130315657: syntax failed, catalog was skipped, report ran and failed
The run page of 36130315657: syntax failed, catalog was skipped, report ran and failed

Prefer if: ${{ !cancelled() }} to always(), which runs even after Cancel. A job that must block a merge has to fail for real, as report does; an annotation alone leaves the check green.