Managing macOS apps with mise

Install and upgrade macOS applications distributed as DMG or ZIP files using mise's GitHub backend and a reusable global task.

mise is a fast, flexible tool manager that can install and keep development tools in sync across machines. Its GitHub backend can also download arbitrary release assets, making it useful for managing macOS applications alongside your usual command-line tools.

mise downloads GitHub release assets, but it does not install DMG applications into /Applications. Add this custom global task to ~/.config/mise/config.toml:

 1[tasks."macos:install-dmg-app"]
 2hide = true
 3run = '''
 4set -euo pipefail
 5
 6install_path="${MISE_TOOL_INSTALL_PATH:?MISE_TOOL_INSTALL_PATH is required}"
 7dmg_pattern="${MACOS_DMG_PATTERN:-*.dmg}"
 8app_pattern="${MACOS_APP_PATTERN:-*.app}"
 9
10dmg="$(find "$install_path" -maxdepth 1 -name "$dmg_pattern" -type f -print -quit)"
11app_root="$install_path"
12
13if [ -n "$dmg" ]; then
14  mount="$(hdiutil attach "$dmg" -nobrowse -readonly |
15    awk '/\/Volumes\// {print substr($0, index($0, "/Volumes/")); exit}')"
16
17  cleanup() {
18    hdiutil detach "$mount" -quiet 2>/dev/null || true
19  }
20  trap cleanup EXIT
21  app_root="$mount"
22fi
23
24app="$(find "$app_root" -maxdepth 1 -name "$app_pattern" -type d -print -quit)"
25[ -n "$app" ] || { echo "No .app found in $app_root"; exit 1; }
26
27app_name="${MACOS_APP_NAME:-$(basename "$app")}"
28case "$app_name" in
29  *.app) ;;
30  *) app_name="$app_name.app" ;;
31esac
32
33ditto "$app" "/Applications/$app_name"
34'''

Then declare apps using mise’s GitHub backend:

1[tools."github:user/repo"]
2version = "latest"
3asset_pattern = "App-darwin-arm64-{{ version }}.dmg"
4postinstall = "mise run --skip-tools --raw macos:install-dmg-app"

For ZIP releases containing an .app:

1asset_pattern = "App-*.zip"
2strip_components = 0
3postinstall = "mise run --skip-tools --raw macos:install-dmg-app"

Install or upgrade the configured apps:

1mise install
2mise upgrade