[Feature/Medium] Release-driven versioning: About shows release tag, monotonic build number #189

Closed
opened 2026-09-15 12:46:42 +01:00 by gronod · 0 comments
Owner

Goal

Make the release tag the source of truth for app versioning:

  • About dialog "Version:" shows the release tag string with marketing version in parens — v2.0.0-pre2-grok (2.0.0); exact-release tag dedupes to v2.0.0; untagged/dev builds fall back to CFBundleShortVersionString.
  • "Build:" (CFBundleVersion / CURRENT_PROJECT_VERSION) becomes a monotonically increasing integer — git rev-list --count HEAD — per Apple TN2420 / macOS App Store convention (Mac build numbers must never reset across versions).
  • MARKETING_VERSION (CFBundleShortVersionString) stays strictly X.Y.Z and must equal the tag's numeric core — packaging hard-fails on mismatch.

Implementation

  • New scripts/version.sh: resolves ICCERY_RELEASE_TAG (RELEASE_TAG env matching v* else git describe --tags --always --dirty --match 'v[0-9]*'), MARKETING_VERSION (first 3 numeric components of tag core; 4-component tags like v2.0.0.0-x clamp), CURRENT_PROJECT_VERSION (BUILD_NUMBER env override else commit count). Emits KEY=value for eval.
  • project.yml: ICCERY_RELEASE_TAG build setting + a "Stamp release tag" post-build phase that writes it to a bundled Contents/Resources/ICCeryReleaseTag file. (A generated Info.plist cannot carry custom keys: INFOPLIST_KEY_* honours an Apple allowlist, and ProcessInfoPlistFile runs after script phases — the resource approach lands before CodeSign regardless.)
  • scripts/package-release.sh: eval "$(scripts/version.sh)", pass the three values as xcodebuild overrides, DMG named ICCery-<tag-sans-v>-<build>.dmg for tagged/described builds.
  • ArtefactFiles.appInfo(): compose display version from the bundled tag + CFBundleShortVersionString; displayVersion helper + new AppInfoTests.
  • CI (.gitea/workflows/macos.yml + .github/workflows/macos.yml twins): fetch-depth: 0 (shallow checkout breaks git describe/rev-list), RELEASE_TAG: ${{ github.ref_name }} job env, version overrides stamped into build-for-testing.
  • Docs: README release section, PREUAT DMG name, AGENTS.md, docs/21 About row.

Acceptance

  • Tag build v2.0.0-preN → About shows v2.0.0-preN (2.0.0), DMG ICCery-2.0.0-preN-<build>.dmg.
  • RELEASE_TAG=v9.9.9 while project.yml says 2.0.0 → packaging fails with clear error.
  • xcodebuild test -scheme ICCery green incl. new AppInfoTests.
  • develop push and v* tag push both produce stamped DMGs on Gitea + GitHub.
## Goal Make the release **tag** the source of truth for app versioning: - About dialog "Version:" shows the release tag string with marketing version in parens — `v2.0.0-pre2-grok (2.0.0)`; exact-release tag dedupes to `v2.0.0`; untagged/dev builds fall back to `CFBundleShortVersionString`. - "Build:" (`CFBundleVersion` / `CURRENT_PROJECT_VERSION`) becomes a monotonically increasing integer — `git rev-list --count HEAD` — per Apple TN2420 / macOS App Store convention (Mac build numbers must never reset across versions). - `MARKETING_VERSION` (`CFBundleShortVersionString`) stays strictly `X.Y.Z` and must equal the tag's numeric core — packaging hard-fails on mismatch. ## Implementation - New `scripts/version.sh`: resolves `ICCERY_RELEASE_TAG` (`RELEASE_TAG` env matching `v*` else `git describe --tags --always --dirty --match 'v[0-9]*'`), `MARKETING_VERSION` (first 3 numeric components of tag core; 4-component tags like `v2.0.0.0-x` clamp), `CURRENT_PROJECT_VERSION` (`BUILD_NUMBER` env override else commit count). Emits `KEY=value` for `eval`. - `project.yml`: `ICCERY_RELEASE_TAG` build setting + a "Stamp release tag" post-build phase that writes it to a bundled `Contents/Resources/ICCeryReleaseTag` file. (A generated Info.plist cannot carry custom keys: `INFOPLIST_KEY_*` honours an Apple allowlist, and `ProcessInfoPlistFile` runs after script phases — the resource approach lands before CodeSign regardless.) - `scripts/package-release.sh`: `eval "$(scripts/version.sh)"`, pass the three values as `xcodebuild` overrides, DMG named `ICCery-<tag-sans-v>-<build>.dmg` for tagged/described builds. - `ArtefactFiles.appInfo()`: compose display version from the bundled tag + `CFBundleShortVersionString`; `displayVersion` helper + new `AppInfoTests`. - CI (`.gitea/workflows/macos.yml` + `.github/workflows/macos.yml` twins): `fetch-depth: 0` (shallow checkout breaks `git describe`/`rev-list`), `RELEASE_TAG: ${{ github.ref_name }}` job env, version overrides stamped into `build-for-testing`. - Docs: README release section, PREUAT DMG name, AGENTS.md, docs/21 About row. ## Acceptance - Tag build `v2.0.0-preN` → About shows `v2.0.0-preN (2.0.0)`, DMG `ICCery-2.0.0-preN-<build>.dmg`. - `RELEASE_TAG=v9.9.9` while project.yml says `2.0.0` → packaging fails with clear error. - `xcodebuild test -scheme ICCery` green incl. new `AppInfoTests`. - `develop` push and `v*` tag push both produce stamped DMGs on Gitea + GitHub.
gronod added the Kind/Feature
Priority
Medium
3
Project/ICCery-v2Feature/DevOps
labels 2026-09-15 12:46:42 +01:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: gronod/iccery-v2-mac#189