homelab: v0.4.0 — ci/deploy verbs (watch what you trigger)
Adds the verb-group that kills the single biggest reasoning sink in agent sessions — watching a build/deploy to completion (proven the session that built it: hours hand-rolling Woodpecker polling + DB-schema spelunking for one CI incident). - ci status/watch: Woodpecker REST API (version-stable, not its DB schema), reached via the internal Traefik LB (dial 10.0.20.203, SNI=ci.viktorbarzin.me so the cert verifies — the Go form of the house `curl --resolve` pattern), token from WOODPECKER_TOKEN/Vault, repo id resolved from the cwd remote, with retries that ride Woodpecker's intermittent empty responses. watch matches the HEAD/given commit (avoids the post-push race) and exits non-zero on failure. - deploy wait: image-sha match THEN rollout status (rollout status alone returns success on the old ReplicaSet); kubectl-based. - work land now auto-watches CI to green on the landed commit (--no-ci-watch to skip), closing the v0.1 gap. - ci logs deferred to v0.4.1 (Woodpecker detail/log endpoints were the least reliable; status/watch use the working list endpoint). Live-verified ci status/watch against the live API. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
787ce4edfa
commit
9189560ac3
10 changed files with 444 additions and 7 deletions
51
cli/cmd_deploy.go
Normal file
51
cli/cmd_deploy.go
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
func deployCommands() []Command {
|
||||
return []Command{
|
||||
{Path: []string{"deploy", "wait"}, Tier: TierRead,
|
||||
Summary: "wait for <ns>/<deploy> to roll out the current (or --sha) image: deploy wait <ns>/<deploy> [--sha SHA]", Run: deployWait},
|
||||
}
|
||||
}
|
||||
|
||||
// deployWait closes the "did the NEW code land" gap: rollout status alone returns
|
||||
// success on the OLD ReplicaSet, so we first wait for the deployment image to
|
||||
// reference the expected sha, THEN block on rollout status.
|
||||
func deployWait(args []string) error {
|
||||
target, _ := firstPositional(args)
|
||||
if target == "" || !strings.Contains(target, "/") {
|
||||
return fmt.Errorf("usage: homelab deploy wait <ns>/<deploy> [--sha SHA] [--timeout 10m]")
|
||||
}
|
||||
parts := strings.SplitN(target, "/", 2)
|
||||
ns, deploy := parts[0], parts[1]
|
||||
|
||||
sha := flagValue(args, "--sha")
|
||||
if sha == "" {
|
||||
sha = short(currentHEAD())
|
||||
}
|
||||
deadline := time.Now().Add(10 * time.Minute)
|
||||
|
||||
if sha != "" {
|
||||
fmt.Fprintf(os.Stderr, "homelab: waiting for %s/%s image to match %s...\n", ns, deploy, sha)
|
||||
matched := false
|
||||
for time.Now().Before(deadline) {
|
||||
img, _ := kubectlCapture(ns, "get", "deploy", deploy, "-o", "jsonpath={.spec.template.spec.containers[*].image}")
|
||||
if strings.Contains(img, sha) {
|
||||
matched = true
|
||||
break
|
||||
}
|
||||
time.Sleep(10 * time.Second)
|
||||
}
|
||||
if !matched {
|
||||
return fmt.Errorf("timed out: %s/%s image never matched %q", ns, deploy, sha)
|
||||
}
|
||||
}
|
||||
fmt.Fprintf(os.Stderr, "homelab: rollout status %s/%s...\n", ns, deploy)
|
||||
return kubectlStream(ns, "rollout", "status", "deploy/"+deploy, "--timeout=180s")
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue