Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .github/workflows/build-dmg.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,15 @@ jobs:
uses: actions/checkout@v4
with:
submodules: recursive
fetch-depth: 0 # Full history — needed for `git rev-list --count HEAD` (build number)

- name: Generate Xcode Project
run: |
# See generate_xcodeproj.py's header comment: without these, every
# build reports the same hardcoded 1.0/1 app version. Matches
# release.yml's scheme so ad-hoc and release builds are consistent.
export SWIFTBUDDY_MARKETING_VERSION="$(date -u +%Y.%m.%d)"
export SWIFTBUDDY_BUILD_NUMBER="$(git rev-list --count HEAD)"
cd SwiftBuddy && python3 generate_xcodeproj.py

- name: Build Ad-Hoc App
Expand Down
13 changes: 12 additions & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,17 @@ jobs:

- name: Build macOS DMG Wrapper
run: |
# Previously hardcoded 1.0/1 inside generate_xcodeproj.py, so every
# release ever built reported the same app version regardless of
# which commit produced it. SWIFTBUDDY_BUILD_NUMBER reuses the same
# `git rev-list --count HEAD` counter this workflow's bNNN release
# tags already use (step "Determine tag name" above), so the app's
# build number and its release tag always agree. Marketing version
# is date-based (always distinct, no manual "when do we bump this"
# decision needed for a pipeline that releases roughly daily).
export SWIFTBUDDY_MARKETING_VERSION="$(date -u +%Y.%m.%d)"
export SWIFTBUDDY_BUILD_NUMBER="$(git rev-list --count HEAD)"
echo "App version: ${SWIFTBUDDY_MARKETING_VERSION} (${SWIFTBUDDY_BUILD_NUMBER})"
cd SwiftBuddy && python3 generate_xcodeproj.py
cd ..
xcodebuild clean build \
Expand Down Expand Up @@ -187,7 +198,7 @@ jobs:
### Download

- **CLI Server**: [macOS Apple Silicon (arm64)](https://github.com/SharpAI/SwiftLM/releases/download/${{ steps.tag.outputs.name }}/SwiftLM-${{ steps.tag.outputs.name }}-macos-arm64.tar.gz)
- **GUI Desktop App**: Download the attached `SwiftBuddy-macOS.dmg` below!
- **GUI Desktop App**: Download the attached DMG file below!

### Quick Start

Expand Down
25 changes: 21 additions & 4 deletions SwiftBuddy/generate_xcodeproj.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,20 @@
Includes MLXInferenceCore sources directly + local SPM packages (mlx-swift, mlx-swift-lm).
Run from the SwiftBuddy/ directory:
python3 generate_xcodeproj.py

Since this script (not a checked-in Info.plist) regenerates project.pbxproj
fresh on every build, it's also the single place that controls the app's
displayed version — MARKETING_VERSION (CFBundleShortVersionString) and
CURRENT_PROJECT_VERSION (CFBundleVersion) were previously hardcoded to
"1.0"/"1" here, so every release ever built reported the same version
regardless of which commit or CI run produced it. Override either via env
var; both default to the previous hardcoded values for local/manual runs
where CI hasn't set them:
SWIFTBUDDY_MARKETING_VERSION e.g. "2026.08.27" (release.yml sets this
to the build date — see that workflow)
SWIFTBUDDY_BUILD_NUMBER e.g. "703" (release.yml sets this to
`git rev-list --count HEAD`, the same
counter its bNNN release tags use)
"""

import os, uuid
Expand All @@ -12,6 +26,9 @@
def uid():
return uuid.uuid4().hex[:24].upper()

MARKETING_VERSION = os.environ.get("SWIFTBUDDY_MARKETING_VERSION", "1.0")
BUILD_NUMBER = os.environ.get("SWIFTBUDDY_BUILD_NUMBER", "1")

# ── UUIDs ─────────────────────────────────────────────────────────────
PROJ = uid()
MAIN_GRP = uid()
Expand Down Expand Up @@ -343,7 +360,7 @@ def pbxproj():
\t\t\t\tASSTCATALOG_COMPILER_APPICON_NAME = AppIcon;
\t\t\t\tASSTCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
\t\t\t\tCODE_SIGN_STYLE = Automatic;
\t\t\t\tCURRENT_PROJECT_VERSION = 1;
\t\t\t\tCURRENT_PROJECT_VERSION = {BUILD_NUMBER};
\t\t\t\tGENERATE_INFOPLIST_FILE = YES;
\t\t\t\tINFOPLIST_KEY_CFBundleDisplayName = "SwiftBuddy Chat";
\t\t\t\tINFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2026 SharpAI";
Expand All @@ -354,7 +371,7 @@ def pbxproj():
\t\t\t\tINFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 17.0;
\t\t\t\tMACOS_DEPLOYMENT_TARGET = 14.0;
\t\t\t\tMARKETING_VERSION = 1.0;
\t\t\t\tMARKETING_VERSION = {MARKETING_VERSION};
\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = com.sharpai.SwiftBuddy;
\t\t\t\tPRODUCT_NAME = "$(TARGET_NAME)";
\t\t\t\tSDKROOT = auto;
Expand All @@ -371,12 +388,12 @@ def pbxproj():
\t\t\t\tASSTCATALOG_COMPILER_APPICON_NAME = AppIcon;
\t\t\t\tASSTCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
\t\t\t\tCODE_SIGN_STYLE = Automatic;
\t\t\t\tCURRENT_PROJECT_VERSION = 1;
\t\t\t\tCURRENT_PROJECT_VERSION = {BUILD_NUMBER};
\t\t\t\tGENERATE_INFOPLIST_FILE = YES;
\t\t\t\tINFOPLIST_KEY_CFBundleDisplayName = "SwiftBuddy Chat";
\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 17.0;
\t\t\t\tMACOS_DEPLOYMENT_TARGET = 14.0;
\t\t\t\tMARKETING_VERSION = 1.0;
\t\t\t\tMARKETING_VERSION = {MARKETING_VERSION};
\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = com.sharpai.SwiftBuddy;
\t\t\t\tPRODUCT_NAME = "$(TARGET_NAME)";
\t\t\t\tSDKROOT = auto;
Expand Down
Loading