fix: clear golangci-lint backlog and make lint job blocking
CI / Lint (push) Successful in 2m29s
Build and Publish Container / build-and-publish (push) Successful in 2m58s
CI / Vulnerability scan (push) Successful in 44s
CI / Test (push) Successful in 1m45s

Addresses errcheck, gosec, revive, staticcheck, and unused findings
across the codebase (unchecked error returns, unsafe file inclusion
warnings on operator/test-controlled paths, missing package comments,
unused parameters, deprecated API usage). Also fixes two suppression
comments that were silently no-ops due to wrong syntax (#nosec needs
a leading '#', nolint reasons need '//' not '--').

With the backlog clear, drop continue-on-error from the CI lint job
per the plan left in b4b4806.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-18 10:32:51 -07:00
parent d63a440f63
commit eda033ff9b
36 changed files with 279 additions and 203 deletions
+9 -9
View File
@@ -17,9 +17,9 @@ func TestCORSMiddleware_AllowedOrigin(t *testing.T) {
}
middleware := newCORSMiddleware(config)
handler := middleware(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
handler := middleware(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
w.WriteHeader(http.StatusOK)
w.Write([]byte("OK"))
_, _ = w.Write([]byte("OK"))
}))
tests := []struct {
@@ -94,9 +94,9 @@ func TestCORSMiddleware_BlockedOrigin(t *testing.T) {
}
middleware := newCORSMiddleware(config)
handler := middleware(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
handler := middleware(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
w.WriteHeader(http.StatusOK)
w.Write([]byte("OK"))
_, _ = w.Write([]byte("OK"))
}))
tests := []struct {
@@ -158,7 +158,7 @@ func TestCORSMiddleware_PreflightRequest(t *testing.T) {
}
middleware := newCORSMiddleware(config)
handler := middleware(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
handler := middleware(http.HandlerFunc(func(_ http.ResponseWriter, _ *http.Request) {
t.Error("Handler should not be called for OPTIONS request")
}))
@@ -217,7 +217,7 @@ func TestCORSMiddleware_Credentials(t *testing.T) {
}
middleware := newCORSMiddleware(config)
handler := middleware(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
handler := middleware(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
w.WriteHeader(http.StatusOK)
}))
@@ -243,7 +243,7 @@ func TestCORSMiddleware_NoWildcard(t *testing.T) {
}
middleware := newCORSMiddleware(config)
handler := middleware(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
handler := middleware(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
w.WriteHeader(http.StatusOK)
}))
@@ -273,7 +273,7 @@ func TestCORSMiddleware_EmptyConfig(t *testing.T) {
}
middleware := newCORSMiddleware(config)
handler := middleware(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
handler := middleware(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
w.WriteHeader(http.StatusOK)
}))
@@ -355,7 +355,7 @@ func TestCORSMiddleware_MaxAge(t *testing.T) {
}
middleware := newCORSMiddleware(config)
handler := middleware(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
handler := middleware(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
w.WriteHeader(http.StatusOK)
}))
+1 -1
View File
@@ -226,7 +226,7 @@ func (h *Handler) GetNotifiers(w http.ResponseWriter, r *http.Request) {
}
// HealthCheck handles GET /health
func (h *Handler) HealthCheck(w http.ResponseWriter, r *http.Request) {
func (h *Handler) HealthCheck(w http.ResponseWriter, _ *http.Request) {
respondJSON(w, http.StatusOK, map[string]interface{}{
"status": "healthy",
"service": "notifier",
+13 -5
View File
@@ -306,7 +306,7 @@ func (h *KeyManagementHandler) GetAuditLog(w http.ResponseWriter, r *http.Reques
// Helper methods
// hasRole checks if the auth context has a specific role
func (h *KeyManagementHandler) hasRole(authCtx *auth.AuthContext, role string) bool {
func (h *KeyManagementHandler) hasRole(authCtx *auth.Context, role string) bool {
for _, r := range authCtx.Roles {
if r == role {
return true
@@ -319,16 +319,24 @@ func (h *KeyManagementHandler) hasRole(authCtx *auth.AuthContext, role string) b
func (h *KeyManagementHandler) respondJSON(w http.ResponseWriter, statusCode int, data interface{}) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(statusCode)
json.NewEncoder(w).Encode(data)
// Headers are already written at this point, so there's nothing left to
// do but log an encode failure.
if err := json.NewEncoder(w).Encode(data); err != nil {
h.logger.Errorf("Failed to encode JSON response: %v", err)
}
}
// respondError writes an error JSON response
func (h *KeyManagementHandler) respondError(w http.ResponseWriter, statusCode int, error string, message string) {
func (h *KeyManagementHandler) respondError(w http.ResponseWriter, statusCode int, errMsg string, message string) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(statusCode)
resp := ErrorResponse{
Error: error,
Error: errMsg,
Message: message,
}
json.NewEncoder(w).Encode(resp)
// Headers are already written at this point, so there's nothing left to
// do but log an encode failure.
if err := json.NewEncoder(w).Encode(resp); err != nil {
h.logger.Errorf("Failed to encode JSON error response: %v", err)
}
}
+10 -3
View File
@@ -1,3 +1,6 @@
// Package rest implements the HTTP/JSON transport for the notifier
// service: request routing, handlers, authentication and CORS middleware,
// and API key management endpoints.
package rest
import (
@@ -138,9 +141,11 @@ func NewRouterWithOptions(opts RouterOptions) *mux.Router {
// LivenessHandler returns a minimal liveness handler for dedicated health
// listeners (the REST router serves the same signal at /health).
func LivenessHandler() http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
return http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(map[string]interface{}{
// Headers are already written, so an encode error can only be
// dropped on the floor here.
_ = json.NewEncoder(w).Encode(map[string]interface{}{
"status": "healthy",
"service": "notifier",
"time": time.Now().UTC(),
@@ -173,7 +178,9 @@ func readinessHandler(checks map[string]ReadinessCheck) http.HandlerFunc {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(status)
ready := status == http.StatusOK
json.NewEncoder(w).Encode(map[string]interface{}{
// Headers are already written, so an encode error can only be
// dropped on the floor here.
_ = json.NewEncoder(w).Encode(map[string]interface{}{
"ready": ready,
"components": components,
})