From 46572b4a25c7edf9e3ef308b63d15e10483d1b75 Mon Sep 17 00:00:00 2001 From: enricobuehler Date: Sat, 13 Jun 2026 19:05:35 +0000 Subject: [PATCH] fix(ci/release): robust iOS provisioning-profile extraction + diagnostics The profile-name/UUID read used 'security cms -D ... || true' which masked a failed decode, then PlistBuddy printed 'Error Reading File' to stdout and that got captured as the UUID, producing a garbage cp path. Now: check the extracted plist is non-empty, fall back to 'openssl smime' if 'security cms' fails, validate the UUID is actually hex+dashes, and print the decoded byte count + decoder stderr + first bytes so a bad IOS_PROFILE_B64 is obvious in-log. Still non-fatal (skips iOS, never blocks the macOS release). Co-Authored-By: Claude Opus 4.8 (1M context) --- .gitea/workflows/release.yml | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/.gitea/workflows/release.yml b/.gitea/workflows/release.yml index 012da94..b04d708 100644 --- a/.gitea/workflows/release.yml +++ b/.gitea/workflows/release.yml @@ -292,12 +292,24 @@ jobs: # export reference it by name; Xcode finds it by UUID under the profiles dirs). printf '%s' "$IOS_PROFILE_B64" | tr -d '\r\n ' | base64 -d > "$RUNNER_TEMP/appstore.mobileprovision" \ || { echo "::warning::IOS_PROFILE_B64 is not valid base64 — skipping iOS"; exit 0; } - security cms -D -i "$RUNNER_TEMP/appstore.mobileprovision" > "$RUNNER_TEMP/appstore-profile.plist" 2>/dev/null || true - PROFILE_NAME=$(/usr/libexec/PlistBuddy -c 'Print :Name' "$RUNNER_TEMP/appstore-profile.plist" 2>/dev/null || true) - PROFILE_UUID=$(/usr/libexec/PlistBuddy -c 'Print :UUID' "$RUNNER_TEMP/appstore-profile.plist" 2>/dev/null || true) - if [ -z "$PROFILE_NAME" ] || [ -z "$PROFILE_UUID" ]; then - echo "::warning::could not read provisioning profile Name/UUID — skipping iOS"; exit 0 + echo "profile bytes: $(wc -c < "$RUNNER_TEMP/appstore.mobileprovision")" + # A .mobileprovision is a CMS-signed plist — extract it (security, openssl fallback). + security cms -D -i "$RUNNER_TEMP/appstore.mobileprovision" \ + -o "$RUNNER_TEMP/appstore-profile.plist" 2>"$RUNNER_TEMP/cms.err" \ + || openssl smime -inform DER -verify -noverify \ + -in "$RUNNER_TEMP/appstore.mobileprovision" \ + -out "$RUNNER_TEMP/appstore-profile.plist" 2>>"$RUNNER_TEMP/cms.err" || true + if [ ! -s "$RUNNER_TEMP/appstore-profile.plist" ]; then + echo "::warning::could not extract the plist from the profile — is IOS_PROFILE_B64 the base64 of the .mobileprovision FILE?" + cat "$RUNNER_TEMP/cms.err" 2>/dev/null || true + echo "first bytes of decoded profile:"; head -c 64 "$RUNNER_TEMP/appstore.mobileprovision" | xxd | head -2 || true + exit 0 fi + PROFILE_NAME=$(/usr/libexec/PlistBuddy -c 'Print :Name' "$RUNNER_TEMP/appstore-profile.plist" 2>/dev/null) + PROFILE_UUID=$(/usr/libexec/PlistBuddy -c 'Print :UUID' "$RUNNER_TEMP/appstore-profile.plist" 2>/dev/null) + case "$PROFILE_UUID" in + ""|*[!A-Fa-f0-9-]*) echo "::warning::profile UUID not readable (got: '$PROFILE_UUID') — skipping iOS"; exit 0;; + esac for d in "$HOME/Library/MobileDevice/Provisioning Profiles" \ "$HOME/Library/Developer/Xcode/UserData/Provisioning Profiles"; do mkdir -p "$d"