diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml index cf77677..d75cb1e 100644 --- a/.github/workflows/docker-publish.yml +++ b/.github/workflows/docker-publish.yml @@ -56,5 +56,7 @@ jobs: sbom: false tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} + build-args: | + VERSION=${{ env.RELEASE_VERSION }} cache-from: type=gha cache-to: type=gha,mode=max diff --git a/Dockerfile b/Dockerfile index 925de01..d89ea04 100644 --- a/Dockerfile +++ b/Dockerfile @@ -8,7 +8,7 @@ # # Build: # docker buildx build --platform linux/amd64,linux/arm64 \ -# -t mediastation-go:latest --push . +# --build-arg VERSION=MediaStationGo-v0.1.16 -t mediastation-go:latest --push . # # Optional Intel VAAPI/QSV runtime packages: # docker buildx build --build-arg WITH_VAAPI=true ... @@ -29,6 +29,7 @@ FROM --platform=$BUILDPLATFORM golang:1.25-alpine AS backend ARG TARGETOS ARG TARGETARCH ARG GOPROXY=https://proxy.golang.org,direct +ARG VERSION=dev ENV GOPROXY=${GOPROXY} WORKDIR /app COPY go.mod go.sum ./ @@ -38,7 +39,7 @@ COPY . . COPY --from=frontend /app/web/dist ./web/dist RUN --mount=type=cache,target=/go/pkg/mod \ CGO_ENABLED=0 GOOS=${TARGETOS} GOARCH=${TARGETARCH} \ - go build -trimpath -ldflags="-s -w" -o mediastation-go ./cmd/server + go build -trimpath -ldflags="-s -w -X main.version=${VERSION}" -o mediastation-go ./cmd/server # ---- Stage 3: runtime ------------------------------------------------------ FROM alpine:3.23 diff --git a/cmd/server/main.go b/cmd/server/main.go index 6b8dd70..5eafad8 100644 --- a/cmd/server/main.go +++ b/cmd/server/main.go @@ -18,6 +18,7 @@ import ( "net/http" "os" "os/signal" + "strings" "syscall" "time" @@ -33,6 +34,20 @@ import ( // version is overwritten at build time via -ldflags="-X main.version=...". var version = "dev" +func effectiveVersion(buildVersion string) string { + buildVersion = strings.TrimSpace(buildVersion) + if buildVersion != "" && buildVersion != "dev" { + return buildVersion + } + if envVersion := strings.TrimSpace(os.Getenv("MEDIASTATION_VERSION")); envVersion != "" { + return envVersion + } + if buildVersion == "" { + return "dev" + } + return buildVersion +} + func main() { cfg, err := config.Load() if err != nil { @@ -47,8 +62,9 @@ func main() { } defer func() { _ = logger.Sync() }() + appVersion := effectiveVersion(version) logger.Info("starting MediaStationGo", - zap.String("version", version), + zap.String("version", appVersion), zap.Int("port", cfg.App.Port), zap.String("data_dir", cfg.App.DataDir), ) @@ -77,7 +93,7 @@ func main() { repos := repository.New(db) service.ApplyRuntimeSettings(context.Background(), cfg, repos, logger) applyCPUThreadLimit(cfg, logger) - services := service.NewWithVersion(cfg, logger, repos, version) + services := service.NewWithVersion(cfg, logger, repos, appVersion) if repaired, err := services.RepairCloudPathMetadata(context.Background()); err != nil { logger.Warn("cloud path metadata repair failed", zap.Error(err)) diff --git a/cmd/server/main_test.go b/cmd/server/main_test.go index 0f2ce25..7f1bd36 100644 --- a/cmd/server/main_test.go +++ b/cmd/server/main_test.go @@ -11,6 +11,30 @@ import ( "github.com/gin-gonic/gin" ) +func TestEffectiveVersionPrefersBuildVersion(t *testing.T) { + t.Setenv("MEDIASTATION_VERSION", "MediaStationGo-v0.1.15") + + if got := effectiveVersion("MediaStationGo-v0.1.16"); got != "MediaStationGo-v0.1.16" { + t.Fatalf("effectiveVersion = %q, want MediaStationGo-v0.1.16", got) + } +} + +func TestEffectiveVersionUsesEnvWhenBuildVersionIsDev(t *testing.T) { + t.Setenv("MEDIASTATION_VERSION", " MediaStationGo-v0.1.16 ") + + if got := effectiveVersion("dev"); got != "MediaStationGo-v0.1.16" { + t.Fatalf("effectiveVersion = %q, want MediaStationGo-v0.1.16", got) + } +} + +func TestEffectiveVersionDefaultsToDev(t *testing.T) { + t.Setenv("MEDIASTATION_VERSION", "") + + if got := effectiveVersion(""); got != "dev" { + t.Fatalf("effectiveVersion = %q, want dev", got) + } +} + func TestServeSPANoCachesIndexAndServesRoutes(t *testing.T) { gin.SetMode(gin.TestMode) webDir := t.TempDir()