Skip to content

feat: add /healthz and /readyz health endpoints - #2

Merged
slayerjain merged 2 commits into
mainfrom
feat/health-endpoints
Sep 19, 2026
Merged

slayerjain merged 2 commits into
mainfrom
feat/health-endpoints

Conversation

@slayerjain

@slayerjain slayerjain commented Sep 19, 2026

Copy link
Copy Markdown
Member

Problem

gitstats implemented no health endpoints (validated against source v1.0.0: routes/routes.go had /, /orgs, /repo-stats, … but no /healthz//readyz). When the shared api-server chart added default probes (startup+liveness → /healthz, readiness → /readyz), the pod 404'd the startup probe, kubelet killed it, → CrashLoopBackOff (old ReplicaSet kept serving; no outage).

Fix

Add proper endpoints so the standard chart probes work unmodified:

  • /healthz (liveness): 200 "ok", no I/O — never restarts the pod for a slow upstream.
  • /readyz (readiness): 200 "ready" — gitstats has no hard startup dependency (serves static pages, queries GitHub lazily per request), so ready == server accepting connections.

Both registered on the DefaultServeMux; exact patterns take precedence over the / catch-all (go 1.24 ServeMux), verified with a live smoke test (/, /orgs, /bogus→404 all still correct).

Also: bound the GitHub HTTP clients

Every GitHub API call used a zero-value http.Client{} with no timeout — it could hang a request handler (and CI) indefinitely if GitHub is slow/unreachable. Added const githubHTTPClientTimeout = 15s applied to all 8 clients.

Also: make the active-contributors test hermetic

TestHandleActiveContributors_ValidOrgAndRepo previously hit live api.github.com with a Body.Len()>0 assertion that passed even on rate-limit/error responses. Introduced an overridable githubAPIBaseURL (all 10 GitHub REST calls route through it) so the test redirects to an httptest stub, and it now asserts real behaviour (org members excluded, external contributor's commits counted, repo_name). Runs offline in ~0ms. Format strings kept constant so go vet still checks the verbs.

Tests / CI

  • handlers/health_test.go: hermetic unit tests (status + body) for both endpoints.
  • New .woodpecker/ci.yml (go build/vet/test on PRs and pushes to main), mirroring the telemetry repo — gitstats previously ran no tests in CI (only a tag-triggered GH Actions docker build, which stays as-is).

gitstats implemented no health endpoints, so when the shared api-server
chart added default probes (startup+liveness on /healthz, readiness on
/readyz) the pod failed them (404) and crashlooped.

Add proper endpoints so the standard chart probes work unmodified:
- /healthz (liveness): 200 while the HTTP server is up; no I/O.
- /readyz (readiness): 200 — gitstats has no hard startup dependency
  (static pages + lazy per-request GitHub calls), so ready == serving.

Also bound every outbound GitHub API call with a 15s client timeout;
the previous zero-value http.Client had no timeout and could hang a
request handler (and CI) indefinitely when GitHub is slow.

Adds hermetic unit tests for both endpoints and a Woodpecker CI pipeline
(go build/vet/test on PRs and pushes to main) — the repo previously ran
no tests in CI.

Signed-off-by: Shubham Jain <shubhamkjain@outlook.com>
@slayerjain
slayerjain force-pushed the feat/health-endpoints branch from 124d261 to 33580ff Compare September 19, 2026 12:33
TestHandleActiveContributors_ValidOrgAndRepo hit live api.github.com with a
Body.Len()>0 assertion that passed even on rate-limit/error responses —
network-coupled and effectively assertion-free.

Introduce an overridable githubAPIBaseURL (all 10 GitHub REST calls route
through it) so the test can redirect to an httptest stub, and assert real
behaviour: org members excluded, the external contributor's commits counted,
repo_name correct. The test now runs offline in ~0ms.

Format strings are kept constant (fmt.Sprintf("%s/...", githubAPIBaseURL, ...))
so go vet still validates the printf verbs.

Signed-off-by: Shubham Jain <shubhamkjain@outlook.com>
@slayerjain
slayerjain merged commit b4abfde into main Sep 19, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant