commit 24dc9973eb1a89dda0b05906f4c6a95e9ceea519
parent bb38ae05a94acd670e34d92ae430a6043cd40aab
Author: Michael Camilleri <[email protected]>
Date: Sun, 19 Jul 2026 09:11:30 +0900
Make the release script's keychain cleanup failure-safe
Previously publish-ios.sh created, unlocked, and imported the signing
identities into the temporary keychain before installing its cleanup
trap. Under `set -e`, a failed import or partition-list update exited
before cleanup ran, leaving the unlocked keychain — with whichever
distribution identities had already been imported — on disk in the
repository. Cleanup was also destructive on success: it restored an
assumed login-only configuration, so a user with additional keychains in
their search list lost them after every publish.
This commit installs the trap before any `security` mutation and makes
cleanup tolerate a partially created keychain. The script now captures
the exact prior keychain search list and default keychain up front and
restores those verbatim values on every exit; the temporary keychain is
prepended to the original list during the build rather than replacing it
with a hardcoded pair. If the search list cannot be read at all, the
script aborts before modifying anything it could not restore.
Co-Authored-By: Claude Fable 5 <[email protected]>
Diffstat:
1 file changed, 40 insertions(+), 11 deletions(-)
diff --git a/Scripts/publish-ios.sh b/Scripts/publish-ios.sh
@@ -81,6 +81,45 @@ if ! git diff --quiet || ! git diff --cached --quiet; then
exit 1
fi
+# Capture the caller's exact keychain configuration before touching anything,
+# so cleanup restores their real prior state rather than assuming login-only.
+# `security` prints each path quoted and indented; strip both.
+unquote_keychain_path() {
+ local line="$1"
+ line="${line#"${line%%[![:space:]]*}"}"
+ line="${line%\"}"
+ line="${line#\"}"
+ printf '%s' "$line"
+}
+
+ORIGINAL_KEYCHAINS=()
+while IFS= read -r line; do
+ [[ -n "$line" ]] && ORIGINAL_KEYCHAINS+=("$(unquote_keychain_path "$line")")
+done < <(security list-keychains -d user)
+
+ORIGINAL_DEFAULT_KEYCHAIN="$(unquote_keychain_path "$(security default-keychain -d user 2>/dev/null || true)")"
+
+if [[ ${#ORIGINAL_KEYCHAINS[@]} -eq 0 ]]; then
+ echo "Error: could not read the current keychain search list; refusing to modify it."
+ exit 1
+fi
+
+# Cleanup must tolerate a partially completed setup: it is installed before the
+# temporary keychain exists, and any step below can die under `set -e`.
+cleanup_keychain() {
+ echo "==> Restoring keychain search list..."
+ if [[ ${#ORIGINAL_KEYCHAINS[@]} -gt 0 ]]; then
+ security list-keychains -d user -s "${ORIGINAL_KEYCHAINS[@]}" || true
+ fi
+ if [[ -n "$ORIGINAL_DEFAULT_KEYCHAIN" ]]; then
+ security default-keychain -d user -s "$ORIGINAL_DEFAULT_KEYCHAIN" || true
+ fi
+ security delete-keychain "$TMP_KEYCHAIN" 2>/dev/null || true
+ rm -f "$REPO_ROOT/private_keys/AuthKey_${KEY_ID}.p8"
+ rmdir "$REPO_ROOT/private_keys" 2>/dev/null || true
+}
+trap cleanup_keychain EXIT
+
echo "==> Setting up temporary keychain..."
security delete-keychain "$TMP_KEYCHAIN" 2>/dev/null || true
security create-keychain -p "$TMP_KEYCHAIN_PASS" "$TMP_KEYCHAIN"
@@ -92,17 +131,7 @@ security import "$DIST_P12" -k "$TMP_KEYCHAIN" -P "$DIST_P12_PASS" \
-T /usr/bin/codesign -T /usr/bin/security -T /usr/bin/productbuild
security set-key-partition-list -S apple-tool:,apple:,codesign:,productbuild: \
-s -k "$TMP_KEYCHAIN_PASS" "$TMP_KEYCHAIN"
-security list-keychains -d user -s "$TMP_KEYCHAIN" ~/Library/Keychains/login.keychain-db
-
-cleanup_keychain() {
- echo "==> Restoring keychain search list..."
- security list-keychains -d user -s ~/Library/Keychains/login.keychain-db
- security default-keychain -d user -s ~/Library/Keychains/login.keychain-db
- security delete-keychain "$TMP_KEYCHAIN" 2>/dev/null || true
- rm -f "$REPO_ROOT/private_keys/AuthKey_${KEY_ID}.p8"
- rmdir "$REPO_ROOT/private_keys" 2>/dev/null || true
-}
-trap cleanup_keychain EXIT
+security list-keychains -d user -s "$TMP_KEYCHAIN" "${ORIGINAL_KEYCHAINS[@]}"
mkdir -p "$ARCHIVE_DIR"
echo "==> Archiving $SCHEME to $ARCHIVE_PATH..."