Skip to content

fix(macos): stamp app version from git release tag - #223

Open
xavierforge wants to merge 1 commit into
omacom:mainfrom
xavierforge:fix/stamp-app-version
Open

xavierforge wants to merge 1 commit into
omacom:mainfrom
xavierforge:fix/stamp-app-version

Conversation

@xavierforge

@xavierforge xavierforge commented Sep 17, 2026

Copy link
Copy Markdown

Summary

  • Stamp CFBundleShortVersionString, CFBundleVersion and a new TryOmarchyBuildDescribe key into the built Info.plist from git, right before codesign.
  • Add a version-preflight target that package and release depend on: the worktree must be clean (untracked files included) and HEAD must carry an exact vX.Y.Z tag.

Problem

macos/Info.plist has carried CFBundleShortVersionString = 0.4.0 and CFBundleVersion = 5 unchanged since a469b7e (2026-08-24), and build-app.sh installs it verbatim. Every tagged release from v0.1.0 to v0.4.1 therefore reports the same version:

for t in v0.1.0 v0.2.0 v0.3.0 v0.4.0 v0.4.1; do
  printf '%-7s ' "$t"; git show "$t:macos/Info.plist" | grep -A1 CFBundleShortVersionString | tail -1
done
# every line: <string>0.4.0</string>

Users cannot tell which release they installed, and a version quoted in an issue cannot be trusted. #211 is titled "v0.4.0: every launch fails ... v0.3.0 fine", but a v0.3.0 build also shows 0.4.0 in Finder. I hit the same thing: Finder said 0.4.0, the bundle was actually built at the v0.3.0 tag time, and I assumed the guest already contained #172.

Fix

macos/build-app.sh, after the Info.plist install and before codesign:

Checkout state CFBundleShortVersionString CFBundleVersion TryOmarchyBuildDescribe
clean, HEAD at exact vX.Y.Z tag X.Y.Z git rev-list --count HEAD vX.Y.Z
any other git state (no tag, past tag, dirty) 0.0.0 commit count e.g. v0.4.1-2-g4a8ccab-dirty
not a git checkout checked-in plist kept kept absent, warning on stderr

0.0.0 for non-release builds follows Apple's three-integer format for CFBundleShortVersionString while making sure a development build never presents itself as a release; the full git describe output stays readable with plutil -p or mdls.

Makefile: version-preflight runs git status --porcelain --untracked-files=all and git describe --tags --exact-match --match 'v[0-9]*', and both package-preflight and release-preflight depend on it. Ignored build output (dist/, .build/, guest/.work/) does not count as dirty.

Scope

  • This identifies the .app build only. It does not identify which factory image seeded an already-provisioned VM disk; that identity lives in the host-side persistent-disk metadata.json (bundleIdentity, sourceRootfs.sha256) and is not touched here.
  • Already-published DMGs are not corrected retroactively.
  • No supply-chain pins, guest/spec.json, or guest provenance are changed.

Test plan

  • make test on macOS 26.6.2 (arm64): all suites pass, including swift test and qemu-persistent-storage.test
  • make version-preflight on a clean untagged HEAD: rejected with HEAD must carry an exact vX.Y.Z release tag
  • make version-preflight at a local v9.9.9 tag: passes
  • make version-preflight with an untracked file present: rejected with the worktree must be clean before building a signed app
  • plist rewrite block run standalone with macOS python3 at the v9.9.9 tag: plutil -lint OK, 9.9.9 / 316 / v9.9.9
  • Same block against a throwaway git repo (Linux): no tag, exact tag, past tag, dirty tracked file, non-semver tag v1foo, and no .git all produce the values in the table above
  • version-preflight against a throwaway repo: non-semver tag rejected, modified tracked file rejected, ignored dist/ and .build/ contents accepted
  • Full make app and codesign --verify --deep --strict on the produced bundle. Not run: make guest on current main fails to resolve the factory transaction against Arch Linux ARM (hyprland 0.56.2-3 now requires libaquamarine.so=14, the pinned aquamarine 0.14.0-2 provides .so=13); see the 2026-09-17 comment on [fix] Refresh the factory lock for available ARM packages #192. The plist rewrite was verified standalone with macOS python3 instead.

Info.plist has shipped CFBundleShortVersionString 0.4.0 and CFBundleVersion 5
unchanged since a469b7e, so every release from v0.1.0 to v0.4.1 reports the
same version in Finder. Users cannot tell which release they installed, and
issue reports naming a version cannot be trusted.

build-app.sh now rewrites the installed Info.plist from git before codesign:
a clean checkout at an exact vX.Y.Z tag gets that version, anything else gets
0.0.0 so a development build never claims a release number, CFBundleVersion is
the commit count, and TryOmarchyBuildDescribe keeps the full git describe
output. Without a git checkout the checked-in plist is kept and a warning is
printed.

The package and release targets now require a clean worktree (including
untracked files) and an exact vX.Y.Z tag on HEAD, so a signed DMG cannot be
produced with a stale or development version again.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant