ci: check readiness and the release version after deploy
CI / go (push) Canceled after 0s
CI / web (push) Canceled after 0s
CI / images (Dockerfile, server, alisten) (push) Canceled after 0s
CI / images (web/Dockerfile, web, ) (push) Canceled after 0s
CI / images (worker.Dockerfile, worker, alisten-worker) (push) Canceled after 0s
CI / helm-release (push) Canceled after 0s

The ops port serves GET /version, so the smoke test can confirm that the
upgraded build is the one answering.
This commit is contained in:
DiheChen committed 2026-11-07 08:07:21 +08:00
1 parent 0345d948ac
commit 535136bc7b
6 files changed
+23 -6

No files matched your search

+9 -1
View File
@@ -59,6 +59,7 @@ jobs:
shell: bash
env:
KUBECONFIG: ${{ runner.temp }}/k3s-kubeconfig
HEAD_SHA: ${{ github.event.workflow_run.head_sha }}
run: |
set -euo pipefail
kubectl port-forward --namespace alisten service/alisten-serve 18090:9090 &
@@ -69,4 +70,11 @@ jobs:
--retry-delay 2 \
--retry-connrefused \
--max-time 10 \
http://127.0.0.1:18090/healthz
http://127.0.0.1:18090/readyz
# CI 构建发布镜像时把 tag+commit 写进版本号。
expected="${TAG}+${HEAD_SHA}"
actual="$(curl --silent --show-error --fail --max-time 10 http://127.0.0.1:18090/version)"
if [[ "$actual" != "$expected" ]]; then
printf '线上版本是 %s,期望 %s\n' "$actual" "$expected" >&2
exit 1
fi
+4 -1
View File
@@ -8,7 +8,7 @@ import (
"github.com/prometheus/client_golang/prometheus/promhttp"
)
func NewHandler(ready func() bool, metrics prometheus.Gatherer) http.Handler {
func NewHandler(ready func() bool, metrics prometheus.Gatherer, version string) http.Handler {
mux := http.NewServeMux()
mux.HandleFunc("GET /healthz", func(w http.ResponseWriter, _ *http.Request) {
_, _ = io.WriteString(w, "ok\n")
@@ -20,6 +20,9 @@ func NewHandler(ready func() bool, metrics prometheus.Gatherer) http.Handler {
}
_, _ = io.WriteString(w, "ok\n")
})
mux.HandleFunc("GET /version", func(w http.ResponseWriter, _ *http.Request) {
_, _ = io.WriteString(w, version+"\n")
})
mux.Handle("GET /metrics", promhttp.HandlerFor(metrics, promhttp.HandlerOpts{}))
return mux
}
+7 -1
View File
@@ -15,7 +15,7 @@ func TestHandler(t *testing.T) {
registry := prometheus.NewRegistry()
registry.MustRegister(prometheus.NewGauge(prometheus.GaugeOpts{Name: "test_gauge", Help: "测试用指标。"}))
var ready atomic.Bool
handler := NewHandler(ready.Load, registry)
handler := NewHandler(ready.Load, registry, "v1.2.3+abc")
get := func(path string) *httptest.ResponseRecorder {
rec := httptest.NewRecorder()
@@ -28,6 +28,12 @@ func TestHandler(t *testing.T) {
t.Errorf("/healthz 状态码 = %d,期望 200", rec.Code)
}
})
t.Run("version 返回构建版本", func(t *testing.T) {
rec := get("/version")
if body := rec.Body.String(); rec.Code != http.StatusOK || body != "v1.2.3+abc\n" {
t.Errorf("/version 状态码 = %d,响应 = %q,期望 200 和 \"v1.2.3+abc\\n\"", rec.Code, body)
}
})
t.Run("metrics 输出注册的指标", func(t *testing.T) {
rec := get("/metrics")
body, _ := io.ReadAll(rec.Body)
+1 -1
View File
@@ -12,7 +12,7 @@ import (
func TestHealthcheckFollowsReadiness(t *testing.T) {
var ready atomic.Bool
server := httptest.NewServer(ops.NewHandler(ready.Load, prometheus.NewRegistry()))
server := httptest.NewServer(ops.NewHandler(ready.Load, prometheus.NewRegistry(), version))
defer server.Close()
t.Setenv("ALISTEN_OPS_LISTEN", server.Listener.Addr().String())
+1 -1
View File
@@ -182,7 +182,7 @@ func runServe(base *slog.Logger) (err error) {
opsLogger := base.With("component", "ops")
publicServer := newHTTPServer(p.handler, base.With("component", "http"))
opsServer := newHTTPServer(recoverPanics(ops.NewHandler(ready, metrics), opsLogger), opsLogger)
opsServer := newHTTPServer(recoverPanics(ops.NewHandler(ready, metrics, version), opsLogger), opsLogger)
go func() { fatal <- fmt.Errorf("HTTP 服务异常退出:%w", publicServer.Serve(publicListener)) }()
go func() { fatal <- fmt.Errorf("HTTP 服务异常退出:%w", opsServer.Serve(opsListener)) }()
logger.Info("服务已启动", "listen", publicListener.Addr().String(), "ops_listen", opsListener.Addr().String(), "instance", instance)
+1 -1
View File
@@ -275,7 +275,7 @@ func (w mediaWorker) run(ctx context.Context, listener net.Listener) error {
}),
)
opsLogger := w.base.With("component", "ops")
opsServer := newHTTPServer(recoverPanics(ops.NewHandler(ready, w.metrics), opsLogger), opsLogger)
opsServer := newHTTPServer(recoverPanics(ops.NewHandler(ready, w.metrics, version), opsLogger), opsLogger)
go func() { fatal <- fmt.Errorf("运维端口异常退出:%w", opsServer.Serve(listener)) }()
w.logger.Info("worker 已启动", "ops_listen", listener.Addr().String(), "instance", w.instance)