vole
Clone
Read only, no credentials:
https://rodent.software/git/vole.git
Write over SSH with a registered key:
git clone ssh://git@0.0.0.0:2222/vole.git
A free and open-source forge that lives in your Git repo.
Let a job start service containers beside it
c1929d2fceb5e9e65204d5eef907d0781b9a5391 · Keenan Nemetz · 5d ago · parent 1d06b008
docs/runner.md +16−4
| @@ -164,13 +164,22 @@ that build. Prefer rootless Podman, and pin the base image by digest. | |||
| 164 | 164 | ||
| 165 | 165 | ## How a job runs | |
| 166 | 166 | ||
| 167 | One container is created per job and removed afterward. The workflow's steps run | ||
| 168 | inside it, but the runner process stays on the host: the SSH key, the trusted Git | ||
| 169 | cache, and the finish channel are never exposed to the job. Each job gets a fresh | ||
| 167 | One container is created for the job, plus one for each service the job declares; | ||
| 168 | all are removed afterward. The workflow's steps run inside the job container, but | ||
| 169 | the runner process stays on the host: the SSH key, the trusted Git cache, and the | ||
| 170 | finish channel are never exposed to the job. Each job gets a fresh | ||
| 170 | 171 | clone of the runner's saved copy of the repository (see | |
| 171 | 172 | [Saved checkouts](#saved-checkouts)), so a job cannot leave a Git hook or a modified | |
| 172 | 173 | checkout behind for the next one. | |
| 173 | 174 | ||
| 175 | A service is a second container on a private user-defined network created for the | ||
| 176 | attempt. It gets the job's user, capabilities, and resource limits, but no job tree, | ||
| 177 | no cache, and no secrets. Its declared name is the network alias a step connects to. | ||
| 178 | The runner starts services after the image is ready and before the first step, | ||
| 179 | fails the job if one is not running, and adds the end of their output to a failed | ||
| 180 | attempt's log. Services, the job, and the network are removed together; a killed | ||
| 181 | runner finds its leftovers by label on the next start. | ||
| 182 | |||
| 174 | 183 | Container defaults are intentionally closed: | |
| 175 | 184 | ||
| 176 | 185 | - no network unless the job asks for one with `network: bridge`, or the runner was | |
| @@ -256,7 +265,10 @@ decides what the container gets, and the runner applies it: | |||
| 256 | 265 | So a machine with a network is not a machine that hands it to every build. A job | |
| 257 | 266 | that asks for none is isolated on either kind of runner, and a job that asks for | |
| 258 | 267 | bridge waits in the queue for a runner that advertises one instead of running | |
| 259 | without the network it needs. The runner advertises this with every lease, the same | ||
| 268 | without the network it needs. A bridge job that declares services gets a | ||
| 269 | user-defined network for that attempt rather than the runtime's default bridge; the | ||
| 270 | job and its services are its only members, so the service names resolve there and | ||
| 271 | nowhere else. The runner advertises this with every lease, the same | ||
| 260 | 272 | way it advertises `--label`, and the job's request is pinned with the run when it is | |
| 261 | 273 | queued. | |
| 262 | 274 | ||