Sync develop → main for v1.4.0 chart release#157
Conversation
feat(#154): auto-refresh jobs-manager image on Docker Hub publish
…tion (#156) Caught in dev-cluster smoke test on tb-client-dev-templates. `kubectl get -o jsonpath="{.metadata.annotations['key.with.dots']}"` returns empty for keys containing `.` or `/` on kubectl-go 1.30.x — verified directly: `kubectl get ... -o jsonpath='{.metadata.annotations}'` showed `tracebloc.io/last-refreshed-jobs-manager-digest:sha256:f913...` present and persisted, but the script's bracket-notation read returned empty. Effect: every tick saw `recorded=<unset>` and re-entered the first-observation path, re-annotating the deployment with the same digest on every run. No spurious restarts (first-observation skips restart), but the script was incapable of ever transitioning to the "unchanged; no-op" path, and a real image update would have been indistinguishable from first observation. Fix: read via `kubectl get -o json | jq -r --arg k "$_key" '.metadata.annotations[$k] // empty'`. alpine/k8s ships jq, so this adds no new dependency. The dot-escape jsonpath form (`.tracebloc\.io/...`) also works but is fragile against future kubectl version changes; jq's behaviour is locked. Regression tests: * The script must include `jq -r --arg k` (positive match). * The script must NOT include `annotations['$_key']` bracket-notation jsonpath (negative match — the regression vector itself). Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Brings the image-refresh CronJob feature to main for release: - #155: feat(#154) auto-refresh jobs-manager image on Docker Hub publish - #156: fix(#154) read annotations via jq (kubectl jsonpath bracket notation returns empty for keys containing dots/slashes) Verified end-to-end on the tb-client-dev-templates EKS dev cluster: fresh upgrade installs the new resources cleanly, first-tick records both annotations without restart, second tick is a no-op, and a forced digest mismatch triggers the expected rollout-restart-then-annotate sequence. Rollout history bumps as expected. Closes #154.
|
👋 Heads-up — Code review queue is at 17 / 8 Above the WIP limit. The team convention is to review existing PRs before opening new work. Open PRs currently in Code review (oldest first):
Pull from review before opening new work. (This is a nudge from the kanban WIP check, not a block.) |
|
Adding The gate checks each referenced PR (#155, #156) AND the current PR (#157). Both #155 and #156 are correctly at This is the gate's own documented emergency override — audit-logged via the |
Summary
Brings the image-refresh CronJob feature to
mainahead of cutting thev1.4.0release tag.What's included
feat(#154): auto-refresh jobs-manager image on Docker Hub publishfix(#154): read annotations via jq, not kubectl jsonpath bracket notationTogether they deliver the closure for #154: existing customers' jobs-manager (and pods-monitor) deployments now auto-refresh on Docker Hub tag publishes with no manual
kubectl rollout restartneeded. Source of truth is atracebloc.io/last-refreshed-<image>-digestannotation on the deployment, comparing against the registry's HEAD digest each tick.Dev verification
Smoke-tested end-to-end on
tb-client-dev-templatesEKS:helm upgradefrom 1.3.5 → 1.4.0 with--reset-then-reuse-valuesdigest unchanged; no-op, no annotate, no rolloutdigest changed → restart needed, rollout, then re-annotate to current digestAfter merging
Cut
v1.4.0release tag frommain— that fires release-helm-chart.yaml which publishesclient-1.4.0.tgzto gh-pages. Existing customers'autoUpgradeCronJobs pick it up at the next:23tick.Closes #154
🤖 Generated with Claude Code
Note
Medium Risk
The CronJob can restart the jobs-manager deployment and holds patch RBAC on it; blast radius is one deployment in one namespace, but unintended restarts or registry/API failures could cause brief outages.
Overview
Releases the Helm chart at v1.4.0 and adds an image-refresh path so
jobs-manager(andpods-monitorvia the same deployment) can pick up new Docker Hub images under the floatingCLIENT_ENVtag without manualkubectl rollout restart.A scheduled CronJob runs a shell script that HEADs Docker Hub for manifest digests, compares them to
tracebloc.io/last-refreshed-*-digestannotations on the deployment (not podimageID), records digests on first run without restarting, and on change runskubectl rollout restartthenrollout statusbefore updating annotations. Rendering is gated bytracebloc.imageRefreshEnabled(off when disabled or both images are digest-pinned); namespace-scoped RBAC limits the job to patch/watch that deployment. NewimageRefreshvalues and schema defaults, plus helm-unittest coverage for script/RBAC contracts and upgrade safety whenimageRefreshis missing.Reviewed by Cursor Bugbot for commit 15e78d9. Bugbot is set up for automated code reviews on this repo. Configure here.