Stamp app version into builds
ci / lint-test (push) Successful in 1m17s
ci / build (push) Successful in 2m33s

This commit is contained in:
Joe Julian
2026-04-05 23:56:58 -07:00
parent 9aeb98da58
commit 1c72a5009f
9 changed files with 55 additions and 4 deletions
+4 -1
View File
@@ -107,6 +107,7 @@ jobs:
shell: bash shell: bash
run: | run: |
set -euo pipefail set -euo pipefail
app_version="$(git describe --tags --always --dirty)"
# Gio needs a Linux ARM64 cgo cross-toolchain for desktop builds. # Gio needs a Linux ARM64 cgo cross-toolchain for desktop builds.
# Keep the CI matrix to targets this runner can build reproducibly. # Keep the CI matrix to targets this runner can build reproducibly.
for target in \ for target in \
@@ -126,13 +127,15 @@ jobs:
ext=".exe" ext=".exe"
fi fi
out="${DIST_DIR}/keepassgo-${goos}-${goarch}${ext}" out="${DIST_DIR}/keepassgo-${goos}-${goarch}${ext}"
GOOS="${goos}" GOARCH="${goarch}" CGO_ENABLED="${cgo_enabled}" go build -o "${out}" . GOOS="${goos}" GOARCH="${goarch}" CGO_ENABLED="${cgo_enabled}" \
go build -ldflags "-X main.appVersion=${app_version}" -o "${out}" .
done done
- name: Build APK - name: Build APK
shell: bash shell: bash
run: | run: |
set -euo pipefail set -euo pipefail
export APP_VERSION="$(git describe --tags --always --dirty)"
make apk make apk
cp build/keepassgo.apk "${DIST_DIR}/keepassgo.apk" cp build/keepassgo.apk "${DIST_DIR}/keepassgo.apk"
+1
View File
@@ -12,6 +12,7 @@ Environment:
- `ANDROID_NDK_ROOT` defaults to `/opt/android-ndk`. - `ANDROID_NDK_ROOT` defaults to `/opt/android-ndk`.
- `JAVA_HOME` defaults to `/usr/lib/jvm/java-25-openjdk`. - `JAVA_HOME` defaults to `/usr/lib/jvm/java-25-openjdk`.
- `APP_ID` overrides the Android application id. - `APP_ID` overrides the Android application id.
- `APP_VERSION` overrides the version shown inside KeePassGO itself.
- `APK_OUT` overrides the output path. - `APK_OUT` overrides the output path.
- `APK_VERSION` overrides the packaged app version. - `APK_VERSION` overrides the packaged app version.
- `ANDROID_MIN_SDK` overrides the minimum supported Android SDK. - `ANDROID_MIN_SDK` overrides the minimum supported Android SDK.
+3
View File
@@ -5,6 +5,8 @@ PATH := $(JAVA_HOME)/bin:$(ANDROID_SDK_ROOT)/cmdline-tools/latest/bin:$(ANDROID_
APP_ID ?= org.julianfamily.keepassgo APP_ID ?= org.julianfamily.keepassgo
APK_OUT ?= build/keepassgo.apk APK_OUT ?= build/keepassgo.apk
APK_VERSION ?= 0.1.0.1 APK_VERSION ?= 0.1.0.1
APP_VERSION ?= $(shell git describe --tags --always --dirty 2>/dev/null || echo dev)
GO_LDFLAGS ?= -X main.appVersion=$(APP_VERSION)
ANDROID_MIN_SDK ?= 28 ANDROID_MIN_SDK ?= 28
ANDROID_TARGET_SDK ?= 35 ANDROID_TARGET_SDK ?= 35
@@ -24,6 +26,7 @@ apk: android/keepassgo-android.jar
go tool gogio -target android \ go tool gogio -target android \
-buildmode exe \ -buildmode exe \
-appid $(APP_ID) \ -appid $(APP_ID) \
-ldflags "$(GO_LDFLAGS)" \
-o $(APK_OUT) \ -o $(APK_OUT) \
-version $(APK_VERSION) \ -version $(APK_VERSION) \
-minsdk $(ANDROID_MIN_SDK) \ -minsdk $(ANDROID_MIN_SDK) \
+7
View File
@@ -41,6 +41,13 @@ Desktop build:
go build ./... go build ./...
``` ```
By default, build outputs stamp the app version from `git describe --tags --always --dirty`.
You can override the version shown in KeePassGO with:
```bash
go build -ldflags "-X main.appVersion=v0.0.1" ./...
```
## Arch Linux Package ## Arch Linux Package
An AUR-style package definition for the Linux desktop client lives under: An AUR-style package definition for the Linux desktop client lives under:
+4
View File
@@ -13,6 +13,7 @@ const (
DefaultAppID = "org.julianfamily.keepassgo" DefaultAppID = "org.julianfamily.keepassgo"
DefaultAPKOut = "build/keepassgo.apk" DefaultAPKOut = "build/keepassgo.apk"
DefaultVersion = "0.1.0.1" DefaultVersion = "0.1.0.1"
DefaultLdflags = "-X main.appVersion=dev"
DefaultMinSDK = "28" DefaultMinSDK = "28"
DefaultTargetSDK = "35" DefaultTargetSDK = "35"
DefaultIconPath = "assets/keepassgo-icon.png" DefaultIconPath = "assets/keepassgo-icon.png"
@@ -25,6 +26,7 @@ type Config struct {
AppID string AppID string
APKOut string APKOut string
Version string Version string
Ldflags string
MinSDK string MinSDK string
TargetSDK string TargetSDK string
IconPath string IconPath string
@@ -38,6 +40,7 @@ func DefaultConfig() Config {
AppID: DefaultAppID, AppID: DefaultAppID,
APKOut: DefaultAPKOut, APKOut: DefaultAPKOut,
Version: DefaultVersion, Version: DefaultVersion,
Ldflags: DefaultLdflags,
MinSDK: DefaultMinSDK, MinSDK: DefaultMinSDK,
TargetSDK: DefaultTargetSDK, TargetSDK: DefaultTargetSDK,
IconPath: DefaultIconPath, IconPath: DefaultIconPath,
@@ -49,6 +52,7 @@ func (c Config) GogioArgs() []string {
"-target", "android", "-target", "android",
"-buildmode", "exe", "-buildmode", "exe",
"-appid", c.AppID, "-appid", c.AppID,
"-ldflags", c.Ldflags,
"-o", c.APKOut, "-o", c.APKOut,
"-version", c.Version, "-version", c.Version,
"-minsdk", c.MinSDK, "-minsdk", c.MinSDK,
+3
View File
@@ -15,6 +15,7 @@ func TestDefaultConfigGogioArgs(t *testing.T) {
"-target", "android", "-target", "android",
"-buildmode", "exe", "-buildmode", "exe",
"-appid", DefaultAppID, "-appid", DefaultAppID,
"-ldflags", DefaultLdflags,
"-o", DefaultAPKOut, "-o", DefaultAPKOut,
"-version", DefaultVersion, "-version", DefaultVersion,
"-minsdk", DefaultMinSDK, "-minsdk", DefaultMinSDK,
@@ -52,6 +53,7 @@ func TestValidateAcceptsCompleteAndroidToolchainLayout(t *testing.T) {
AppID: DefaultAppID, AppID: DefaultAppID,
APKOut: DefaultAPKOut, APKOut: DefaultAPKOut,
Version: DefaultVersion, Version: DefaultVersion,
Ldflags: DefaultLdflags,
MinSDK: DefaultMinSDK, MinSDK: DefaultMinSDK,
TargetSDK: DefaultTargetSDK, TargetSDK: DefaultTargetSDK,
IconPath: filepath.Join(root, "icon.png"), IconPath: filepath.Join(root, "icon.png"),
@@ -77,6 +79,7 @@ func TestValidateRejectsMissingPrerequisites(t *testing.T) {
AppID: DefaultAppID, AppID: DefaultAppID,
APKOut: DefaultAPKOut, APKOut: DefaultAPKOut,
Version: DefaultVersion, Version: DefaultVersion,
Ldflags: DefaultLdflags,
MinSDK: DefaultMinSDK, MinSDK: DefaultMinSDK,
TargetSDK: DefaultTargetSDK, TargetSDK: DefaultTargetSDK,
} }
+11 -2
View File
@@ -43,6 +43,15 @@ import (
"golang.org/x/exp/shiny/materialdesign/icons" "golang.org/x/exp/shiny/materialdesign/icons"
) )
var appVersion = "dev"
func currentAppVersion() string {
if strings.TrimSpace(appVersion) == "" {
return "dev"
}
return strings.TrimSpace(appVersion)
}
type entry = vault.Entry type entry = vault.Entry
const ( const (
@@ -4246,12 +4255,12 @@ func (u *ui) aboutDetailPanel(gtx layout.Context) layout.Dimensions {
aboutFact(u.theme, "Programmatic Access", "Secure local gRPC API", "Built for trusted clients such as browser extensions and automation."), aboutFact(u.theme, "Programmatic Access", "Secure local gRPC API", "Built for trusted clients such as browser extensions and automation."),
layout.Spacer{Height: unit.Dp(14)}.Layout, layout.Spacer{Height: unit.Dp(14)}.Layout,
func(gtx layout.Context) layout.Dimensions { func(gtx layout.Context) layout.Dimensions {
lbl := material.Label(u.theme, unit.Sp(12), "Runtime") lbl := material.Label(u.theme, unit.Sp(12), "Version")
lbl.Color = mutedColor lbl.Color = mutedColor
return lbl.Layout(gtx) return lbl.Layout(gtx)
}, },
func(gtx layout.Context) layout.Dimensions { func(gtx layout.Context) layout.Dimensions {
lbl := material.Label(u.theme, unit.Sp(14), fmt.Sprintf("%s on %s/%s", runtime.Version(), runtime.GOOS, runtime.GOARCH)) lbl := material.Label(u.theme, unit.Sp(14), currentAppVersion())
lbl.Color = u.theme.Palette.Fg lbl.Color = u.theme.Palette.Fg
return lbl.Layout(gtx) return lbl.Layout(gtx)
}, },
+19
View File
@@ -5517,6 +5517,25 @@ func TestShowAboutSection(t *testing.T) {
} }
} }
func TestCurrentAppVersion(t *testing.T) {
t.Parallel()
previous := appVersion
t.Cleanup(func() {
appVersion = previous
})
appVersion = ""
if got := currentAppVersion(); got != "dev" {
t.Fatalf("currentAppVersion() with empty version = %q, want dev", got)
}
appVersion = " v0.0.1 "
if got := currentAppVersion(); got != "v0.0.1" {
t.Fatalf("currentAppVersion() with linker version = %q, want v0.0.1", got)
}
}
func TestUIAPIPolicyTargetActionsUseCurrentContext(t *testing.T) { func TestUIAPIPolicyTargetActionsUseCurrentContext(t *testing.T) {
t.Parallel() t.Parallel()
+3 -1
View File
@@ -45,7 +45,9 @@ build() {
cd "$(_repo_dir)" cd "$(_repo_dir)"
export CGO_ENABLED=1 export CGO_ENABLED=1
export GOFLAGS="-trimpath" export GOFLAGS="-trimpath"
go build -o keepassgo . local app_version
app_version="$(git describe --tags --always --dirty)"
go build -ldflags "-X main.appVersion=${app_version}" -o keepassgo .
} }
package() { package() {