chore: update golangci-lint to v2.12.2 with canonical config
All checks were successful
check / check (push) Successful in 2m3s

Replace .golangci.yml with the canonical v2-schema config
(default: all minus six disabled linters, lll 88, tests included)
and bump every golangci-lint pin to v2.12.2:

- Dockerfile: golangci/golangci-lint:v2.12.2-alpine (hash-pinned)
- script/bootstrap: GOLANGCI_LINT_VERSION 2.12.2 with new
  linux-amd64/arm64 release-archive sha256 pins

Fix all 747 findings the stricter config surfaces, with no behavior
changes: t.Parallel() throughout the test suite, static sentinel
errors and errors.Is comparisons, checked error returns, context
propagation (contextcheck/noctx), 88-column wrapping, extracted
constants and helpers for goconst/dupl/funlen/cyclop, exhaustive
switch cases replicating existing defaults, and white-box test files
renamed to *_internal_test.go for testpackage. Three
nolint:tagliatelle directives preserve the existing snake_case JSON
wire and on-disk metadata formats.
This commit is contained in:
2026-08-07 17:10:27 +00:00
parent 5d0b5f864e
commit 23506df609
55 changed files with 2584 additions and 1863 deletions

View File

@@ -1,6 +1,7 @@
package server
import (
"errors"
"fmt"
"net/http"
"time"
@@ -26,8 +27,11 @@ func (s *Server) serveUntilShutdown() {
s.SetupRoutes()
s.log.Info("http begin listen", "listenaddr", listenAddr)
if err := s.httpServer.ListenAndServe(); err != nil && err != http.ErrServerClosed {
err := s.httpServer.ListenAndServe()
if err != nil && !errors.Is(err, http.ErrServerClosed) {
s.log.Error("listen error", "error", err)
if s.cancelFunc != nil {
s.cancelFunc()
}

View File

@@ -56,7 +56,8 @@ func (s *Server) SetupRoutes() {
s.router.Head("/v1/image/*", s.h.HandleImage())
// Encrypted image URL route
// The trailing filename (e.g., /img.jpg) is ignored but helps browsers with content type
// The trailing filename (e.g., /img.jpg) is ignored but helps
// browsers with content type
s.router.Get("/v1/e/{token}/*", s.h.HandleImageEnc())
// Metrics endpoint with auth

View File

@@ -30,6 +30,7 @@ const (
// Params defines dependencies for Server.
type Params struct {
fx.In
Logger *logger.Logger
Globals *globals.Globals
Config *config.Config
@@ -47,7 +48,6 @@ type Server struct {
startupTime time.Time
exitCode int
sentryEnabled bool
ctx context.Context
cancelFunc context.CancelFunc
httpServer *http.Server
router *chi.Mux
@@ -64,9 +64,9 @@ func New(lc fx.Lifecycle, params Params) (*Server, error) {
}
lc.Append(fx.Hook{
OnStart: func(_ context.Context) error {
OnStart: func(ctx context.Context) error {
s.startupTime = time.Now()
go s.Run()
go s.Run(context.WithoutCancel(ctx))
return nil
},
@@ -83,9 +83,14 @@ func New(lc fx.Lifecycle, params Params) (*Server, error) {
}
// Run starts the server.
func (s *Server) Run() {
func (s *Server) Run(ctx context.Context) {
s.enableSentry()
s.serve()
s.serve(ctx)
}
// MaintenanceMode returns whether maintenance mode is enabled.
func (s *Server) MaintenanceMode() bool {
return s.config.MaintenanceMode
}
func (s *Server) enableSentry() {
@@ -103,19 +108,24 @@ func (s *Server) enableSentry() {
s.log.Error("sentry init failure", "error", err)
os.Exit(1)
}
s.log.Info("sentry error reporting activated")
s.sentryEnabled = true
}
func (s *Server) serve() int {
s.ctx, s.cancelFunc = context.WithCancel(context.Background())
func (s *Server) serve(ctx context.Context) int {
ctx, cancelFunc := context.WithCancel(ctx)
s.cancelFunc = cancelFunc
go func() {
c := make(chan os.Signal, 1)
signal.Ignore(syscall.SIGPIPE)
signal.Notify(c, os.Interrupt, syscall.SIGTERM)
sig := <-c
s.log.Info("signal received", "signal", sig)
if s.cancelFunc != nil {
s.cancelFunc()
}
@@ -123,19 +133,22 @@ func (s *Server) serve() int {
go s.serveUntilShutdown()
<-s.ctx.Done()
s.cleanShutdown()
<-ctx.Done()
s.cleanShutdown(ctx)
return s.exitCode
}
func (s *Server) cleanShutdown() {
func (s *Server) cleanShutdown(ctx context.Context) {
s.exitCode = 0
ctxShutdown, shutdownCancel := context.WithTimeout(context.Background(), ShutdownTimeout)
ctxShutdown, shutdownCancel := context.WithTimeout(
context.WithoutCancel(ctx), ShutdownTimeout)
defer shutdownCancel()
if s.httpServer != nil {
if err := s.httpServer.Shutdown(ctxShutdown); err != nil {
err := s.httpServer.Shutdown(ctxShutdown)
if err != nil {
s.log.Error("server clean shutdown failed", "error", err)
}
}
@@ -144,8 +157,3 @@ func (s *Server) cleanShutdown() {
sentry.Flush(SentryFlushTimeout)
}
}
// MaintenanceMode returns whether maintenance mode is enabled.
func (s *Server) MaintenanceMode() bool {
return s.config.MaintenanceMode
}