Add TOOLHIVE_SKIP_UPDATE_CHECK env var to disable update checks#5264
Conversation
ShouldSkipUpdateChecks() previously detected only CI environments via a fixed list of well-known CI env vars. There was no clean way for a user or downstream distribution to disable update checks in a non-CI runtime such as the operator. Add TOOLHIVE_SKIP_UPDATE_CHECK as an explicit opt-out env var. When set to "true" (case-insensitive), ShouldSkipUpdateChecks() returns true, which skips update checks from the CLI, the API server middleware, and the operator telemetry service. Update-derived usage metrics are also skipped, since usagemetrics.shouldEnableMetrics gates on the same function -- this is the intended coupling.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #5264 +/- ##
==========================================
- Coverage 68.12% 68.12% -0.01%
==========================================
Files 617 617
Lines 63066 63068 +2
==========================================
- Hits 42964 42962 -2
- Misses 16896 16902 +6
+ Partials 3206 3204 -2 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Approach looks good — small change, plugs into the right place. A few things I'd like to see before this goes in:
-
Add a unit test for the new env var path.
pkg/updates/client_test.gois already the home forShouldSkipUpdateCheckstests. Covertrue/TRUE/ unset (with CI vars cleared viat.Setenv). -
Heads-up: this also turns off usage metrics, because
usagemetrics.ShouldEnableMetricscallsShouldSkipUpdateChecks(pkg/usagemetrics/collector.go:28). You mention this in the PR body, but the env var name doesn't hint at it. Two options:- Leave the coupling, but note it on the constant's doc comment AND somewhere user-facing (operator Helm values / README) so people don't get surprised.
- Decouple: only update checks read this var; usage metrics keeps its own
TOOLHIVE_USAGE_METRICS_ENABLEDknob. Bigger change — fine to do separately.
-
Bool parsing style:
usagemetricsuses exact== "false"; this PR usesstrings.EqualFold(..., "true"). Not a blocker, butstrconv.ParseBoolwould handle both styles (1,t,TRUE, etc.) and feels more idiomatic. -
Discoverability for operator users: since the motivation is the K8s operator, can we surface this in
deploy/charts/operator/values.yaml(and the README that lists env vars)? Otherwise operators won't know it exists. -
Nit: consider moving the new constant next to
ciEnvVarsso all the "things that decide skip" live together.
- Add TestShouldSkipUpdateChecks_SkipEnvVar covering true / TRUE / unset / false / unrecognized values. Clears CI env vars via t.Setenv so the opt-out path is exercised regardless of how the test binary is run. - Move EnvVarSkipUpdateCheck next to ciEnvVars so all "things that decide skip" live together. Expand the doc comment to spell out the usage-metrics coupling. - Document the env var on the operator chart's `operator.env` field so it is discoverable from values.yaml and the auto-generated chart README. Run helm-docs.
808d003 to
d389da6
Compare
rdimitrov
left a comment
There was a problem hiding this comment.
Thanks — this addresses everything from the previous round:
- ✅
TestShouldSkipUpdateChecks_SkipEnvVarcovers the cases I asked for, and clearing the CI vars inside the loop makes the test deterministic regardless of where it runs. - ✅ Const moved next to
ciEnvVars, and the doc comment now spells out the usage-metrics coupling — that's the discoverability hook I was after. - ✅ Helm chart
values.yaml+ auto-generated README both call it out.
Two tiny things, both non-blocking:
- The PR body's Test plan still only mentions
go build/go vet— worth ticking the unit-test box now that the test exists. - I'm intentionally not pushing on
strconv.ParseBoolvsEqualFold— current behavior matches what you documented ("true"case-insensitive), so leaving it is fine.
LGTM from my side once the test plan checkbox is updated.
Summary
pkg/updates.ShouldSkipUpdateChecks()previously detectedonly CI environments via a fixed list of well-known CI env
vars. There was no clean way for a user or downstream
distribution to disable update checks in a non-CI runtime
such as the operator.
TOOLHIVE_SKIP_UPDATE_CHECKas an explicit opt-outenv var. When set to
"true"(case-insensitive),ShouldSkipUpdateChecks()returns true, which skips updatechecks from the CLI (
cmd/thv/app/commands.go), the APIserver middleware (
pkg/api/server.go), and the operatortelemetry service (
pkg/operator/telemetry/telemetry.go).usagemetrics.shouldEnableMetricsgates on the samefunction. This coupling is intentional.
Type of change
functionality)
Test plan
go build ./pkg/updates/...andgo vet ./pkg/updates/...pass.middleware, operator telemetry) to confirm the new opt-out
gates each path through the existing
ShouldSkipUpdateChecks()entry point.Does this introduce a user-facing change?
Yes. Operators of the binary or the Kubernetes operator can
set
TOOLHIVE_SKIP_UPDATE_CHECK=trueto disable the updatecheck and the usage-metrics collection it gates.