Compare commits

..
Author SHA1 Message Date
gronod 2a8ad4d5d4 fix(ci): cap pip below 26.1 in the Python 3.9 dmgbuild venv
macOS CI / build-and-test (push) Successful in 11s
macOS CI / package (push) Successful in 4m5s
macOS CI / package (pull_request) Canceled after 0s
macOS CI / build-and-test (pull_request) Canceled after 3m29s
Unbounded pip upgrade installed 26.2.1, which uses
dataclass(slots=True) and crashes on Monterey 3.9. Recreate
the venv if pip is already broken, then pin pip>=24.3,<26.1
before force-installing dmgbuild 1.6.7.
2026-09-14 10:34:16 +00:00
gronod c2ac9341c8 fix(ci): force dmgbuild 1.6.7 into the package venv
macOS CI / package (pull_request) Canceled after 0s
macOS CI / build-and-test (pull_request) Canceled after 1m6s
macOS CI / build-and-test (push) Successful in 11s
macOS CI / package (push) Failing after 35s
Python 3.9 hides 1.6.6+ (Requires-Python >=3.10), so
dmgbuild>=1.6.5 left a cached 1.6.5 install. The wheels are
py3-none-any; install 1.6.7 with PIP_IGNORE_REQUIRES_PYTHON,
force-reinstall ds_store>=1.3.3 and mac_alias>=2.2.3, and fail
if the venv is still older than 1.6.7.
2026-09-14 10:29:33 +00:00
gronod 1c310706e4 fix(ci): isolate dmgbuild in a venv, skip it on the test job
macOS CI / package (pull_request) Canceled after 0s
macOS CI / build-and-test (pull_request) Canceled after 1m50s
macOS CI / build-and-test (push) Successful in 13s
macOS CI / package (push) Successful in 4m12s
ensure-host-tools.sh always bootstraps xcodegen. dmgbuild now
lives in build/.venv-dmgbuild and is only installed when
INSTALL_DMGBUILD=1 (package job). The test job no longer
pip-installs dmgbuild, which is what failed on Python 3.9.

package-release.sh reuses that venv (or bootstraps it locally)
instead of creating a second copy.
2026-09-14 10:22:09 +00:00
gronod 7f6c47d85c fix(ci): do not require dmgbuild 1.6.7 on Monterey Python 3.9
macOS CI / package (pull_request) Canceled after 0s
macOS CI / build-and-test (pull_request) Canceled after 6m31s
The tools step runs on the test job. System Python is 3.9;
dmgbuild 1.6.6+ declares Requires-Python >=3.10, so pip only
lists 1.6.5 and the 1.6.7 floor failed the gate.

Install the newest wheel this interpreter accepts. Keep the
HiDPI TIFF background path and the hard-fail if art is missing.
2026-09-14 10:14:29 +00:00
gronod 3b6323378e fix(packaging): DMG background visible on Sonoma+ (#95)
macOS CI / build-and-test (pull_request) Failing after 20s
macOS CI / package (pull_request) Skipped
Pin dmgbuild >= 1.6.7 so Finder gets a bookmark instead of a
Monterey-era Alias Manager blob. Feed a HiDPI TIFF from
tiffutil rather than the 1x RGBA PNG, and fail the package job
if the art is missing instead of shipping a grey window.

Exclude installer chrome from the app bundle; it is not an
in-app asset.
2026-09-14 09:57:37 +00:00
gronod ad7b91cf91 Merge pull request 'fix(ui): settings sheet — ΔE clip + duplicated numeric-field labels (#165)' (#166) from fix/165-settings-deltae-clip into develop
macOS CI / package (push) Successful in 4m48s
macOS CI / build-and-test (push) Successful in 43m0s
Reviewed-on: #166
2026-09-14 07:56:58 +01:00
6 changed files with 119 additions and 25 deletions
+5 -2
View File
@@ -35,7 +35,8 @@ jobs:
# The job still succeeds quickly so `package`'s `needs:` stays satisfied.
# Homebrew's xcodegen formula requires Xcode 15.3, which cannot be
# installed on macOS 12 (#109). The script installs a pinned
# prebuilt release instead.
# prebuilt release instead. dmgbuild is not installed here — the
# test job does not package (#95).
- name: Ensure host tools
if: "!(startsWith(github.ref, 'refs/tags/') && contains(github.ref_name, 'prerelease'))"
run: scripts/ensure-host-tools.sh
@@ -193,8 +194,10 @@ jobs:
# scripts/package-release.sh runs `xcodegen generate` and dmgbuild;
# see build-and-test for why brew is not used on macOS 12 (#109).
# INSTALL_DMGBUILD isolates dmgbuild in build/.venv-dmgbuild so
# the test job never pip-installs it (#95).
- name: Ensure host tools
run: scripts/ensure-host-tools.sh
run: INSTALL_DMGBUILD=1 scripts/ensure-host-tools.sh
- name: Package release
run: scripts/package-release.sh
+1 -1
View File
@@ -25,7 +25,7 @@ Cone-only mark for window/taskbar. Raster set:
| File | Use |
|------|-----|
| `icons/dmg-background.png` (+ `@2x`, `.svg`) | macOS DMG window (ice cream / wordmark scene). Headless `dmgbuild` after #189 |
| `Resources/dmg-background.png` (+ `@2x`; source `brand/dmg-background.svg`) | macOS DMG window. `scripts/package-release.sh` builds a HiDPI TIFF and passes it to `dmgbuild==1.6.7` from `build/.venv-dmgbuild` (created by `INSTALL_DMGBUILD=1 scripts/ensure-host-tools.sh`). Monterey Python 3.9 needs `PIP_IGNORE_REQUIRES_PYTHON=1` or pip will keep 1.6.5. Missing art is a hard fail (#95, #189). |
| `icons/wix-banner.bmp`, `wix-dialog.bmp` | MSI |
| `icons/nsis-header.bmp`, `nsis-sidebar.bmp` | NSIS |
+2
View File
@@ -21,6 +21,8 @@ targets:
- ICCery.entitlements
- ICCery.Debug.entitlements
- Argyll
- dmg-background.png
- dmg-background@2x.png
- path: Resources/Argyll
type: folder
dependencies:
+17 -9
View File
@@ -1,10 +1,10 @@
#!/usr/bin/env python3
# scripts/dmgbuild-settings.py
#
# dmgbuild settings for ICCery. Set DMG_APP, DMG_FILENAME and DMG_VOLUME_NAME
# in the environment, or accept the defaults. Background art can be supplied
# later by placing a PNG at Resources/dmg-background.png and setting
# DMG_BACKGROUND.
# dmgbuild settings for ICCery. scripts/package-release.sh exports
# DMG_APP, DMG_FILENAME, DMG_VOLUME_NAME, and DMG_BACKGROUND (a
# HiDPI TIFF). A missing background is a hard error — a grey
# Finder window is not an acceptable release artefact (#95).
import os
import sys
@@ -23,15 +23,23 @@ if not app_path or not app_path.endswith('.app') or not os.path.isdir(app_path):
files = [app_path]
# Background art is optional. If the referenced PNG does not exist, fall back
# to a plain window. See docs/23-assets.md for the DMG background spec.
background = os.environ.get('DMG_BACKGROUND', 'Resources/dmg-background.png')
if background and not os.path.exists(background):
background = None
# Finder on Sonoma+ is picky about PNG-with-alpha window pictures and
# about classic Alias Manager blobs. package-release.sh always passes
# a flattened HiDPI TIFF as DMG_BACKGROUND. dmgbuild 1.6.7 (bookmark
# .DS_Store) needs Python >= 3.10, which the Monterey runner does not
# have; 1.6.5 + TIFF is what CI can ship (#95).
background = os.environ.get('DMG_BACKGROUND', '')
if not background or not os.path.isfile(background):
sys.stderr.write(
'error: DMG_BACKGROUND must point at an existing image '
'(got %r)\n' % background)
sys.exit(1)
icon = None
# Window size is enough for the app icon and the Applications alias.
# Bitmap is slightly larger than this rect so title-bar chrome on
# 14+ does not crop the wordmark.
window_rect = ((100, 100), (660, 400))
# Use icon view without extra chrome.
+66 -6
View File
@@ -2,19 +2,79 @@
# scripts/ensure-host-tools.sh
#
# Bootstrap host tools needed by CI on the macOS 12 runner:
# - xcodegen: pinned prebuilt release from GitHub (Homebrew's current
# formula requires Xcode 15.3, which cannot be installed on macOS 12).
# - dmgbuild: via pip3 (used by scripts/package-release.sh).
# - xcodegen: always. Pinned prebuilt release from GitHub (Homebrew's
# current formula requires Xcode 15.3, which cannot be installed on
# macOS 12).
# - dmgbuild: only when INSTALL_DMGBUILD=1 or --dmgbuild. Isolated in
# build/.venv-dmgbuild so the test job never pip-installs it.
#
# Safe to run repeatedly: existing tools are left alone.
# dmgbuild 1.6.6+, ds_store 1.3.2+ and mac_alias 2.2.3 declare
# Requires-Python >= 3.10. The wheels are py3-none-any and run on the
# runner's 3.9; PIP_IGNORE_REQUIRES_PYTHON is required or pip will only
# offer 1.6.5 and keep a cached venv on that version (#95).
# pip itself is capped at <26.1: 26.1+ needs Python 3.10.
#
# Safe to run repeatedly: existing tools are left alone unless the
# dmgbuild pin is not met.
set -eu
ROOT="$(CDPATH='' cd -- "$(dirname -- "$0")/.." && pwd)"
XCODEGEN_VERSION="2.38.0"
INSTALL_ROOT="${XCODEGEN_HOME:-$HOME/.local/xcodegen/$XCODEGEN_VERSION}"
VENV="$ROOT/build/.venv-dmgbuild"
DMGBUILD_PIN="1.6.7"
echo "==> Ensuring dmgbuild"
python3 -c "import dmgbuild" 2>/dev/null || pip3 install dmgbuild
INSTALL_DMGBUILD="${INSTALL_DMGBUILD:-0}"
for arg in "$@"; do
case "$arg" in
--dmgbuild) INSTALL_DMGBUILD=1 ;;
esac
done
if [ "$INSTALL_DMGBUILD" = "1" ]; then
echo "==> Ensuring dmgbuild==$DMGBUILD_PIN in $VENV"
mkdir -p "$ROOT/build"
# pip 26.1+ requires Python 3.10 (dataclass slots). A leftover
# `pip install --upgrade pip` on this 3.9 venv installed 26.2.1 and
# the next pip invocation crashed. Recreate if pip is already dead.
if [ -x "$VENV/bin/python" ] \
&& ! "$VENV/bin/python" -m pip --version >/dev/null 2>&1; then
echo "==> venv pip is broken; recreating $VENV"
rm -rf "$VENV"
fi
if [ ! -x "$VENV/bin/python" ]; then
python3 -m venv "$VENV"
fi
# Without this, pip on Python 3.9 hides 1.6.6+ and leaves 1.6.5.
PIP_IGNORE_REQUIRES_PYTHON=1
export PIP_IGNORE_REQUIRES_PYTHON
"$VENV/bin/python" -m pip install --upgrade 'pip>=24.3,<26.1'
"$VENV/bin/python" -m pip install --upgrade --force-reinstall \
"dmgbuild==$DMGBUILD_PIN" \
'ds_store>=1.3.3' \
'mac_alias>=2.2.3'
"$VENV/bin/python" -c 'from importlib.metadata import version
print("dmgbuild", version("dmgbuild"))
print("ds_store", version("ds_store"))
print("mac_alias", version("mac_alias"))
parts=[]
for p in version("dmgbuild").split("."):
try:
parts.append(int("".join(c for c in p if c.isdigit()) or "0"))
except ValueError:
parts.append(0)
parts += [0, 0, 0]
raise SystemExit(0 if tuple(parts[:3]) >= (1, 6, 7) else 1)
'
if [ -n "${GITHUB_PATH:-}" ]; then
echo "$VENV/bin" >> "$GITHUB_PATH"
fi
PATH="$VENV/bin:$PATH"
export PATH
else
echo "==> Skipping dmgbuild (set INSTALL_DMGBUILD=1 for the package job)"
fi
if command -v xcodegen >/dev/null 2>&1; then
echo "==> xcodegen already on PATH: $(xcodegen --version)"
+28 -7
View File
@@ -103,19 +103,39 @@ EOF
scripts/verify-sidecar-signatures.sh "$APP"
fi
echo "==> Installing / locating dmgbuild"
echo "==> Locating dmgbuild"
# The package CI job already ran INSTALL_DMGBUILD=1 ensure-host-tools.sh,
# which created build/.venv-dmgbuild and prepended it to PATH. Local
# runs bootstrap the same venv if dmgbuild is missing.
VENV="$ROOT/build/.venv-dmgbuild"
if ! command -v dmgbuild >/dev/null 2>&1; then
VENV="$ROOT/build/.venv-dmgbuild"
if [ ! -d "$VENV/bin" ]; then
python3 -m venv "$VENV"
"$VENV/bin/pip" install --upgrade pip
"$VENV/bin/pip" install dmgbuild
if [ ! -x "$VENV/bin/dmgbuild" ]; then
INSTALL_DMGBUILD=1 "$ROOT/scripts/ensure-host-tools.sh" --dmgbuild
fi
PATH="$VENV/bin:$PATH"
export PATH
fi
if ! command -v dmgbuild >/dev/null 2>&1; then
echo "error: dmgbuild not available. Try 'python3 -m venv .venv && pip install dmgbuild'" >&2
echo "error: dmgbuild not on PATH; run INSTALL_DMGBUILD=1 scripts/ensure-host-tools.sh" >&2
exit 1
fi
echo "dmgbuild $(command -v dmgbuild)"
if [ -x "$VENV/bin/python" ]; then
"$VENV/bin/python" -c 'from importlib.metadata import version; print("dmgbuild", version("dmgbuild"))'
fi
PNG1X="$ROOT/Resources/dmg-background.png"
PNG2X="$ROOT/Resources/dmg-background@2x.png"
if [ ! -f "$PNG1X" ] || [ ! -f "$PNG2X" ]; then
echo "error: missing $PNG1X or $PNG2X" >&2
exit 1
fi
mkdir -p "$ROOT/build"
DMG_BACKGROUND="$ROOT/build/dmg-background.tiff"
echo "==> Building HiDPI DMG background TIFF"
tiffutil -cathidpicheck "$PNG1X" "$PNG2X" -out "$DMG_BACKGROUND"
if [ ! -f "$DMG_BACKGROUND" ]; then
echo "error: tiffutil did not write $DMG_BACKGROUND" >&2
exit 1
fi
@@ -128,6 +148,7 @@ VOLUME_NAME="ICCery ${VERSION}"
DMG_APP="$APP" \
DMG_FILENAME="$DMG" \
DMG_VOLUME_NAME="$VOLUME_NAME" \
DMG_BACKGROUND="$DMG_BACKGROUND" \
dmgbuild -s scripts/dmgbuild-settings.py "$VOLUME_NAME" "$DMG"
echo "DMG: $PWD/$DMG"