Add thv upgrade check and list --check-upgrades#5409
Conversation
CLI and API users have no way to discover when a newer version of a registry-sourced MCP server is available; only Studio implements drift detection, in its frontend. Introduce a backend package that all clients can consume. Add pkg/workloads/upgrade with a Checker that compares a running workload's image tag against its registry entry (semver-aware, with a string fallback) and reports environment-variable and configuration (transport / permission-profile / network-isolation) drift. Comparison degrades safely to "unknown" for :latest, digest refs, repository changes, and non-registry-sourced workloads, so only a strictly-newer tag on the same repository yields "upgrade-available". This is the read-only detection core (RFC THV-0068, phase A); the apply path, API endpoints, and CLI follow in later changes. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
0224c57 to
4574212
Compare
2af4157 to
53115aa
Compare
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #5409 +/- ##
==========================================
+ Coverage 68.76% 68.78% +0.01%
==========================================
Files 634 634
Lines 64183 64183
==========================================
+ Hits 44136 44147 +11
+ Misses 16778 16770 -8
+ Partials 3269 3266 -3 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
jhrozek
left a comment
There was a problem hiding this comment.
A few notes from reviewing the CLI surface. Nothing blocking - the change is clean and follows the existing command patterns well. Left one usability point and two minor maintainability/hardening suggestions inline.
4574212 to
6faa7be
Compare
53115aa to
a6b9a1d
Compare
- Lowercase an uppercase "V" tag prefix so semver comparison works; "V1.2.0" vs "V1.3.0" no longer falls through to undecidable and hides a real upgrade. - Drop the raw provider error from CheckResult.Reason (it is serialized into the API response and can leak internal addressing); log it at DEBUG and return a fixed string. Same for the CheckAll path. - Add a defensive default to the comparison switch so an unexpected value yields StatusUnknown rather than the least-safe StatusUpToDate. - Stop reporting network-isolation drift: the registry has no network-isolation field, so it fired for every isolated workload regardless of the candidate version. Remove the ConfigDrift field and the now-unused BoolChange type. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
CLI, Studio, and automation need a single backend source of truth for
upgrade availability instead of each client reimplementing registry
drift detection. Expose the Phase A checker over the existing workloads
API.
Add GET /api/v1beta/workloads/upgrade-check (batch) and
GET /api/v1beta/workloads/{name}/upgrade-check (single). The batch
handler reuses the exact group/all authorization scoping of the list
endpoint and intersects it with the enumerated run configs, so it can
never report a workload outside the caller's scope. Responses carry only
non-sensitive CheckResult metadata; secret env-var defaults are cleared.
Both routes are read-only and skip image pulls, so they use the standard
timeout. Regenerate the OpenAPI spec.
The dedicated apply endpoint (POST .../upgrade) follows once the Applier
lands (RFC THV-0068, phase B).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
FilterByGroup returns an empty slice (nil error) for a group that does not exist, so a typo'd ?group= silently returned 200 with an empty list instead of the documented 404. Check group existence explicitly via the group manager before filtering, in both the upgrade-check and the listWorkloads handlers, so the advertised 404 is real. Add a bulk upgrade-check test covering the unknown-group path. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The upgrade detection change removed the ConfigDrift.NetworkIsolation field and the BoolChange type, so regenerate the committed OpenAPI spec to drop the stale schema and property. Fixes the Verify Swagger Documentation CI check. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
CLI users had no way to see whether their registry-sourced MCP servers have newer versions available. Surface the upgrade checker on the command line. Add a thv upgrade command group with a check [name] subcommand: with a name it prints a verbose report (candidate image, new env vars, and permission/transport/network posture drift); with no name it prints a table for all workloads. Add an opt-in --check-upgrades flag to thv list that appends an upgrade column. Both reuse the pkg/workloads/upgrade checker and only format results; the default list path is unchanged and performs no registry lookup, so it stays offline-friendly. Bulk output is sorted by name to match thv list. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Reject --check-upgrades together with --format mcpservers: that format has no upgrade column, so the combination performed a registry lookup per workload and discarded the result. Fail loudly in PreRunE instead. - Guard the bulk-result loop against nil entries so it stays robust if CheckAll's contract ever changes. - Drop the network-isolation line from the posture-drift report; the checker no longer reports it (the registry has no such field). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
6faa7be to
664e594
Compare
a6b9a1d to
1029c5c
Compare
There was a problem hiding this comment.
Large PR Detected
This PR exceeds 1000 lines of changes and requires justification before it can be reviewed.
How to unblock this PR:
Add a section to your PR description with the following format:
## Large PR Justification
[Explain why this PR must be large, such as:]
- Generated code that cannot be split
- Large refactoring that must be atomic
- Multiple related changes that would break if separated
- Migration or data transformationAlternative:
Consider splitting this PR into smaller, focused changes (< 1000 lines each) for easier review and reduced risk.
See our Contributing Guidelines for more details.
This review will be automatically dismissed once you add the justification section.
PR size has been reduced below the XL threshold. Thank you for splitting this up!
|
✅ PR size has been reduced below the XL threshold. The size review has been dismissed and this PR can now proceed with normal review. Thank you for splitting this up! |
Summary
CLI users still can't see whether their registry-sourced MCP servers have newer versions. This surfaces the upgrade checker on the command line. Part of RFC THV-0068, local scope.
thv upgradecommand group with acheck [name]subcommand: with a name it prints a verbose report (candidate image, new env vars, permission/transport/network posture drift); with no name it prints a table for all workloads. Supports--format json|text.--check-upgradesflag tothv listthat appends an upgrade column.pkg/workloads/upgradechecker and only format results. The defaultthv listpath is unchanged and performs no registry lookup, so it stays offline-friendly. Bulk output is sorted by name to matchthv list.Type of change
Test plan
task test) — output-formatting helpers only (per the repo's CLI testing convention; command behavior is covered by the e2e in PR 6).task lint-fix)Changes
cmd/thv/app/upgrade.goupgradegroup +checksubcommandcmd/thv/app/list.go--check-upgradesflag + columncmd/thv/app/commands.godocs/cli/*Does this introduce a user-facing change?
Yes — new
thv upgrade checkcommand and an opt-inthv list --check-upgradescolumn.Special notes for reviewers
PR 3 of 6 in the RFC THV-0068 stack; based on #5408. The CLI stays thin — all comparison logic lives in
pkg/workloads/upgrade.🤖 Generated with Claude Code