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
65 changes: 21 additions & 44 deletions codemagic.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1471,35 +1471,23 @@ workflows:

xcrun stapler staple "$APP_PATH"

- name: Install create-dmg
script: |
brew install create-dmg

- name: Create DMG installer
script: |
set -e
pip3 install --break-system-packages dmgbuild
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Unversioned dmgbuild install

pip3 install --break-system-packages dmgbuild installs the latest available release on every build with no version pin. A breaking change in a future dmgbuild release could silently corrupt the DMG layout or fail the build. Consider pinning to a known-good version:

Suggested change
pip3 install --break-system-packages dmgbuild
pip3 install --break-system-packages "dmgbuild==1.6.1"

The same applies to the second workflow's identical install line (line 2289).

APP_PATH=$(find $(pwd)/build/macos -name "Omi.app" -type d | head -1)

mkdir -p build/macos/dmg
DMG_NAME="Omi.dmg"
DMG_PATH="build/macos/dmg/${DMG_NAME}"

# Create professional DMG with Applications folder shortcut
# Use --skip-jenkins to avoid AppleScript timeout issues in CI
create-dmg \
--volname "Omi ${VERSION}" \
--volicon "$APP_PATH/Contents/Resources/prodAppIcon.icns" \
--window-pos 200 120 \
--window-size 660 400 \
--icon-size 130 \
--text-size 16 \
--icon "Omi.app" 180 180 \
--hide-extension "Omi.app" \
--app-drop-link 480 180 \
--no-internet-enable \
--skip-jenkins \
"$DMG_PATH" \
"$APP_PATH"
DMG_PATH="build/macos/dmg/Omi.dmg"

# Use dmgbuild instead of create-dmg — writes .DS_Store directly
# without Finder/AppleScript (which hangs in CI with --skip-jenkins)
dmgbuild -s ../desktop/dmg-assets/dmgbuild_settings.py \
-D app_path="$APP_PATH" \
-D app_name=Omi \
-D assets_dir="$(pwd)/../desktop/dmg-assets" \
"Omi ${VERSION}" \
"$DMG_PATH"

# Sign DMG
codesign --force --sign "$DEVELOPER_ID_CERT" "$DMG_PATH"
Expand Down Expand Up @@ -2295,13 +2283,11 @@ workflows:
xcrun stapler staple "$APP_BUNDLE"
echo "App stapled"

- name: Install create-dmg
script: |
brew install create-dmg || true

- name: Create DMG installer
script: |
set -e
pip3 install --break-system-packages dmgbuild

STAGING_DIR="/tmp/omi-dmg-staging-$$"
mkdir -p "$STAGING_DIR"
# Use ditto to preserve the notarization staple ticket (cp -R drops it)
Expand All @@ -2310,23 +2296,14 @@ workflows:
xcrun stapler validate "$STAGING_DIR/$APP_NAME.app" 2>/dev/null || \
xcrun stapler staple "$STAGING_DIR/$APP_NAME.app"

BG_ARGS=""
[ -f "dmg-assets/background.png" ] && BG_ARGS="--background dmg-assets/background.png"

create-dmg \
--volname "$APP_NAME" \
--volicon "$STAGING_DIR/$APP_NAME.app/Contents/Resources/OmiIcon.icns" \
--window-pos 200 120 \
--window-size 610 365 \
--icon-size 80 \
--icon "$APP_NAME.app" 155 175 \
--hide-extension "$APP_NAME.app" \
--app-drop-link 455 175 \
--no-internet-enable \
--skip-jenkins \
$BG_ARGS \
"$DMG_PATH" \
"$STAGING_DIR/$APP_NAME.app"
# Use dmgbuild instead of create-dmg — writes .DS_Store directly
# without Finder/AppleScript (which hangs in CI with --skip-jenkins)
dmgbuild -s dmg-assets/dmgbuild_settings.py \
-D app_path="$STAGING_DIR/$APP_NAME.app" \
-D app_name="$APP_NAME" \
-D assets_dir="$(pwd)/dmg-assets" \
"$APP_NAME" \
"$DMG_PATH"

rm -rf "$STAGING_DIR"
echo "DMG created"
Expand Down
Binary file modified desktop/dmg-assets/background.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
51 changes: 51 additions & 0 deletions desktop/dmg-assets/dmgbuild_settings.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# dmgbuild settings for OMI Desktop installer
# Usage: dmgbuild -s dmgbuild_settings.py -D app_path=/path/to/Omi.app -D app_name=omi "Omi" output.dmg
#
# This replaces create-dmg + AppleScript (which fails in CI due to --skip-jenkins).
# dmgbuild writes .DS_Store directly — no Finder/AppleScript needed.

import os

app_path = defines.get("app_path", "Omi.app")
app_name = defines.get("app_name", "omi")
# __file__ is not set when executed by dmgbuild; use defines or fall back to cwd
_script_dir = defines.get("assets_dir", os.path.join(os.getcwd(), "dmg-assets"))
bg_path = defines.get("background", os.path.join(_script_dir, "background.png"))
icon_path = defines.get("volume_icon", None)

# Volume settings
format = "UDBZ" # bzip2 compressed
size = None # auto-calculate
filesystem = "HFS+"

# Files to include
files = [app_path]
symlinks = {"Applications": "/Applications"}

# Window settings
background = bg_path
show_status_bar = False
show_tab_view = False
show_toolbar = False
show_pathbar = False
show_sidebar = False
sidebar_width = 0

window_rect = ((200, 120), (610, 365))
default_view = "icon-view"

icon_size = 80
text_size = 12

# Icon positions — must match background.png arrow (left=app, right=Applications)
icon_locations = {
app_name + ".app": (155, 175),
"Applications": (455, 175),
}

# Hide extension for the app
hide_extensions = [app_name + ".app"]

# Volume icon
if icon_path:
badge_icon = icon_path
Comment on lines +50 to +51
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 badge_icon should be icon for volume icon

badge_icon composites the supplied image onto the standard macOS folder icon (like a badge). To replicate what create-dmg --volicon did (replace the volume icon entirely with the .icns file), the correct dmgbuild variable is icon:

Suggested change
if icon_path:
badge_icon = icon_path
if icon_path:
icon = icon_path

This code path is currently dormant — neither workflow passes -D volume_icon=... — so it won't break CI today, but if someone later enables it they'll get a badged folder instead of the app icon as the volume icon.

Loading