ref:54545c135e3d6eedc3c13d240fa08dea27f86d42

feat: integrate CI runner into single binary

Ports the full anvil-runner functionality from Elixir/Burrito into Rust: Runner execution: - anvil runner configure — register with server via registration token - anvil runner start — polling loop with exponential backoff (5s-30s) - anvil runner unconfigure — deregister and remove config - anvil runner status — show runner config Job execution: - Docker container execution with workspace mounting - Bare execution fallback (host shell) - Streaming log reporter with buffering (100 lines) and 1s flush timer - Log upload retry (2 retries, 500ms backoff) - Job timeout support (default 600s) Infrastructure: - Service sidecar lifecycle (Docker network, health checks, cleanup) - Health checks for postgres, redis, mysql, mongo - Well-known port detection for 8 service types - Stateful workspaces (no git clean — preserves build caches) - Heartbeat loop (30s interval) - Graceful shutdown with 30s grace period (ctrl+c) - --once and --ephemeral modes - Workspace cleanup policies (always/never/on-success) OS service integration: - macOS: launchd plist (~/Library/LaunchAgents/) - Linux: systemd unit (user or system) - install/uninstall/start/stop/status commands Admin commands (PAT auth) preserved: list/view/update/remove/token Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
SHA: 54545c135e3d6eedc3c13d240fa08dea27f86d42
Author: Cole Christensen <cole.christensen@macmillan.com>
Date: 2026-03-11 02:26
Parents: c62e1fb
13 files changed +1728 -12
Type
Cargo.lock +69 −0
@@ -70,6 +70,9 @@
"colored",
"dialoguer",
"dirs",
"futures",
"hostname",
"libc",
"reqwest",
"serde",
"serde_json",
@@ -335,6 +338,21 @@
checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf"
dependencies = [
"percent-encoding",
]
[[package]]
name = "futures"
version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b147ee9d1f6d097cef9ce628cd2ee62288d963e16fb287bd9286455b241382d"
dependencies = [
"futures-channel",
"futures-core",
"futures-executor",
"futures-io",
"futures-sink",
"futures-task",
"futures-util",
]
[[package]]
@@ -344,6 +362,7 @@
checksum = "07bbe89c50d7a535e539b8c17bc0b49bdb77747034daa8087407d655f3f7cc1d"
dependencies = [
"futures-core",
"futures-sink",
]
[[package]]
@@ -353,6 +372,40 @@
checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d"
[[package]]
name = "futures-executor"
version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf29c38818342a3b26b5b923639e7b1f4a61fc5e76102d4b1981c6dc7a7579d"
dependencies = [
"futures-core",
"futures-task",
"futures-util",
]
[[package]]
name = "futures-io"
version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cecba35d7ad927e23624b22ad55235f2239cfa44fd10428eecbeba6d6a717718"
[[package]]
name = "futures-macro"
version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.117",
]
[[package]]
name = "futures-sink"
version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c39754e157331b013978ec91992bde1ac089843443c49cbc7f46150b0fad0893"
[[package]]
name = "futures-task"
version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -364,8 +417,13 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6"
dependencies = [
"futures-channel",
"futures-core",
"futures-io",
"futures-macro",
"futures-sink",
"futures-task",
"memchr",
"pin-project-lite",
"slab",
]
@@ -436,6 +494,17 @@
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
[[package]]
name = "hostname"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "617aaa3557aef3810a6369d0a99fac8a080891b68bd9f9812a1eeda0c0730cbd"
dependencies = [
"cfg-if",
"libc",
"windows-link",
]
[[package]]
name = "http"
Cargo.toml +4 −1
@@ -2,7 +2,7 @@
name = "anvil-cli"
version = "0.1.0"
edition = "2021"
description = "CLI for Anvil — a self-hosted code forge"
description = "CLI and CI runner for Anvil — a self-hosted code forge"
license = "MIT"
[[bin]]
@@ -22,3 +22,6 @@
tabled = "0.17"
url = "2"
thiserror = "2"
hostname = "0.4"
libc = "0.2"
futures = "0.3"