ADR 0034 Run the workflows on the owner s self hosted runner - AnnabiGihed/RaidManager GitHub Wiki
Generated from
docs/adr/0034-run-the-workflows-on-a-self-hosted-runner.md. Edit that file in the repository: changes made in the wiki are overwritten.
- Status: Accepted
- Date: 2026-10-08
- Deciders: Gihed Annabi
Context
Every GitHub Actions job of the repository ran on ubuntu-latest, a runner GitHub hosts and wipes after each job. The
owner decided to switch every workflow to a self-hosted runner on their own Linux computer, labeled self-hosted,
linux and pc-personal (owner request on #561).
The repository is public. GitHub advises using self-hosted runners only with private repositories, because a pull request from a fork can run its own code on the runner: here, the owner's computer. On 2026-10-08 the repository asked for approval only before a first-time contributor's workflows ran, so anyone with one merged pull request could start a job on that machine without approval.
The workflows rely on tools GitHub's images come with: Git, the GitHub CLI, jq, curl, SSH, gzip and Docker. The
PostgreSQL tests start containers through Testcontainers, the dev deployment builds images and sends them with
docker save, and the Lua job compiles Lua and luarocks from source.
Decision
-
Every job of every workflow in
.github/workflows/usesruns-on: [self-hosted, linux, pc-personal]. -
No fork pull request reaches the runner (owner decision on #561, the recommended option). Each job a
pull_requestevent can start carriesif: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository(thesonarjob adds the same test to its own condition). Thepull_request_target,workflow_run,issues,schedule, push and manual runs executemain's own workflow code, never a pull request's, and thereviewanddependency-taskjobs already skip forks. -
The owner sets "Require approval for all external contributors" under the repository's Settings, Actions, General, so a fork's workflows wait for approval even if a guard is missed.
-
The docs check enforces these rules.
scripts/workflow_runners.py, run byvalidate_docs.py, fails on a job without these labels, on a job reachable from a fork pull request without the guard, and on a job that callspythonorpython3withoutactions/setup-python(#564). -
Jobs install what they can themselves (owner decision on #561): the local action
.github/actions/setup-toolsputs the GitHub CLI andjq, pinned and checked against their SHA-256, in the job's temporary folder when the image lacks them or has older versions, and every job that calls them runs it after checkout. An olderghfrom the image broke the review merge of #566 (#567). Python, .NET and Node come from thesetup-*actions: the image has nopythoncommand, and the dev deployment's first run on the runners failed on it (#564). -
The runner image provides what can't be installed without
sudo: Git, curl,gzipandunzip; a C compiler withmakefor theluajob; Docker usable by the job for the PostgreSQL tests and the deployment; and an SSH client for the deployment. -
No job uses
sudo: the runners refuse it ("no new privileges"). Theluajob therefore builds Lua 5.1.5 itself, checked against its SHA-256, instead of withleafo/gh-actions-lua, which installs thereadlineheaders withsudo apt-get.
Consequences
- Jobs run only while the owner's computer is on and can start runners. A pull request's checks, the review merge, the dev deployment and the docs publication wait for it.
- A pull request from a fork gets no checks: its guarded jobs are skipped, and GitHub counts a skipped required check as passed. Such a pull request is never merged as it is. The owner pushes the change to a branch of this repository, whose pull request runs every check.
- The runners are ephemeral (the owner, 2026-10-08): each job gets a new runner that registers itself and is removed
after the job, so no workspace, tool cache or package cache carries over. The
setup-*actions and the restores download again in every job, and the image must provide the tools listed above. - The deploy SSH keys and the environment secrets (ADR-0028) are now handled on the owner's computer during the deploy job instead of on a disposable GitHub machine.
- The Windows packaging job ADR-0033 proposes needs a Windows runner, which this runner isn't; that ADR's implementation decides how it runs.
- GitHub-hosted runner minutes are no longer used.
Alternatives considered
- Keep GitHub-hosted runners: no change on the owner's machine and no exposure, but not what the owner chose.
- Self-hosted runner with the approval setting only: fewer workflow changes, but a fork's code runs on the computer as soon as a run is approved, and one wrong approval is enough.
- Make the repository private: removes the fork risk, but GitHub Pages and SonarCloud's free plan need a public
repository; the documentation site and the
sonargate would need replacing.