Recently I've been playing around with GitHub Actions to familiarize myself more with them. I also find it quite satisfying to maintain a certain level of stability and reliability even on my own personal projects, especially given the fact that the amount of free time I have to spend on them varies wildly from week to week. Additionally, I've been exploring the use of dependabot to help me keep dependencies up-to-date, which is particularly useful for me given the number of personal projects I have. So for each project, I've begun to introduce a pull request workflow, that runs tests and ensures that the project builds (usually an Android or JVM project), and the PR will be marked for auto-merge if the author is myself or dependabot and all the required checks pass. Here's an example of what that workflow looks like on one of my personal projects:
pull-request.yml
name: Pull request workflow
on: pull_request
permissions:
contents: write
pull-requests: write
checks: write
jobs:
test:
name: Build and Test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-java@v3
with:
distribution: temurin
java-version: 17
- name: Validate Gradle Wrapper
uses: gradle/wrapper-validation-action@v1
- name: Build with Gradle
uses: gradle/gradle-build-action@v2
with:
arguments: --stacktrace build
- name: Publish JUnit Results
uses: dorny/test-reporter@v1
if: always()
with:
name: Unit Tests
path: "*/build/test-results/test/*.xml"
reporter: java-junit
fail-on-error: true
automerge:
name: Enable automerge
runs-on: ubuntu-latest
if: ${{ github.actor == 'wbrawner' || github.actor == 'dependabot[bot]' }}
steps:
- name: Enable auto-merge
run: gh pr merge --auto --rebase "$PR_URL"
env:
PR_URL: ${{github.event.pull_request.html_url}}
GH_TOKEN: ${{secrets.GH_TOKEN}}
Nothing particularly interesting, except that if you look closely, you'll notice that I'm using a different authentication token to enable auto-merge:
GH_TOKEN: ${{secrets.GH_TOKEN}}
In most cases, when having GitHub Actions execute API calls, you'd use the
standard GITHUB_TOKEN
provided for authentication with GitHub's APIs from a
GitHub Action1. If you do that however, you'll soon realize that none of your
other actions will be triggered. Take, for instance, this other action that I
have configured to run on pushes to my main
branch:
main.yml
name: Publish Docker image
on:
push:
branches:
- main
jobs:
push_to_registry:
name: Push Docker image to GitHub Packages
runs-on: ubuntu-latest
steps:
- name: Check out the repo
uses: actions/checkout@v2
- name: Docker meta
id: meta
uses: docker/metadata-action@v4
with:
images: |
ghcr.io/wbrawner/twigs
tags: |
type=schedule
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
type=sha
- name: Set up QEMU
uses: docker/setup-qemu-action@v2
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Login to GitHub Container Registry
uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push
uses: docker/build-push-action@v3
with:
context: .
platforms: linux/amd64,linux/arm64
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
This workflow just builds and publishes the docker image for my project on each
push to main
, be it a direct push or as a result of merging a pull request. I
was quite confused as to why this job was triggering when I pushed directly to
main
, and when I manually merged PRs, but not when PRs were automatically
merged by the GitHub bot. Turns out I just needed to slow down a little and read
the manual2:
When you use the repository's
GITHUB_TOKEN
to perform tasks, events triggered by theGITHUB_TOKEN
, with the exception ofworkflow_dispatch
andrepository_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'sGITHUB_TOKEN
, a new workflow will not run even when the repository contains a workflow configured to run whenpush
events occur. For more information, see "Automatic token authentication."
So, if you find yourself in a situation where your GitHub Actions are not being
triggered when you auto-merge the PR (or perform some other interaction with
GitHub's API) from another GitHub Action, the trick is to just create a token
for your own user (or your own bot user with read/write access to the repo) and
use that token instead of the default GITHUB_TOKEN
. Happy coding!