feat(runner): status, remove, and repoint — the runner lifecycle verbs #11
No reviewers
Labels
No labels
attention
blocked
blocker:ci-red
blocker:conflict
blocker:drill-pending
blocker:unrequested
bug
claimed
documentation
enhancement
epic
merge-next
needs-ruling
needs-triage
offsite
post-merge
ready
release
scope:bootstrap
scope:coolify
scope:db
scope:docs
scope:drill
scope:installer
scope:labels
scope:platform
scope:runner
scope:users
stale
state:addressing
state:bots-reviewing
state:building
state:needs-human
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: heavy-duty/rig#11
Loading…
Reference in a new issue
No description provided.
Delete branch "feat/runner-lifecycle"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Why
rig runner installis convergent by skipping — it sees a registered runner and leaves it alone. rig could therefore create a runner and never move or destroy one. Re-pointing a box at a different repository meant hand-rolledconfig.sh/svc.shincantations against an install layout only rig knew about (~github-runner/actions-runner), which is exactly the class of box-shaped, on-box bash that rig exists to absorb.This came out of a real act: moving a CI box's runner from a fork to the upstream repo, where the runner is the deploy path to a tailnet-only control plane. That move should be one command, not a runbook.
What
rig runner status— repo, runner name, labels, install dir, systemd unit + state. Read-only: no token, no network call, exits 1 when nothing is installed.rig runner remove [--local]— service down, then deregister.--localwipes the box without contacting GitHub (no token), leaving a stale offline entry to delete by hand.rig runner repoint --repo <owner/repo>— deregister + re-register in one act, keeping the runner's name and reusing the binary already on the box. Convergent: repointing to the repo it's already on is a no-op that never asks for a token.Three things the source forced
UnconfigureAsyncthrows"Uninstall service first"on Linux while the service is configured — andconfig.sh remove --localskips that check entirely (Runner.cs:171deletes local config and exits), which would strand a running service pointed at config that no longer exists. Sosvc.sh stop && svc.sh uninstallruns first regardless of path.repointcollects both tokens up front. They come from different repos and different endpoints (remove-tokenfor the old,registration-tokenfor the new). A token you turn out not to have must fail while the runner is still registered and working — not halfway through the move. If re-registration fails anyway, rig says so plainly and prints the exactrunner installline that finishes the job.runs-onmatches — so a silent change there is a workflow that quietly stops finding its runner.installnow records what it registered with (.rig-labels, box-local metadata, never a credential) sorepointandstatuscan read it back. A runner installed before that has nothing to read:repointfalls back to theci-runnerdefault and warns loudly before it touches anything, while ctrl-c is still useful.Verification
shellcheck install.sh bin/rig commands/*.sh test/cli.sh— clean.bash test/cli.sh— 59 passed, 0 failed (+22 new cases: help/usage, arg validation, bad repo slug,--user rootrefusal, non-root refusals incl. the token-free--localpath).config.sh/svc.sh, asserting: convergent no-op on same-repo; correct ordering (svc stop → uninstall → config remove → configure → svc install → start); the runner's name preserved across the move; no re-download;.rig-labelswritten; andstatusreading back the new repo. The JSON parse correctly picksgitHubUrlover the adjacentserverUrl.🤖 Generated with Claude Code