feat: package macOS builds as DMG and fix release workflow#5
Conversation
- Add build_dmg.sh: runs macdeployqt, resolves Frameworks symlinks, ad-hoc signs, and creates a DMG via hdiutil. Default mode packages filterGenerator.app and filterRuleTest.app from ./build/ with full Qt deploy. Single-app mode (--app-path/--output) is used by CI. - Update macos-build.yml: replace tar.gz with DMG via build_dmg.sh for both arm64 and x86_64 jobs (macdeployqt step retained before). - Update release.yml: add draft:false so releases publish immediately; add artifacts/**/*.dmg glob so macOS DMGs attach to Release page. - Add tools/README.md: deprecation notice pointing to Releases page. - Update README.md: add CI status badges for Release/macOS/Linux/Windows.
There was a problem hiding this comment.
Pull request overview
This PR improves the macOS release/distribution pipeline by switching macOS artifacts from .tar.gz bundles to .dmg images, and updates the release workflow so macOS DMGs are attached to GitHub Releases. It also adds documentation and CI badges to better direct users to official downloads.
Changes:
- Add
build_dmg.shto package.appbundles into.dmgfiles (with optional deploy/sign behavior). - Update macOS build workflow to upload DMG artifacts instead of tarballs; update release workflow to include
**/*.dmgin release assets. - Add
tools/README.mddeprecation notice and add CI workflow badges toREADME.md.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
build_dmg.sh |
New macOS DMG packaging script intended for local use and CI single-app packaging. |
.github/workflows/macos-build.yml |
Switch macOS CI packaging/upload from .tar.gz to .dmg via build_dmg.sh. |
.github/workflows/release.yml |
Publish releases non-draft and attach .dmg artifacts to GitHub Releases. |
tools/README.md |
New deprecation notice pointing users to GitHub Releases for binaries. |
README.md |
Add workflow status badges. |
| _REAL="$(realpath "$_F")" | ||
| rm "$_F" |
There was a problem hiding this comment.
resolve_frameworks_symlinks calls realpath under set -e, so if a Frameworks/ symlink is broken (the situation this function is meant to fix), realpath will exit non-zero and abort the entire script before the symlink can be replaced. Handle realpath failure explicitly (e.g., conditional + warning + continue, or use readlink and validate existence) so broken symlinks don’t hard-fail packaging.
| _REAL="$(realpath "$_F")" | |
| rm "$_F" | |
| if ! _REAL="$(realpath "$_F" 2>/dev/null)"; then | |
| echo " warning: failed to resolve symlink $(basename "$_F"); leaving as-is" >&2 | |
| continue | |
| fi | |
| if [[ ! -e "$_REAL" ]]; then | |
| echo " warning: target of symlink $(basename "$_F") does not exist: $_REAL" >&2 | |
| continue | |
| fi | |
| rm -f "$_F" |
| echo "→ macdeployqt: $_APP" | ||
| "$_QDEPLOY" "$_APP" -verbose=1 | ||
|
|
||
| echo " Resolving Frameworks symlinks..." | ||
| resolve_frameworks_symlinks "$_APP" | ||
| } |
There was a problem hiding this comment.
In single-app mode (the mode used by CI), the script never calls resolve_frameworks_symlinks because it only runs inside deploy_app. If macdeployqt leaves Frameworks/ symlinks (or dangling .DS_Store links) that need fixing, CI-produced DMGs won’t get that cleanup. Consider calling resolve_frameworks_symlinks from package_dmg (or adding an explicit cleanup step/flag) so both modes produce equivalent, reliable bundles.
| while [[ $# -gt 0 ]]; do | ||
| case "$1" in | ||
| --app-path) | ||
| APP_PATH="$2" | ||
| shift 2 | ||
| ;; | ||
| --output) | ||
| OUTPUT_PATH="$2" | ||
| shift 2 | ||
| ;; | ||
| --volname) | ||
| VOLNAME="$2" | ||
| shift 2 |
There was a problem hiding this comment.
Argument parsing assumes options that take a value always have a following parameter (e.g., --app-path uses $2). With set -u, invoking the script with a missing value will terminate with an “unbound variable” error rather than a clear usage message. Add explicit validation for missing option values and print --help / a friendly error.
71489a9 to
ff3dd70
Compare
- Add explicit validation for missing option values (--app-path, --output, --volname) - Handle realpath failure gracefully in resolve_frameworks_symlinks - Call resolve_frameworks_symlinks in package_dmg for single-app mode (CI)
Summary
Improves the macOS release experience by packaging apps as DMG files and fixing several issues in the release workflow.
Changes
build_dmg.sh(new)macdeployqt, resolvesFrameworks/symlinks (prevents broken symlinks in DMG), ad-hoc signs, and creates a DMG viahdiutil— targetsfilterGenerator.appandfilterRuleTest.appin./build/--app-path/--output): used by CI wheremacdeployqtruns in a dedicated prior step--no-deploy,--no-sign,--volname,-h.github/workflows/macos-build.ymltar -czfpackaging with DMG packaging viabuild_dmg.shfor botharm64andx86_64jobsmacdeployqtstep is retained as a separate step before packaging (CI already had it; single-app mode does not re-run it).github/workflows/release.ymldraft: false— releases now publish immediately without requiring manual promotion from draft stateartifacts/**/*.dmgto thefiles:glob so macOS DMGs are attached to the GitHub Release pagetools/README.md(new)tools/; directs users to the GitHub Releases pageREADME.mdTesting
./build_dmg.shdefault mode: produces 29 MB DMGs with Qt frameworks correctly embedded (was 1.3 MB withoutmacdeployqt)macdeployqtstep runs beforebuild_dmg.shin single-app mode