Automate Maintainer Tasks with GitHub Actions
Severin Neumann (OpenTelemetry)
Being a maintainer is fun …
Image by Arne Hendriks (CC BY 2.0)
“Maintenance involves functional checks, servicing, repairing, or replacing necessary devices, equipment, machinery, building infrastructure, and supporting utilities"
… until you do the same thing
Image by Jackie (CC BY 2.0)
… and again,
and again,
and again
and again
and again
and again
and again
and
again
and
again…
again …
Image by xkcd.com (CC BY-NC 2.5)
We all know the answer:
Automation!
Automation Without Hurting Yourself
1. Reuse what is out there | 2. script first, workflow later |
3. Learn the basics (and then use a LLM…) | 4. Common Pitfalls x |
too much
Reuse what is out there
Before you write any automation on your own, make sure you use what others have created before you:
CODEOWNERS
The easiest way to get PRs assigned to the right person or team*:
* Limitation: Groups and users need write permissions on the repo!
* @your-project/project-owners
**/docs @your-project/project-docs-owners
*.cpp @username
Dependabot
Another automation you can enable without writing any scripts or workflows!
version: 2
updates:
- package-ecosystem: github-actions
directory: /
schedule:
interval: weekly
GitHub’s GitHub Actions
Common actions to add to your repo:
name: 'Label PR'
on:
pull_request_target:
types: [opened,reopened]
jobs:
labeler:
name: 'Add component labels'
permissions: [...]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/labeler@v5
with:
configuration-path: '.github/component-label-map.yml'
Docker’s GitHub Actions
All you need to build containers!
steps:
- name: Docker meta
uses: docker/metadata-action@<hash>
tags: “type=semver,pattern={{ version }}”
- name: Log into GitHub Container Registry
uses: docker/login-action@<hash>
with:
registry: ghcr.io
- name: Set up QEMU
uses: docker/setup-qemu-action@<...>
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@<...>
- name: Build and push images
uses: docker/build-push-action@<...>
with: …
OpenSSF Scorecard’s GitHub Actions
Checks for issues with software security for each commit! Easy setup:
github.com/org/repo/actions/new?category=security&query=scorecard
After running the workflow go to
securityscorecards.dev/viewer/?uri=github.com%2Forg%2Frepo
OpenSSF Scorecard’s GitHub Actions
… and more
GitHub has a marketplace for Actions (and Apps), so always check if there is something reusable.
But as with any other dependency, pay attention:
(March, 2024) Multiple tags in this action are compromised
script first, workflow later
Image by chriscom (CC BY-SA 2.0)
script first, workflow later
If there is no “ready to use” workflow by a third party, go half the way from manual to semi-automatic:
Learn the basics
If you have a script that you want to run based on a trigger wrapping it into a GitHub action is (relatively) easy
name: Run my script
# what triggers the workflow?
on:
# the following allows you to manually trigger the workflow
workflow_dispatch:
schedule:
# hourly at minute 10
- cron: 10 * * * *
# a list of (parallel) jobs that this workflow will execute
jobs:
my-script:
name: run-my-script
# the name of the runner used, “ubuntu-*” is a good starting point
runs-on: ubuntu-24.04
# The sequential steps the script will take
steps:
# Checkout the repo
- uses: actions/checkout@<hash> # v4.2.x
# Run the script
- run: ./scripts/my-script.sh
… and then use an LLM
Writing and testing GitHub actions can be painful, but gladly most LLMs do a decent job in creating you something you can start from, e.g.
“I need a github action that writes a thank you note below a merged PR and shares a link to a survey with the contributor. Make sure that you follow security best practices for github actions, and the the gh tool is used where applicable”
name: Thank Contributor
on:
pull_request_target:
types:
- closed
permissions:
pull-requests: write # Required to comment on PRs
contents: read # Minimal required permission
jobs:
thank_contributor:
if: github.event.pull_request.merged == true
runs-on: ubuntu-latest
steps:
- name: Comment on PR
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SURVEY_URL: "https://example.com/contributor-survey"
run: |
gh pr comment ${{ github.event.pull_request.number }} \
--body "🎉 Thank you for your contribution! We appreciate your effort. 🙌
We'd love to hear your feedback—please take a moment to fill out our survey: [$SURVEY_URL]($SURVEY_URL)"
common pitfalls
Image by Erich Ferdinand (CC BY 2.0)
common pitfalls
common pitfalls
Things that can go wrong:
Runs locally but not on the GH runner
Common problems:
How to fix them:
Runs locally but not on the GH runner
Runs locally but not on the GH runner
Permission & token issues
This type of issue is the hardest to solve, because often it can
not be reproduced
What you can do:
Set your permissions for GITHUB_TOKEN
name: Thank Contributor
on:
pull_request_target:
types:
- closed
permissions:
issues: read
jobs:
thank_contributor:
permissions:
contents: write
pull-requests: write
You can set global permissions, and local permissions per job.
Token Types for actions
Thank you