From 10b0c99f176e29218cad59dc5f7bc1ca5510e5aa Mon Sep 17 00:00:00 2001 From: andig Date: Wed, 26 Aug 2026 21:11:46 +0200 Subject: [PATCH] chore: make dev versions increase monotonically (#33205) --- .goreleaser-nightly.yml | 10 ++++------ .goreleaser.yml | 10 ++++------ Makefile | 17 +++++++++-------- assets/js/components/AboutModal.stories.ts | 3 ++- assets/js/components/AboutModal.vue | 11 +++-------- assets/js/types/evcc.ts | 1 + assets/js/utils/version.test.ts | 14 +++----------- assets/js/utils/version.ts | 8 ++------ assets/js/views/App.vue | 1 + server/http_site_handler.go | 2 ++ util/version.go | 2 +- 11 files changed, 32 insertions(+), 47 deletions(-) diff --git a/.goreleaser-nightly.yml b/.goreleaser-nightly.yml index 427faeedf..a9a957db2 100644 --- a/.goreleaser-nightly.yml +++ b/.goreleaser-nightly.yml @@ -11,8 +11,7 @@ builds: - -trimpath - -tags=release ldflags: - # the package version carries a timestamp for ordering, the reported version does not - - -X github.com/evcc-io/evcc/util.Version={{ if .IsSnapshot }}{{ incminor .Tag }}-dev+{{ .ShortCommit }}{{ else }}{{ .Version }}{{ end }} -X github.com/evcc-io/evcc/util.Commit={{ .ShortCommit }} -s -w + - -X github.com/evcc-io/evcc/util.Version={{ .Version }} -X github.com/evcc-io/evcc/util.Commit={{ .ShortCommit }} -s -w env: - CGO_ENABLED=0 goos: @@ -57,10 +56,9 @@ checksum: name_template: "checksums.txt" snapshot: - # semver pre-release of the upcoming version. The timestamp makes the package - # version increase monotonically: apt compares it numerically, while the commit - # alone would sort randomly. - version_template: "{{ incminor .Version }}-dev.{{ .Timestamp }}+{{ .ShortCommit }}" + # semver pre-release of the upcoming version, the timestamp keeps the package + # version increasing monotonically for apt + version_template: "{{ incminor .Version }}-dev.{{ .Timestamp }}" changelog: sort: asc diff --git a/.goreleaser.yml b/.goreleaser.yml index 8c1d08ea3..4782813ce 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -16,8 +16,7 @@ builds: - -trimpath - -tags=release ldflags: - # the package version carries a timestamp for ordering, the reported version does not - - -X github.com/evcc-io/evcc/util.Version={{ if .IsSnapshot }}{{ incminor .Tag }}-dev+{{ .ShortCommit }}{{ else }}{{ .Version }}{{ end }} -s -w + - -X github.com/evcc-io/evcc/util.Version={{ .Version }} -s -w env: - CGO_ENABLED=0 goos: @@ -77,10 +76,9 @@ checksum: name_template: "checksums.txt" snapshot: - # semver pre-release of the upcoming version. The timestamp makes the package - # version increase monotonically: apt compares it numerically, while the commit - # alone would sort randomly. - version_template: "{{ incminor .Version }}-dev.{{ .Timestamp }}+{{ .ShortCommit }}" + # semver pre-release of the upcoming version, the timestamp keeps the package + # version increasing monotonically for apt + version_template: "{{ incminor .Version }}-dev.{{ .Timestamp }}" changelog: sort: asc diff --git a/Makefile b/Makefile index c44314969..70a2acd9b 100644 --- a/Makefile +++ b/Makefile @@ -6,15 +6,16 @@ GIT_TAG := $(shell test -d .git && git describe --abbrev=0 --tags) # commits since the latest tag, empty or 0 means the commit is tagged GIT_DIST := $(shell test -n "$(GIT_TAG)" && git rev-list --count $(GIT_TAG)..HEAD) NEXT_TAG = $(shell echo $(GIT_TAG) | awk -F. -v b='$(BUMP)' '{ if (b == "patch") { m = $$2; p = $$3 + 1 } else { m = $$2 + 1; p = 0 }; print $$1 "." m "." p }') -# untagged builds are semver pre-releases of the upcoming version -TAG_NAME ?= $(if $(filter-out 0,$(GIT_DIST)),$(NEXT_TAG)-dev+$(SHA),$(GIT_TAG)) +# untagged builds are semver pre-releases of the upcoming version, the build +# timestamp keeps them increasing monotonically +BUILD_TIMESTAMP := $(shell date -u '+%s') +TAG_NAME ?= $(if $(filter-out 0,$(GIT_DIST)),$(NEXT_TAG)-dev.$(BUILD_TIMESTAMP),$(GIT_TAG)) COMMIT := $(SHA) # hide commit for releases ifeq ($(RELEASE),1) COMMIT := endif VERSION := $(if $(TAG_NAME),$(TAG_NAME),$(SHA)) -BUILD_DATE := $(shell date -u '+%Y-%m-%d_%H:%M:%S') BUILD_TAGS := -tags=release LD_FLAGS := -X github.com/evcc-io/evcc/util.Version=$(VERSION) -X github.com/evcc-io/evcc/util.Commit=$(COMMIT) -s -w BUILD_ARGS := -trimpath -ldflags='$(LD_FLAGS)' @@ -99,7 +100,7 @@ porcelain:: test -z "$$(git status --porcelain)" || (git status; git diff; false) build:: - @echo Version: $(VERSION) $(SHA) $(BUILD_DATE) + @echo Version: $(VERSION) $(SHA) CGO_ENABLED=0 go build -v $(BUILD_TAGS) $(BUILD_ARGS) snapshot:: @@ -109,15 +110,15 @@ release:: goreleaser --clean docker:: - @echo Version: $(VERSION) $(SHA) $(BUILD_DATE) + @echo Version: $(VERSION) $(SHA) docker buildx build --platform $(PLATFORM) --tag $(DOCKER_IMAGE):$(DOCKER_TAG) --push . publish-nightly:: - @echo Version: $(VERSION) $(SHA) $(BUILD_DATE) + @echo Version: $(VERSION) $(SHA) docker buildx build --platform $(PLATFORM) --tag $(DOCKER_IMAGE):nightly --push . publish-release:: - @echo Version: $(VERSION) $(SHA) $(BUILD_DATE) + @echo Version: $(VERSION) $(SHA) docker buildx build --platform $(PLATFORM) --tag $(DOCKER_IMAGE):latest --tag $(DOCKER_IMAGE):$(VERSION) --build-arg RELEASE=1 --push . apt-nightly:: @@ -153,7 +154,7 @@ gok-update:: ${GOK} update yes soc:: - @echo Version: $(VERSION) $(SHA) $(BUILD_DATE) + @echo Version: $(VERSION) $(SHA) go build $(BUILD_TAGS) $(BUILD_ARGS) github.com/evcc-io/evcc/cmd/soc # patch asn1.go to allow Elli buggy certificates to be accepted with EEBUS diff --git a/assets/js/components/AboutModal.stories.ts b/assets/js/components/AboutModal.stories.ts index 4b23c3fb1..089c8e461 100644 --- a/assets/js/components/AboutModal.stories.ts +++ b/assets/js/components/AboutModal.stories.ts @@ -94,7 +94,8 @@ StableUpdateWithUpdater.args = { export const Nightly = Template.bind({}); Nightly.args = { - installed: "0.304.0-dev+5ce7be4", + installed: "0.304.0-dev.1712345678", + commit: "5ce7be4", }; export const DevBuild = Template.bind({}); diff --git a/assets/js/components/AboutModal.vue b/assets/js/components/AboutModal.vue index b0df8929e..21fd167db 100644 --- a/assets/js/components/AboutModal.vue +++ b/assets/js/components/AboutModal.vue @@ -147,13 +147,7 @@ import Logo from "./Footer/Logo.vue"; import api from "@/api"; import settings from "@/settings"; import { extractDomain } from "@/utils/extractDomain"; -import { - isDevelopment, - isNightly, - getReleaseName, - commitFromVersion, - isNewVersionAvailable, -} from "@/utils/version"; +import { isDevelopment, isNightly, getReleaseName, isNewVersionAvailable } from "@/utils/version"; import { defineComponent } from "vue"; const GITHUB_REPO = "https://github.com/evcc-io/evcc"; @@ -164,6 +158,7 @@ export default defineComponent({ components: { GenericModal, Logo }, props: { installed: { type: String, default: "" }, + commit: { type: String, default: "" }, availableVersion: String, releaseNotes: String, hasUpdater: Boolean, @@ -208,7 +203,7 @@ export default defineComponent({ return `${GITHUB_REPO}/network/dependencies`; }, githubCommitUrl() { - return `${GITHUB_REPO}/commit/${commitFromVersion(this.installed)}`; + return `${GITHUB_REPO}/commit/${this.commit}`; }, modalSize() { return this.newVersionAvailable ? undefined : "sm"; diff --git a/assets/js/types/evcc.ts b/assets/js/types/evcc.ts index 470188ed3..509ee3c87 100644 --- a/assets/js/types/evcc.ts +++ b/assets/js/types/evcc.ts @@ -8,6 +8,7 @@ declare global { app: any; evcc?: { version: string; + commit: string; customCss: boolean; customLogo: boolean; customBrand: string; diff --git a/assets/js/utils/version.test.ts b/assets/js/utils/version.test.ts index a48edb1c6..84a6c3114 100644 --- a/assets/js/utils/version.test.ts +++ b/assets/js/utils/version.test.ts @@ -2,14 +2,13 @@ import { describe, expect, test } from "vite-plus/test"; import { isDevelopment, isNightly, - commitFromVersion, getReleaseName, getShortVersion, isNewVersionAvailable, } from "./version"; const DEV = "0.0.0"; -const NIGHTLY = "0.304.0-dev+abc1234"; +const NIGHTLY = "0.304.0-dev.1712345678"; const STABLE = "0.303.1"; describe("isDevelopment", () => { @@ -21,20 +20,13 @@ describe("isDevelopment", () => { }); describe("isNightly", () => { - test("only versions with build metadata", () => { + test("only pre-release versions", () => { expect(isNightly(DEV)).toBe(false); expect(isNightly(NIGHTLY)).toBe(true); expect(isNightly(STABLE)).toBe(false); }); }); -describe("commitFromVersion", () => { - test("extracts build metadata", () => { - expect(commitFromVersion(NIGHTLY)).toBe("abc1234"); - expect(commitFromVersion(STABLE)).toBe(""); - }); -}); - describe("getReleaseName", () => { test("maps version to release name", () => { expect(getReleaseName(DEV)).toBe("development"); @@ -46,7 +38,7 @@ describe("getReleaseName", () => { describe("getShortVersion", () => { test("formats version", () => { expect(getShortVersion(DEV)).toBe("dev build"); - expect(getShortVersion(NIGHTLY)).toBe("v0.304.0-dev+abc1234"); + expect(getShortVersion(NIGHTLY)).toBe("v0.304.0-dev.1712345678"); expect(getShortVersion(STABLE)).toBe("v0.303.1"); }); }); diff --git a/assets/js/utils/version.ts b/assets/js/utils/version.ts index 5fb990d3b..71b98e80c 100644 --- a/assets/js/utils/version.ts +++ b/assets/js/utils/version.ts @@ -2,13 +2,9 @@ export function isDevelopment(version: string): boolean { return version === "0.0.0"; } -// untagged builds carry the commit as build metadata: 0.304.0-dev+abc1234 +// untagged builds are pre-releases carrying the build timestamp: 0.304.0-dev.1712345678 export function isNightly(version: string): boolean { - return version.includes("+"); -} - -export function commitFromVersion(version: string): string { - return version.split("+")[1] ?? ""; + return version.includes("-dev."); } export function getReleaseName(version: string): string { diff --git a/assets/js/views/App.vue b/assets/js/views/App.vue index 44f8a4740..f1d08e08a 100644 --- a/assets/js/views/App.vue +++ b/assets/js/views/App.vue @@ -105,6 +105,7 @@ export default defineComponent({ aboutModalProps() { return { installed: window.evcc?.version, + commit: window.evcc?.commit, customLogo: this.custom.logo, customBrand: this.custom.brand, customWebsite: this.custom.website, diff --git a/server/http_site_handler.go b/server/http_site_handler.go index 659dd7708..231298187 100644 --- a/server/http_site_handler.go +++ b/server/http_site_handler.go @@ -54,6 +54,7 @@ func getPreferredLanguage(header string) string { func globalsJsHandler(custom Customization) http.HandlerFunc { globals := struct { Version string `json:"version"` + Commit string `json:"commit"` CustomCss bool `json:"customCss"` CustomLogo bool `json:"customLogo"` Brand string `json:"customBrand"` @@ -63,6 +64,7 @@ func globalsJsHandler(custom Customization) http.HandlerFunc { Theme string `json:"customTheme"` }{ Version: util.Version, + Commit: util.Commit, CustomCss: custom.Css != "", CustomLogo: custom.LogoLight != "", Brand: custom.Brand, diff --git a/util/version.go b/util/version.go index 3feb56031..22710a4ec 100644 --- a/util/version.go +++ b/util/version.go @@ -12,7 +12,7 @@ var ( Commit = "" ) -// FormattedVersion returns the version, untagged builds carry the commit as build metadata +// FormattedVersion returns the version, untagged builds carry a build timestamp func FormattedVersion() string { return Version }