crossmate

A collaborative crossword app for iOS
Log | Files | Refs | LICENSE

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:
MScripts/publish-ios.sh | 51++++++++++++++++++++++++++++++++++++++++-----------
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..."