feat: inject build version/commit into scraper and UI at docker build time
Some checks failed
CI / Scraper / Lint (push) Failing after 6s
CI / Scraper / Lint (pull_request) Failing after 6s
CI / Scraper / Test (push) Successful in 16s
CI / Scraper / Test (pull_request) Successful in 9s
CI / Scraper / Docker Push (push) Has been skipped
CI / Scraper / Docker Push (pull_request) Has been skipped
CI / UI / Build (push) Successful in 28s
CI / UI / Build (pull_request) Successful in 22s
CI / UI / Docker Push (pull_request) Has been skipped
CI / UI / Docker Push (push) Successful in 36s
iOS CI / Build (pull_request) Successful in 1m41s
iOS CI / Test (pull_request) Successful in 4m7s

- Go scraper: Version/Commit vars in main.go, injected via -ldflags; Server struct + New() updated; GET /health and new GET /api/version expose them
- UI Dockerfile: ARG BUILD_VERSION/BUILD_COMMIT → ENV PUBLIC_BUILD_VERSION/PUBLIC_BUILD_COMMIT for SvelteKit
- Footer: shows version+short commit when not 'dev' (text-zinc-800, subtle)
- docker-compose: args blocks for scraper and ui build sections pass $GIT_TAG/$GIT_COMMIT
This commit is contained in:
Admin
2026-03-10 20:18:13 +05:00
parent 5528abe4b0
commit 261c738fc0
6 changed files with 53 additions and 4 deletions

View File

@@ -9,8 +9,14 @@ RUN go mod download
COPY . .
# Build-time version info — injected by docker-compose or CI via --build-arg.
ARG VERSION=dev
ARG COMMIT=unknown
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 \
go build -ldflags="-s -w" -o /scraper ./cmd/scraper
go build \
-ldflags="-s -w -X main.Version=${VERSION} -X main.Commit=${COMMIT}" \
-o /scraper ./cmd/scraper
# ── Runtime stage ──────────────────────────────────────────────────────────────
FROM alpine:3.21

View File

@@ -47,6 +47,13 @@ import (
"github.com/libnovel/scraper/internal/storage"
)
// Build-time version info — injected via -ldflags during docker build.
// Falls back to "dev" / "unknown" when built without -ldflags (local dev).
var (
Version = "dev"
Commit = "unknown"
)
func main() {
logLevel := slog.LevelInfo
if v := os.Getenv("LOG_LEVEL"); v != "" {
@@ -183,7 +190,7 @@ func run(log *slog.Logger) error {
"pocketbase_url", pbCfg.BaseURL,
"pocketbase_email", pbCfg.AdminEmail,
)
srv := server.New(addr, oCfg, nf, log, store, kokoroURL, kokoroVoice)
srv := server.New(addr, oCfg, nf, log, store, kokoroURL, kokoroVoice, Version, Commit)
return srv.ListenAndServe(ctx)
case "save-browse":

View File

@@ -43,6 +43,8 @@ type Server struct {
running bool
kokoroURL string // Kokoro-FastAPI base URL, e.g. http://kokoro:8880
kokoroVoice string // default voice, e.g. af_bella
version string // semver tag, e.g. "v1.2.3" (set via ldflags)
commit string // short git SHA (set via ldflags)
// voiceMu guards cachedVoices.
voiceMu sync.RWMutex
@@ -74,7 +76,7 @@ type browseCacheEntry struct {
}
// New creates a new Server.
func New(addr string, oCfg orchestrator.Config, novel scraper.NovelScraper, log *slog.Logger, store storage.Store, kokoroURL, kokoroVoice string) *Server {
func New(addr string, oCfg orchestrator.Config, novel scraper.NovelScraper, log *slog.Logger, store storage.Store, kokoroURL, kokoroVoice, version, commit string) *Server {
return &Server{
addr: addr,
oCfg: oCfg,
@@ -83,6 +85,8 @@ func New(addr string, oCfg orchestrator.Config, novel scraper.NovelScraper, log
store: store,
kokoroURL: kokoroURL,
kokoroVoice: kokoroVoice,
version: version,
commit: commit,
audioJobIDs: make(map[string]string),
browseInFlight: make(map[string]struct{}),
browseMemCache: make(map[string]browseCacheEntry),
@@ -138,6 +142,7 @@ func (s *Server) voices() []string {
func (s *Server) ListenAndServe(ctx context.Context) error {
mux := http.NewServeMux()
mux.HandleFunc("GET /health", s.handleHealth)
mux.HandleFunc("GET /api/version", s.handleVersion)
mux.HandleFunc("POST /scrape", s.handleScrapeCatalogue)
mux.HandleFunc("POST /scrape/book", s.handleScrapeBook)
mux.HandleFunc("POST /scrape/book/range", s.handleScrapeBookRange)
@@ -222,7 +227,19 @@ func (s *Server) ListenAndServe(ctx context.Context) error {
func (s *Server) handleHealth(w http.ResponseWriter, _ *http.Request) {
w.Header().Set("Content-Type", "application/json")
_ = json.NewEncoder(w).Encode(map[string]string{"status": "ok"})
_ = json.NewEncoder(w).Encode(map[string]string{
"status": "ok",
"version": s.version,
"commit": s.commit,
})
}
func (s *Server) handleVersion(w http.ResponseWriter, _ *http.Request) {
w.Header().Set("Content-Type", "application/json")
_ = json.NewEncoder(w).Encode(map[string]string{
"version": s.version,
"commit": s.commit,
})
}
// ─── Session cookie helpers ───────────────────────────────────────────────────