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/workflows.md +42−1
| @@ -309,6 +309,46 @@ push time. Everything else is the workflow's. This is how a job opts in to the | |||
| 309 | 309 | cache the runner mounts at `/cache`, and how a job using a registry image gets it | |
| 310 | 310 | without an image definition. | |
| 311 | 311 | ||
| 312 | ## Services | ||
| 313 | |||
| 314 | A job can start a database, a queue, or another server beside it and reach it by | ||
| 315 | name. The job has to ask for a network too, because the service is reached over it: | ||
| 316 | |||
| 317 | ```yaml | ||
| 318 | jobs: | ||
| 319 | test: | ||
| 320 | image: golang:1.27-bookworm | ||
| 321 | network: bridge | ||
| 322 | services: | ||
| 323 | db: | ||
| 324 | image: postgres:17 | ||
| 325 | env: | ||
| 326 | POSTGRES_PASSWORD: test | ||
| 327 | PGDATA: /tmp/pgdata | ||
| 328 | steps: | ||
| 329 | - run: | | ||
| 330 | DATABASE_URL=postgres://postgres:test@db:5432/postgres go test ./... | ||
| 331 | ``` | ||
| 332 | |||
| 333 | The service's name is its hostname on a private network the runner creates for the | ||
| 334 | attempt. The job and its services are the only members, so `db:5432` is the address | ||
| 335 | a step uses. The service is a container, not a job: it has no steps, no checkout, | ||
| 336 | no secrets, and no files from the runner. At most three may run beside one job. | ||
| 337 | |||
| 338 | The runner starts them after the image is ready and before the first step. A service | ||
| 339 | that exits before the steps start fails the job. There is no health check, so a step | ||
| 340 | that needs a server to accept connections waits for it, as a postgres test waits with | ||
| 341 | `pg_isready`. When the job fails, times out, or is canceled, the end of each | ||
| 342 | service's output is added to the log under `=== service db ===`; a passing run drops | ||
| 343 | it. The job, the services, and the network are removed together, and a killed | ||
| 344 | runner's leftovers are cleaned up by its next start. | ||
| 345 | |||
| 346 | A service image must run as the job's uid, and `/tmp` is writable. The postgres | ||
| 347 | example points `PGDATA` at `/tmp` for that reason. A database image that insists on | ||
| 348 | starting as root does not work here; use one that can run unprivileged or publish a | ||
| 349 | custom image. The runner's memory, CPU, and PID flags apply to each container, so a | ||
| 350 | job with services can use more than one container's share. | ||
| 351 | |||
| 312 | 352 | ## Secrets | |
| 313 | 353 | ||
| 314 | 354 | A repository can keep the values its jobs need out of its code: a deploy key, a | |
| @@ -431,7 +471,8 @@ variables: the image's `env:` (or the step) decides whether `/cache` is used. Se | |||
| 431 | 471 | ||
| 432 | 472 | A local run still ignores triggers and `runs-on`, publishes no artifacts, | |
| 433 | 473 | and deploys no site. It does apply the job's `network:` request, so a `bridge` job | |
| 434 | needs `--container-network bridge` here too (the default), and it spends the job's | ||
| 474 | needs `--container-network bridge` here too (the default), and it starts the job's | ||
| 475 | services on the same kind of private network a runner would. It spends the job's | ||
| 435 | 476 | `timeout:` the way a runner does. It sets `CI=true` and `VOLE_CI=1`, gives each step | |
| 436 | 477 | whatever the job's budget and its own timeout leave it, and reads no standard input. | |
| 437 | 478 | It reads the secrets its jobs declare from the instance the checkout's remote names, | |