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.
Add packaging, a CI workflow, and containerised local runs
3b39a84c913cabe15bfa6a60dd176ff2dd28d241 · Keenan Nemetz · 14d ago · parent 30a72490
Add packaging, a CI workflow, and containerised local runs A v* tag now builds a .deb and a .rpm for amd64 and arm64 with nfpm and attaches them, with checksums, to the release. The package ships the systemd unit, a config at /etc/vole/vole.toml, and a postinstall that creates the service account and prepares the instance that config names; `vole admin init --config` is what makes that possible, and the binary's version is stamped from the tag instead of the source tree. scripts/ci.sh becomes .vole/workflows/ci.yaml, so `vole workflow run ci` executes exactly what a push runs, and the Markdown link check moves to scripts/check-links.py. Local runs now always execute in the job image and share ci/container with the runner; --no-container is gone, because a run in a different environment proves nothing about CI. The runner mounts a per-repository namespace at /cache and sets no variable for it: a job opts in through its image's env or the new job-level env, which is pinned with the queue and delivered with the lease. Whole namespaces are evicted least-recently-written first so a module cache is never half-deleted, and contributor branches get their own namespace so an untrusted tip cannot seed the cache a protected branch builds into. Running the suite in that container found four bugs worth naming: /tmp was mounted noexec, which broke `go test` and `go run`; the read-only root is gone, because images make toolchain directories world-writable deliberately and the mount set is what protects the host; OpenSSH needs a passwd entry for the job's uid; and a lost metadata push reported as "cannot lock ref" was not classified as a race, so concurrent CLI writes gave up on the first collision. That retry now backs off exponentially with jitter.
docs/cli.md +9−2
| @@ -28,7 +28,7 @@ end option parsing. Options may appear before or after arguments. `vole help | |||
| 28 | 28 | ## Instance | |
| 29 | 29 | ||
| 30 | 30 | ```sh | |
| 31 | vole admin init [--dir <path>] | ||
| 31 | vole admin init [--dir <path> | --config <path>] | ||
| 32 | 32 | vole serve [--config <path>] [--log debug] | |
| 33 | 33 | vole version | |
| 34 | 34 | ``` | |
| @@ -179,12 +179,19 @@ vole runner --remote <ssh-url> [--once] [--dir <path>] [--repos <name>]... [--la | |||
| 179 | 179 | [--container-runtime <name>] [--container-network none|bridge] | |
| 180 | 180 | [--container-pull missing|always|never] [--container-user <uid:gid>] [--container-userns <mode>] | |
| 181 | 181 | [--container-memory <size>] [--container-cpus <n>] [--container-pids <n>] | |
| 182 | [--cache-size <size>] [--no-cache] | ||
| 182 | 183 | vole workflow check [--dir <path>] | |
| 183 | 184 | vole workflow list [--dir <path>] | |
| 184 | 185 | vole workflow run [--dir <path>] [<workflow>...] [--job <id>]... | |
| 186 | [--container-runtime <name>] | ||
| 187 | [--container-network none|bridge] [--container-pull missing|always|never] | ||
| 188 | [--container-user <uid:gid>] [--container-userns <mode>] | ||
| 189 | [--cache-size <size>] [--no-cache] | ||
| 185 | 190 | ``` | |
| 186 | 191 | ||
| 187 | `workflow run` executes steps in the working tree, with no server or runner. See | ||
| 192 | `workflow run` executes steps in the working tree, in the job's image, with no | ||
| 193 | server or runner. It needs a container runtime; there is no host mode. Both it and | ||
| 194 | `vole runner` reuse a job cache (see [Runners § Caching](runner.md#caching)). See | ||
| 188 | 195 | [Workflows § Check and run a workflow locally](workflows.md#check-and-run-a-workflow-locally). | |
| 189 | 196 | ||
| 190 | 197 | ## Internal | |