Commit f9845abbc9

f9845abbc93ead5d74684a56f2e677be71c69587

parent: 6a868d3112

Verified · cmc

cmc <hello@cleberg.net> · 2026-09-09 03:24 UTC

wiki: runners attached to repositories

Ref #184
.gitbay/wiki/Admin.org +22 −13
@@ -329,13 +329,16 @@ startup to point at the current binary path.
329329* CI runner
330330
331331=gitbay-runner= executes builds queued by pushes and merge requests. It
332polls over SSH with a key added by =keys add --scope runner=, which
333reaches only the runner protocol and read-only git (a runner executes
334arbitrary repository code, so the key it holds must not do more), then
335clones, runs the steps, streams the log back and resolves the commit
336status. Run it as a dedicated unprivileged user on a non-admin account.
337=admin user create --key= registers a full-scope key, so the runner key
338is added afterwards through a bootstrap key that is then removed:
332polls over SSH with a key of scope =runner=, which reaches only the
333runner protocol and read-only git (a runner executes arbitrary
334repository code, so the key it holds must not do more). A runner key
335claims builds only for the repositories it is attached to, by =repo
336runner add= from a repository admin or an instance admin; an admin key
337claims any. Users attach their own runners: see the Users page. For an
338instance runner, run it as a dedicated unprivileged user on a non-admin
339account. =admin user create --key= registers a full-scope key, so the
340runner key is added afterwards through a bootstrap key that is then
341removed, and attached to each repository it should build:
339342
340343#+begin_src sh
341344useradd --system --create-home --home-dir /var/lib/gitbay-runner ci-runner
@@ -348,6 +351,10 @@ rm /tmp/ci-bootstrap /tmp/ci-bootstrap.pub
348351gitbay-runner -remote git@127.0.0.1 -workdir /var/lib/gitbay-runner/work
349352#+end_src
350353
354#+begin_src sh
355gitbay repo runner add krz/site < /var/lib/gitbay-runner/.ssh/id_ed25519.pub
356#+end_src
357
351358=-jobs N= runs N builds at once. Claiming is one transaction that
352359selects and updates, and each build works in its own =build-<id>=
353360directory, so workers do not collide; idle polls are staggered across
@@ -391,15 +398,17 @@ gitbay-runner -remote git@gitbay.org -repos krz/site,krz/docs \
391398 -workdir /var/lib/gitbay-runner/work
392399#+end_src
393400
401Add =-untrusted= only with =-isolation podman=.
402
394403gitbay.org's runner is scoped: it builds the forge's own repositories
395404and the isolation canary, nothing else, because it shares the host with
396the forge. A =.gitbay/ci.yml= in another repository there queues builds
397no runner claims. Whether that changes is krz/gitbay#184.
405the forge; any other repository builds on a runner its owner attaches.
398406
399Naming no repositories is the old behaviour and stays the right choice for
400the runner on the server itself. The scoping is what the runner asks for,
401not an ACL the server holds over it: a runner account is admin by
402necessity, so the boundary is you choosing how to start it.
407=-repos= narrows an admin runner; for a runner key the attachments are
408the boundary, held by the server, and =-repos= may only name
409repositories among them. =-untrusted= makes a runner claim merge
410request heads from forks; the bay1 unit sets it because it isolates in
411podman. A runner without it builds trusted commits only.
403412
404413=gitbay dashboard= and =ssh git@<host> admin runners= list every account
405414that has polled as a runner: when it last polled, the =-repos= scope it
.gitbay/wiki/CI.org +6
@@ -20,6 +20,12 @@ Three mechanisms decide what a push does to CI, and they interact:
2020 the build deadline if no stream was ever seen (#179). Its status reads
2121 =build abandoned=.
2222
23Which runner takes a build is the fourth: a build is claimed only by a
24runner attached to its repository (or an instance admin's runner), and
25an untrusted build only by one started with =-untrusted=. A repository
26with no runner attached queues builds nothing claims. See the Users
27page.
28
2329Scheduled jobs run on their cron against the default branch, never on
2430push; a default-branch push registers or updates them. Tag jobs run on
2531a matching tag push and nothing else.
.gitbay/wiki/FAQ.org +8 −6
@@ -17,9 +17,11 @@
1717 email patch flow (revisit only if sourcehut-style demand appears),
1818 federation and Postgres (no need at this scale). Recorded so the
1919 absence reads as a decision, not an oversight.
20- Does CI run for my repository on gitbay.org? :: Not yet. The runner
21 there is scoped to the forge's own repositories and its isolation
22 canary, since it shares the host with the forge. A =.gitbay/ci.yml=
23 in your repository queues builds nothing claims. krz/gitbay#184 is
24 where that gets decided. A self-hosted instance runs the same runner
25 for whichever repositories its operator names.
20- Does CI run for my repository on gitbay.org? :: On a runner you
21 attach. The instance's own runner builds the forge's repositories and
22 its isolation canary, since it shares the host with the forge.
23 Install =gitbay-runner= on a machine of yours, run =gitbay-runner
24 init=, and attach the key it prints with =repo runner add= or on the
25 repository's settings page; see the Users page. A self-hosted
26 instance can do the same, or run one runner for whichever
27 repositories its operator attaches it to.
.gitbay/wiki/Parity.org +1
@@ -162,6 +162,7 @@ always markdown.
162162| access grants | yes | no | yes |
163163| effective access | yes | no | yes |
164164| webhooks | yes | no | yes |
165| runners attach, list, detach| yes | yes | no |
165166| import from a remote | yes | no | yes |
166167| topics, website | yes | yes | yes |
167168| visibility | yes | yes | yes |
.gitbay/wiki/Threat-Model.org +11 −7
@@ -117,13 +117,17 @@ JavaScript, so =script-src 'none'= costs nothing.
117117gitbayd never does: it reads =.gitbay/ci.yml= and queues a build, and a
118118runner, polling over SSH, clones the commit and runs its steps.
119119
120- *What the runner holds.* A key added with =keys add --scope runner=,
121 which the dispatcher confines to =runner next=, =runner log= and
122 =runner done= and to read-only git. A step that reads the key off the
123 disk gets exactly that: it cannot administer the instance, push, or
124 read a repository the runner's account cannot. An admin key still
125 works for the runner protocol so an operator can rotate at their own
126 pace; a runner host should not hold one.
120- *What the runner holds.* A key of scope =runner=, which the dispatcher
121 confines to =runner next=, =runner log= and =runner done= and to
122 read-only git, and which claims, logs and finishes builds only for
123 the repositories it is attached to (=repo runner add=). A step that
124 reads the key off the disk gets exactly that: it cannot administer
125 the instance, push, read a repository the runner's account cannot, or
126 touch another repository's builds. An admin key still works for the
127 runner protocol so an operator can rotate at their own pace; a runner
128 host should not hold one. Untrusted builds are skipped unless the
129 runner asks with =-untrusted=, so a runner on a user's machine never
130 executes a stranger's branch by default.
127131- *What a build sees.* The commit, the =GITBAY_*= variables and the
128132 repository's secrets — unless the head came from another repository.
129133 A merge request from a fork is built in the target as untrusted, with
.gitbay/wiki/Users.org +34
@@ -489,6 +489,40 @@ log says who cancelled it. Both need write access.
489489What each push shape queues, with dedupe, path filters, schedules and
490490the reaper together, is one table on [[CI][CI]].
491491
492** Your own runner
493
494Builds run on runners attached to the repository. An instance need not
495offer any: install =gitbay-runner= on a machine of yours and attach it.
496
497#+begin_src sh
498brew install krz/tap/gitbay-runner # or a binary from the release
499gitbay-runner init -remote git@gitbay.org
500#+end_src
501
502=init= generates a key under =~/.config/gitbay-runner/=, writes
503=config.toml= beside it, and prints the public key with the command to
504attach it:
505
506#+begin_src sh
507gitbay repo runner add owner/name < ~/.config/gitbay-runner/id_ed25519.pub
508#+end_src
509
510or paste the key under Runners on the repository's settings page. Then
511=brew services start krz/tap/gitbay-runner=, or run =gitbay-runner= with
512no arguments; it reads the config file, and any flag overrides it.
513
514What it builds: every build for the repositories it is attached to,
515with the repository's secrets, and nothing else. Merge requests from
516forks are untrusted and wait unless the runner runs with =-untrusted=,
517which is only sensible with =-isolation podman -image <ref>= (see
518[[Admin][Admin]]). Attach one runner to several repositories by repeating
519=repo runner add=; run several runners on one account by running =init=
520on each machine. =repo runner list= shows each attached key, when it
521last polled and the build it holds; =repo runner remove <fingerprint>=
522detaches one (the key stays on your account; =keys remove= drops it).
523A runner key reaches only the runner protocol and read-only git, so a
524build step that reads it off disk cannot administer your account.
525
492526* Large files (LFS)
493527
494528Standard Git LFS works over both transports with no setup beyond the