This commit updates the check_signing_identities.sh script to search for provisioning profiles in multiple common directories, improving the detection process. Additionally, the README_MAS.md is updated to clarify where provisioning profiles are stored in newer Xcode versions and provides guidance on locating the correct profile for Mac App Store builds. This enhances the overall usability and clarity for developers working with macOS builds.
168 lines
4.7 KiB
Bash
Executable File
168 lines
4.7 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
ts() { date +"%H:%M:%S"; }
|
|
|
|
usage() {
|
|
cat <<'EOF'
|
|
Usage:
|
|
./build_tools/macos/find_mas_provisioning_profile.sh --bundle-id com.dryark.strawberry
|
|
|
|
What it does:
|
|
- Scans common macOS provisioning profile locations (new Xcode + legacy)
|
|
- Decodes each *.provisionprofile (CMS) into plist
|
|
- Prints a readable table and recommends a best match for the given bundle id
|
|
|
|
Notes:
|
|
- A provisioning profile is required for Mac App Store signing.
|
|
- This script only helps you *find* the right profile file.
|
|
EOF
|
|
}
|
|
|
|
if [[ "$(uname -s)" != "Darwin" ]]; then
|
|
echo "Error: This script is for macOS only." >&2
|
|
exit 1
|
|
fi
|
|
|
|
bundle_id=""
|
|
while [[ $# -gt 0 ]]; do
|
|
case "$1" in
|
|
--bundle-id) bundle_id="${2:-}"; shift 2 ;;
|
|
-h|--help) usage; exit 0 ;;
|
|
*) echo "Unknown arg: $1" >&2; usage; exit 2 ;;
|
|
esac
|
|
done
|
|
|
|
if [[ -z "$bundle_id" ]]; then
|
|
echo "Error: missing --bundle-id" >&2
|
|
usage
|
|
exit 2
|
|
fi
|
|
|
|
if ! command -v security >/dev/null 2>&1; then
|
|
echo "Error: 'security' not found." >&2
|
|
exit 1
|
|
fi
|
|
|
|
plutil_extract() {
|
|
local keypath="$1"
|
|
local plist="$2"
|
|
/usr/bin/plutil -extract "$keypath" raw -o - "$plist" 2>/dev/null || true
|
|
}
|
|
|
|
find_profiles_in_dir() {
|
|
local dir="$1"
|
|
if [[ -d "$dir" ]]; then
|
|
find "$dir" -maxdepth 1 -type f -name "*.provisionprofile" 2>/dev/null || true
|
|
fi
|
|
}
|
|
|
|
declare -a candidates
|
|
candidates=()
|
|
|
|
# Newer Xcode location (as reported by user)
|
|
while IFS= read -r f; do candidates+=("$f"); done < <(find_profiles_in_dir "$HOME/Library/Developer/Xcode/UserData/Provisioning Profiles")
|
|
|
|
# Legacy location
|
|
while IFS= read -r f; do candidates+=("$f"); done < <(find_profiles_in_dir "$HOME/Library/MobileDevice/Provisioning Profiles")
|
|
|
|
if [[ ${#candidates[@]} -eq 0 ]]; then
|
|
echo "==> [$(ts)] No .provisionprofile files found in common locations."
|
|
echo "Checked:"
|
|
echo " - $HOME/Library/Developer/Xcode/UserData/Provisioning Profiles"
|
|
echo " - $HOME/Library/MobileDevice/Provisioning Profiles"
|
|
exit 1
|
|
fi
|
|
|
|
echo "==> [$(ts)] Scanning ${#candidates[@]} provisioning profile(s) for bundle id: ${bundle_id}"
|
|
echo
|
|
|
|
best_score=-1
|
|
best_path=""
|
|
best_reason=""
|
|
|
|
printf "%-4s %-36s %-10s %-25s %-40s %s\n" "No." "UUID" "TeamID" "Expires" "AppID" "Path"
|
|
printf "%s\n" "---- ------------------------------------ ---------- ------------------------- ---------------------------------------- ----"
|
|
|
|
idx=0
|
|
for f in "${candidates[@]}"; do
|
|
idx=$((idx + 1))
|
|
|
|
tmp="$(mktemp -t strawberry-profile.XXXXXX.plist)"
|
|
if ! security cms -D -i "$f" >"$tmp" 2>/dev/null; then
|
|
rm -f "$tmp" >/dev/null 2>&1 || true
|
|
continue
|
|
fi
|
|
|
|
uuid="$(plutil_extract UUID "$tmp")"
|
|
name="$(plutil_extract Name "$tmp")"
|
|
teamid="$(plutil_extract 'TeamIdentifier.0' "$tmp")"
|
|
exp="$(plutil_extract ExpirationDate "$tmp")"
|
|
|
|
# Profiles vary in which key they use for the app identifier.
|
|
appid="$(plutil_extract 'Entitlements.application-identifier' "$tmp")"
|
|
if [[ -z "$appid" ]]; then
|
|
appid="$(plutil_extract 'Entitlements.com.apple.application-identifier' "$tmp")"
|
|
fi
|
|
|
|
rm -f "$tmp" >/dev/null 2>&1 || true
|
|
|
|
# Fallbacks for display.
|
|
[[ -z "$uuid" ]] && uuid="(unknown)"
|
|
[[ -z "$teamid" ]] && teamid="(unknown)"
|
|
[[ -z "$exp" ]] && exp="(unknown)"
|
|
[[ -z "$appid" ]] && appid="(unknown)"
|
|
|
|
printf "%-4s %-36s %-10s %-25s %-40s %s\n" "$idx" "$uuid" "$teamid" "$exp" "$appid" "$f"
|
|
|
|
# Score match quality.
|
|
score=0
|
|
reason=""
|
|
|
|
# Prefer exact team+bundle match.
|
|
if [[ "$appid" != "(unknown)" && "$teamid" != "(unknown)" ]]; then
|
|
if [[ "$appid" == "${teamid}.${bundle_id}" ]]; then
|
|
score=100
|
|
reason="exact match (${appid})"
|
|
elif [[ "$appid" == "${teamid}."* && "$appid" == *"*"* ]]; then
|
|
# Wildcard profile like TEAMID.*
|
|
score=60
|
|
reason="wildcard match (${appid})"
|
|
elif [[ "$appid" == *".${bundle_id}" ]]; then
|
|
score=50
|
|
reason="endswith match (${appid})"
|
|
fi
|
|
fi
|
|
|
|
# Prefer profiles with a plausible name for MAS (heuristic).
|
|
if [[ "$score" -gt 0 && -n "$name" ]]; then
|
|
case "$name" in
|
|
*Mac\ App\ Store*|*App\ Store*|*appstore*|*AppStore*)
|
|
score=$((score + 5))
|
|
reason="${reason}, name looks like MAS"
|
|
;;
|
|
esac
|
|
fi
|
|
|
|
if [[ "$score" -gt "$best_score" ]]; then
|
|
best_score="$score"
|
|
best_path="$f"
|
|
best_reason="$reason"
|
|
fi
|
|
done
|
|
|
|
echo
|
|
if [[ "$best_score" -le 0 ]]; then
|
|
echo "==> [$(ts)] Could not confidently auto-select a profile for ${bundle_id}."
|
|
echo "Pick the profile whose AppID is TEAMID.${bundle_id} and is a macOS Mac App Store profile."
|
|
exit 2
|
|
fi
|
|
|
|
echo "==> [$(ts)] Recommended profile:"
|
|
echo " $best_path"
|
|
echo " reason: $best_reason"
|
|
echo
|
|
echo "Use it like:"
|
|
echo " ./build_tools/macos/build_mas_pkg.sh --run ... --provisionprofile \"$best_path\""
|
|
|