Files
strawberry/build_tools/macos/find_mas_provisioning_profile.sh
David Helkowski 7a954b3f32 Enhance macOS build scripts for provisioning profile handling and identity management
This commit improves the `find_mas_provisioning_profile.sh` script by expanding the search for provisioning profiles to include both `.provisionprofile` and `.mobileprovision` files. It also introduces a new function to print SHA-1 values for identities, helping to avoid ambiguity when multiple identities share the same display name. Additionally, the `check_signing_identities.sh` script is updated to provide clearer recommendations for using SHA-1 hashes with codesigning and installer identities, enhancing the overall usability and clarity for developers working with macOS builds.
2026-01-22 21:15:07 +09:00

161 lines
4.5 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)
- Uses Apple's `security cms -D` to decode each *.provisionprofile into a 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
plistbuddy_print() {
local keypath="$1"
local plist="$2"
/usr/libexec/PlistBuddy -c "Print :${keypath}" "$plist" 2>/dev/null || true
}
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" -o -name "*.mobileprovision" \) 2>/dev/null || true
fi
}
declare -a candidates
candidates=()
while IFS= read -r f; do candidates+=("$f"); done < <(find_profiles_in_dir "$HOME/Library/Developer/Xcode/UserData/Provisioning Profiles")
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 provisioning profiles found in common locations."
exit 1
fi
echo "==> [$(ts)] Scanning ${#candidates[@]} provisioning profile(s) for bundle id: ${bundle_id}"
echo
printf "%-4s %-36s %-10s %-25s %-45s %s\n" "No." "UUID" "TeamID" "Expires" "AppID" "Path"
printf "%s\n" "---- ------------------------------------ ---------- ------------------------- --------------------------------------------- ----"
best_score=-1
best_path=""
best_reason=""
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")"
if [[ -z "$teamid" ]]; then
teamid="$(plutil_extract 'ApplicationIdentifierPrefix.0' "$tmp")"
fi
exp="$(plutil_extract ExpirationDate "$tmp")"
# App identifier lives under Entitlements; use PlistBuddy because some key names contain dots.
appid="$(plistbuddy_print 'Entitlements:application-identifier' "$tmp")"
if [[ -z "$appid" ]]; then
appid="$(plistbuddy_print 'Entitlements:com.apple.application-identifier' "$tmp")"
fi
rm -f "$tmp" >/dev/null 2>&1 || true
[[ -z "$uuid" ]] && uuid="(unknown)"
[[ -z "$teamid" ]] && teamid="(unknown)"
[[ -z "$exp" ]] && exp="(unknown)"
[[ -z "$appid" ]] && appid="(unknown)"
printf "%-4s %-36s %-10s %-25s %-45s %s\n" "$idx" "$uuid" "$teamid" "$exp" "$appid" "$f"
score=0
reason=""
if [[ "$appid" != "(unknown)" && "$teamid" != "(unknown)" ]]; then
if [[ "$appid" == "${teamid}.${bundle_id}" ]]; then
score=100
reason="exact match (${appid})"
elif [[ "$appid" == *".${bundle_id}" ]]; then
score=50
reason="endswith match (${appid})"
elif [[ "$appid" == "${teamid}."* && "$appid" == *"*"* ]]; then
score=40
reason="wildcard match (${appid})"
fi
fi
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"