@@ -132,55 +132,52 @@ jobs:
132132
133133 # Auto-detect: raw PEM (starts with -----BEGIN) or base64-encoded.
134134 if printf '%s' "$API_KEY" | head -c 20 | grep -q "^-----BEGIN"; then
135- # Raw PEM: strip CR and trailing whitespace per line .
136- printf '%s' "$API_KEY" | tr -d '\r' | sed 's/[[:space:]]*$//' > "$RAW_FILE"
135+ # Raw PEM: strip CR, write as-is .
136+ printf '%s' "$API_KEY" | tr -d '\r' > "$RAW_FILE"
137137 echo "Detected raw PEM format"
138138 else
139- # Base64-encoded: decode then strip CR.
139+ # Base64-encoded outer wrapper : decode it first, strip CR.
140140 printf '%s' "$API_KEY" | tr -d '\r ' | base64 -D > "$RAW_FILE"
141141 echo "Detected base64-encoded format"
142142 fi
143143
144- # Ensure file ends with exactly one newline.
145- if [[ "$(tail -c 1 "$RAW_FILE" | xxd -p)" != "0a" ]]; then
146- printf '\n' >> "$RAW_FILE"
144+ # ── CANONICAL PEM RECONSTRUCTION ─────────────────────────────────────
145+ # GitHub Secrets often strips newlines when pasting multiline values,
146+ # resulting in: -----BEGIN PRIVATE KEY-----<base64>-----END PRIVATE KEY-----
147+ # CryptoKit (used by xcodebuild) requires base64 wrapped at 64 chars.
148+ # We always reconstruct the PEM regardless, so we handle both cases.
149+ RAW_CONTENT=$(cat "$RAW_FILE" | tr -d '\r')
150+ # Extract type from first "-----BEGIN <TYPE>-----" token
151+ KEY_TYPE=$(printf '%s' "$RAW_CONTENT" | grep -o -- "-----BEGIN [^-]*-----" | head -1 | sed 's/-----BEGIN //;s/-----//')
152+ if [[ -z "$KEY_TYPE" ]]; then
153+ echo "::error::Could not detect PEM type from key content"
154+ exit 1
155+ fi
156+ echo "PEM type detected: ${KEY_TYPE}"
157+ # Extract raw base64 payload (strip all PEM headers/footers and whitespace)
158+ B64=$(printf '%s' "$RAW_CONTENT" | grep -v "^-----" | tr -d '\n\r ')
159+ if [[ -z "$B64" ]]; then
160+ echo "::error::Empty base64 payload in key"
161+ exit 1
147162 fi
163+ # Reconstruct with standard 64-char line wrapping
164+ {
165+ printf -- "-----BEGIN %s-----\n" "$KEY_TYPE"
166+ printf '%s' "$B64" | fold -w 64
167+ printf "\n-----END %s-----\n" "$KEY_TYPE"
168+ } > "$KEY_FILE"
169+ echo "PEM reconstructed: $(wc -l < "$KEY_FILE") lines, $(wc -c < "$KEY_FILE" | tr -d ' ') bytes"
170+ rm -f "$RAW_FILE"
148171
149- # Normalize via openssl so CryptoKit gets a canonical PEM structure.
150- # Use || RC=$? to prevent set -e from triggering — we handle the failure.
151- # Try 1: unencrypted PKCS8 (standard Apple API key format)
172+ # Validate via openssl (non-fatal — CryptoKit may still accept it)
152173 OPENSSL_RC=0
153- OPENSSL_OUT="$(openssl pkey -in "$RAW_FILE " -out "$KEY_FILE" 2>&1)" || OPENSSL_RC=$?
174+ OPENSSL_OUT="$(openssl pkey -in "$KEY_FILE " -noout 2>&1)" || OPENSSL_RC=$?
154175 if [ $OPENSSL_RC -eq 0 ]; then
155- echo "Key normalized via openssl pkey (unencrypted) "
176+ echo "openssl validation: PASSED "
156177 else
157- echo "openssl pkey failed (rc=${OPENSSL_RC}): ${OPENSSL_OUT}"
158- # Try 2: encrypted PKCS8 with empty passphrase → strip encryption
159- OPENSSL_RC2=0
160- OPENSSL_OUT2="$(openssl pkey -in "$RAW_FILE" -out "$KEY_FILE" -passin pass: 2>&1)" || OPENSSL_RC2=$?
161- if [ $OPENSSL_RC2 -eq 0 ]; then
162- echo "Key decrypted (empty passphrase) and normalized"
163- else
164- echo "openssl pkey (empty passphrase) failed (rc=${OPENSSL_RC2}): ${OPENSSL_OUT2}"
165- # Try 3: explicit pkcs8 decode with empty passphrase
166- OPENSSL_RC3=0
167- OPENSSL_OUT3="$(openssl pkcs8 -nocrypt -in "$RAW_FILE" -out "$KEY_FILE" -passin pass: 2>&1)" || OPENSSL_RC3=$?
168- if [ $OPENSSL_RC3 -eq 0 ]; then
169- echo "Key normalized via openssl pkcs8 (empty passphrase)"
170- else
171- echo "openssl pkcs8 (empty passphrase) also failed (rc=${OPENSSL_RC3}): ${OPENSSL_OUT3}"
172- cp "$RAW_FILE" "$KEY_FILE"
173- echo "::warning::All openssl normalization attempts failed — using raw key as-is"
174- echo "::warning::If xcodebuild fails with invalidPEMDocument, the key in APP_STORE_CONNECT_PRIVATE_KEY may be corrupted."
175- echo "::warning::Verify locally: openssl pkey -in AuthKey_*.p8 -noout"
176- echo "::warning::If that fails, re-download the key from App Store Connect and update the secret."
177- fi
178- fi
178+ echo "::warning::openssl validation: ${OPENSSL_OUT}"
179+ echo "::warning::Key may still work with xcodebuild — proceeding"
179180 fi
180- # Print PEM header for diagnostics (not secret content — header is masked)
181- HEADER=$(head -1 "$RAW_FILE")
182- echo "PEM header: '${HEADER}'"
183- rm -f "$RAW_FILE"
184181 chmod 600 "$KEY_FILE"
185182
186183 # Validate written file
0 commit comments