Search code examples
github-actionscicd

Some troubles about Github Action workflows and branch protection


Problem

I have a format workflow, which will run some format code, such as gofmt, and then push to the source branch of the pull request. For example:

name: Format

on:
  pull_request_target:
    branches:
      - master

permissions:
  contents: write

jobs:
  format:
    runs-on: 'ubuntu-latest'

    steps:
      - uses: actions/checkout@v4
        with:
          ref: ${{ github.head_ref }}

      - name: Set up Go
        uses: actions/setup-go@v5
        with:
          go-version: '1.22'

      - name: gofmt
        run: |
          if [ "$(gofmt -s -l -w . | wc -l)" -gt 0 ]; then
          git config --local user.name 'github-actions[bot]'
          git config --local user.email '41898282+github-actions[bot]@users.noreply.github.com'
          git add --all
          git commit -m "gofmt"
          git push
          fi

Okey, it works well.

Now I have another workflow named build, witch will run go test and go build.

Then I set my branch protected strategy: build workflow must pass before merging the pull request.

When a pull request is opened, gofmt workflow runs and push a new commit to the pull request source branch. But this new commit by gofmt workflow cannot trigger build workflow automatically because of Github Action's security policy. So I can't merge the pull request for a reason that build workflow doesn't pass.

Expecting

  • Pull request will be formatted automatically.
  • The branch protected strategy works. (build workflow must pass before merge the pull request.)
  • I can merge the pull request.

or:

  • fmt workflow can work on push event on master branch and bypass the branch protected strategy.

Either of the two solutions above can solve my problem.


Edited on 2024-4-10

Github Docs: https://docs.github.com/en/actions/security-guides/automatic-token-authentication#using-the-github_token-in-a-workflow

When you use the repository's GITHUB_TOKEN to perform tasks, events triggered by the GITHUB_TOKEN, with the exception of workflow_dispatch and repository_dispatch, will not create a new workflow run. This prevents you from accidentally creating recursive workflow runs. For example, if a workflow run pushes code using the repository's GITHUB_TOKEN, a new workflow will not run even when the repository contains a workflow configured to run when push events occur.

Commits pushed by a GitHub Actions workflow that uses the GITHUB_TOKEN do not trigger a GitHub Pages build.

Then I tried to use PAT instead of GITHUB_TOKEN, like this:

      - name: gofmt
        env:
          PAT: ${{ secrets.GH_PAT }}
        run: |
          if [ "$(gofmt -s -l -w . | wc -l)" -gt 0 ]; then
          git config --local user.name 'github-actions[bot]'
          git config --local user.email '41898282+github-actions[bot]@users.noreply.github.com'
          git add --all
          git commit -m "gofmt"
          git push
          fi

It could not trigger the build workflow, either. I am not sure whether I use PAT here properly.


Solution

  • PAT is needed in both actions/checkout and push jobs, like this:

    name: GoFmt
    
    on:
      pull_request:
        branches: [ master ]
    
    jobs:
    
      gofmt:
        runs-on: ubuntu-latest
        steps:
          - uses: actions/checkout@v4
            with:
              ref: ${{ github.head_ref }}
              token: ${{ secrets.GH_PAT }}
    
          - name: Set up Go
            uses: actions/setup-go@v5
            with:
              go-version: '1.22'
    
          - name: gofmt
            run: |
              if [ "$(gofmt -s -l -w . | wc -l)" -gt 0 ]; then
              git config --local user.name 'github-actions[bot]'
              git config --local user.email '41898282+github-actions[bot]@users.noreply.github.com'
              git add --all
              git commit -m "gofmt"
              fi
    
          - name: Push changes
            uses: ad-m/github-push-action@master
            with:
              branch: ${{ github.head_ref }}
              github_token: ${{ secrets.GH_PAT }}
    

    Now it works. When this format workflow pushes commits, the build workflow will be triggered.