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.
161 lines
4.5 KiB
Bash
Executable File
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"
|
|
|