diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index c1dd81f..a79331a 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -65,8 +65,8 @@ jobs:
# Create app bundle
mkdir -p "$APP_PATH/Contents/MacOS"
mkdir -p "$APP_PATH/Contents/Resources"
- cp .build/apple/Products/Release/bootstrapmate "$APP_PATH/Contents/MacOS/installapplications"
- chmod 755 "$APP_PATH/Contents/MacOS/installapplications"
+ cp .build/apple/Products/Release/bootstrapmate "$APP_PATH/Contents/MacOS/managedbootstrapinstall"
+ chmod 755 "$APP_PATH/Contents/MacOS/managedbootstrapinstall"
sed "s/{{VERSION}}/$VERSION/g" "$PACKAGING_DIR/resources/Info.plist.template" > "$APP_PATH/Contents/Info.plist"
# Copy LaunchDaemon and scripts
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 3501f1d..6f2bc5c 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -89,10 +89,10 @@ jobs:
"$PKG_ROOT/usr/local/bootstrapmate" "$ACTOOL_OUT"
# Binaries (NO codesign -- the Munki pipeline signs downstream).
- cp "$SWIFT_REL/bootstrapmate" "$APP_MACOS/installapplications"
+ cp "$SWIFT_REL/bootstrapmate" "$APP_MACOS/managedbootstrapinstall"
cp "$SWIFT_REL/BootstrapMateApp" "$APP_MACOS/BootstrapMateGUI"
cp "$SWIFT_REL/BootstrapMateHelper" "$APP_MACOS/BootstrapMateHelper"
- chmod 755 "$APP_MACOS/installapplications" "$APP_MACOS/BootstrapMateGUI" "$APP_MACOS/BootstrapMateHelper"
+ chmod 755 "$APP_MACOS/managedbootstrapinstall" "$APP_MACOS/BootstrapMateGUI" "$APP_MACOS/BootstrapMateHelper"
# Info.plist (version placeholders).
sed -e "s/{{MARKETING_VERSION}}/$MARKETING_VERSION/g" \
@@ -134,7 +134,7 @@ jobs:
echo "pkg=$PKG" >> "$GITHUB_OUTPUT"
echo "--- built (unsigned) ---"
ls -lh "$PKG"
- pkgutil --payload-files "$PKG" | grep -E 'BootstrapMate(GUI|Helper)|installapplications' || true
+ pkgutil --payload-files "$PKG" | grep -E 'BootstrapMate(GUI|Helper)|managedbootstrapinstall' || true
- name: Upload pkg artifact
uses: actions/upload-artifact@v7
diff --git a/Makefile b/Makefile
index 08e14c1..7205e53 100644
--- a/Makefile
+++ b/Makefile
@@ -23,7 +23,7 @@ BUILD_DIR = build
PKG_ROOT = $(BUILD_DIR)/pkg-root
PACKAGING_DIR = packaging
SCRIPTS_DIR = $(BUILD_DIR)/scripts
-BINARY_NAME = installapplications
+BINARY_NAME = managedbootstrapinstall
GUI_BINARY_NAME = BootstrapMateGUI
HELPER_BINARY_NAME = BootstrapMateHelper
BINARY_INSTALL_PATH = usr/local/bootstrapmate
@@ -132,7 +132,7 @@ copy-binary: swift-build
@codesign --force --sign "$(SIGNING_IDENTITY_APP)" \
--options runtime \
--timestamp \
- --identifier com.github.bootstrapmate.installapplications \
+ --identifier com.github.bootstrapmate.managedbootstrapinstall \
$(SWIFT_BINARY)
# Sign the GUI binary
diff --git a/README.md b/README.md
index 3d34312..4f9a42c 100644
--- a/README.md
+++ b/README.md
@@ -22,7 +22,7 @@ Examples:
Check installed version:
```bash
-/usr/local/bootstrapmate/installapplications --version
+/usr/local/bootstrapmate/managedbootstrapinstall --version
```
## Building
diff --git a/Sources/core/Managers/ConfigManager.swift b/Sources/core/Managers/ConfigManager.swift
index 1939e2c..025b21f 100644
--- a/Sources/core/Managers/ConfigManager.swift
+++ b/Sources/core/Managers/ConfigManager.swift
@@ -92,8 +92,7 @@ public final class ConfigManager {
// management preference domains to check (in order of priority)
private let managementPreferenceDomains = [
- "com.github.bootstrapmate", // Primary BootstrapMate domain (management profile)
- "io.macadmins.installapplications" // InstallApplications compatibility
+ "com.github.bootstrapmate" // Primary BootstrapMate domain (management profile)
]
// Default installation path
diff --git a/Sources/core/Utilities/BootstrapMateConstants.swift b/Sources/core/Utilities/BootstrapMateConstants.swift
index b104937..a0902b3 100644
--- a/Sources/core/Utilities/BootstrapMateConstants.swift
+++ b/Sources/core/Utilities/BootstrapMateConstants.swift
@@ -2,7 +2,7 @@ import Foundation
public enum BootstrapMateConstants {
public static let daemonIdentifier = "com.github.bootstrapmate"
- public static let executablePath = "/Applications/Utilities/BootstrapMate.app/Contents/MacOS/installapplications"
+ public static let executablePath = "/Applications/Utilities/BootstrapMate.app/Contents/MacOS/managedbootstrapinstall"
public static let helperBundleID = "com.github.bootstrapmate.helper"
public static let helperPlistName = "com.github.bootstrapmate.helper.plist"
public static let defaultRetryCount = 3
diff --git a/Sources/core/Utilities/ManagementDetector.swift b/Sources/core/Utilities/ManagementDetector.swift
index d270fc9..3cac878 100644
--- a/Sources/core/Utilities/ManagementDetector.swift
+++ b/Sources/core/Utilities/ManagementDetector.swift
@@ -14,8 +14,7 @@ public final class ManagementDetector: Sendable {
/// Preference domains checked for management, in priority order.
private let managedDomains = [
- "com.github.bootstrapmate",
- "io.macadmins.installapplications"
+ "com.github.bootstrapmate"
]
/// Known key aliases — maps canonical key to all variant names.
diff --git a/Sources/core/Utilities/ManifestGenerator.swift b/Sources/core/Utilities/ManifestGenerator.swift
index 51725f5..5dcf64f 100644
--- a/Sources/core/Utilities/ManifestGenerator.swift
+++ b/Sources/core/Utilities/ManifestGenerator.swift
@@ -37,11 +37,12 @@ public struct ManifestGenerator {
)
}
let hash = SHA256.hash(data: data).map { String(format: "%02x", $0) }.joined()
+ let filename = URL(fileURLWithPath: item.file).lastPathComponent
let manifestItem = ManifestItem(
name: item.name,
- file: "/Library/bootstrapmate/\(URL(fileURLWithPath: item.file).lastPathComponent)",
- url: "\(baseURL)/\(item.type)/\(URL(fileURLWithPath: item.file).lastPathComponent)",
+ file: "\(BootstrapMateConstants.cacheDirectory)/\(filename)",
+ url: "\(baseURL)/\(item.type)/\(filename)",
hash: hash,
type: item.type,
retries: item.retries,
diff --git a/packaging/LaunchDaemons/com.github.bootstrapmate.plist b/packaging/LaunchDaemons/com.github.bootstrapmate.plist
index 5a980dd..07cfcee 100644
--- a/packaging/LaunchDaemons/com.github.bootstrapmate.plist
+++ b/packaging/LaunchDaemons/com.github.bootstrapmate.plist
@@ -6,7 +6,7 @@
com.github.bootstrapmate
ProgramArguments
- /Applications/Utilities/BootstrapMate.app/Contents/MacOS/installapplications
+ /Applications/Utilities/BootstrapMate.app/Contents/MacOS/managedbootstrapinstall
RunAtLoad
diff --git a/packaging/scripts/postinstall b/packaging/scripts/postinstall
index a29dd1f..0aeb733 100755
--- a/packaging/scripts/postinstall
+++ b/packaging/scripts/postinstall
@@ -12,9 +12,9 @@ log() {
log "=== BootstrapMate postinstall started ==="
APP_PATH="/Applications/Utilities/BootstrapMate.app"
-BINARY_PATH="${APP_PATH}/Contents/MacOS/installapplications"
+BINARY_PATH="${APP_PATH}/Contents/MacOS/managedbootstrapinstall"
SYMLINK_DIR="/usr/local/bootstrapmate"
-SYMLINK_PATH="${SYMLINK_DIR}/installapplications"
+SYMLINK_PATH="${SYMLINK_DIR}/managedbootstrapinstall"
LAUNCHDAEMON_PATH="/Library/LaunchDaemons/com.github.bootstrapmate.plist"
# Managed Bootstrap directory structure
@@ -44,6 +44,9 @@ if [[ -x "${BINARY_PATH}" ]]; then
mkdir -p "${SYMLINK_DIR}"
ln -sf "${BINARY_PATH}" "${SYMLINK_PATH}"
log "Symlink created: ${SYMLINK_PATH} -> ${BINARY_PATH}"
+
+ # Hard cut: drop the legacy installapplications symlink from prior versions
+ rm -f "${SYMLINK_DIR}/installapplications" 2>/dev/null || true
# Verify symlink works
if [[ -x "${SYMLINK_PATH}" ]]; then
@@ -60,8 +63,11 @@ if [[ -x "${BINARY_PATH}" ]]; then
chown root:wheel "${LAUNCHDAEMON_PATH}"
log "LaunchDaemon permissions set"
- # Load the LaunchDaemon
+ # Boot out any previously loaded job first: launchctl load no-ops when the
+ # label is already loaded, which on an upgrade would leave launchd pointing
+ # at the old executable path (the binary was renamed). Boot out, then load.
log "Loading LaunchDaemon..."
+ /bin/launchctl bootout system/com.github.bootstrapmate 2>/dev/null || true
/bin/launchctl load -w "${LAUNCHDAEMON_PATH}" 2>&1 | tee -a /tmp/bootstrapmate-postinstall.log || log "launchctl load returned non-zero"
log "LaunchDaemon load attempted"
else