Push to protected branch from GitHub actions
It turns out that you really can't just git push from your GitHub actions if the repository has branch protection turned on or required checks before merging. Sorta makes sense, but still a PITA.
The solution that worked for me was to use a different token on checkout. Since the awesome GitHub CLI allows using a separate, higher-permissions token named GH_TOKEN (since depending on the command you use, you might need a different one than GITHUB_TOKEN), I decided to (ab)use the same:
An example workflow that uses this to generate a full changelog and push it to main on releases looks like this:
1
name: changelog
2
on:
3
release:
4
types: [released]
5
​
6
env:
7
GH_TOKEN: ${{ secrets.GH_TOKEN }}
8
​
9
jobs:
10
changelog:
11
runs-on: ubuntu-latest
12
steps:
13
- name: πŸ” GH_TOKEN
14
if: env.GH_TOKEN == ''
15
env:
16
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
17
run: echo "GH_TOKEN=${GITHUB_TOKEN}" >> $GITHUB_ENV
18
​
19
- name: 🀘 checkout
20
uses: actions/[email protected]
21
with:
22
fetch-depth: 0
23
ref: main
24
token: ${{ env.GH_TOKEN }}
25
​
26
- name: βš™ changelog
27
uses: faberNovel/[email protected]
28
with:
29
options: --token ${{ secrets.GITHUB_TOKEN }} --o changelog.md
30
​
31
- name: πŸš€ changelog
32
run: |
33
git config --local user.name github-actions
34
git config --local user.email [email protected]
35
git add changelog.md
36
git commit -m "πŸ–‰ Update changelog with ${GITHUB_REF#refs/*/}"
37
git push
Copied!
Important parts:
  • I default the GH_TOKEN envvar to a same-name secret, if present
  • If it's not present, I default it to GITHUB_TOKEN
  • Checkout always uses GH_TOKEN, which now may be a higher-permissions PAT than the default
  • I do the defaulting since the push will succeed if the repository doesn't use branch protection for main and in that case I don't want to always force the presence of a GH_TOKEN secret.
Last modified 1mo ago
Copy link