@@ -325,75 +325,87 @@ jobs:
325325 with :
326326 name : com.prostoreios.prostore-unsigned-ios.ipa
327327 path : build
328- - name : Fetch Certificates List and Sign
329- run : |
330- set -e
331- UNSIGNED_IPA="build/com.prostoreios.prostore-unsigned-ios.ipa"
332- if [ ! -f "$UNSIGNED_IPA" ]; then
333- echo "ERROR: Unsigned IPA not found"
328+ - name : Fetch Certificates List and Sign
329+ run : |
330+ set -euo pipefail
331+
332+ UNSIGNED_IPA="build/com.prostoreios.prostore-unsigned-ios.ipa"
333+ if [ ! -f "$UNSIGNED_IPA" ]; then
334+ echo "ERROR: Unsigned IPA not found: $UNSIGNED_IPA"
335+ exit 1
336+ fi
337+
338+ # Fetch README.md that lists signed certs
339+ curl -s https://raw.githubusercontent.com/ProStore-iOS/certificates/refs/heads/main/README.md > readme.md
340+
341+ # Extract signed certificate full names (line format in your README)
342+ FULL_NAMES=$(grep -F '| **✅ Signed** |' readme.md | awk -F'|' '{gsub(/^\s+|\s+$/,"",$2); print $2}')
343+
344+ if [ -z "$FULL_NAMES" ]; then
345+ echo "No signed certificates found. Skipping signing."
346+ exit 0
347+ fi
348+
349+ # Install zsign dependencies
350+ brew install pkg-config openssl minizip
351+
352+ # Build zsign
353+ git clone https://github.com/zhlynn/zsign.git
354+ cd zsign/build/macos
355+ make clean && make
356+
357+ # Find the built zsign binary (most zsign builds place it in zsign/bin/zsign)
358+ cd ../../..
359+ ZSIGN_PATH="$(pwd)/zsign/bin/zsign"
360+
361+ # As a fallback, try to locate if not found
362+ if [ ! -x "$ZSIGN_PATH" ]; then
363+ echo "Expected binary not found at $ZSIGN_PATH, searching..."
364+ FOUND=$(find "$(pwd)/zsign" -type f -name zsign -perm -111 -print -quit || true)
365+ if [ -n "$FOUND" ]; then
366+ ZSIGN_PATH="$FOUND"
367+ else
368+ echo "zsign binary not found. Listing zsign tree:"
369+ ls -la zsign || true
334370 exit 1
335371 fi
336-
337- # Fetch README.md
338- curl -s https://raw.githubusercontent.com/ProStore-iOS/certificates/refs/heads/main/README.md > readme.md
339-
340- # Extract signed certificate full names
341- FULL_NAMES=$(grep -F '| **✅ Signed** |' readme.md | awk -F'|' '{gsub(/^\s+|\s+$/,"",$2); print $2}')
342-
343- if [ -z "$FULL_NAMES" ]; then
344- echo "No signed certificates found. Skipping signing."
345- exit 0
346- fi
347-
348- # Install zsign dependencies
349- brew install pkg-config openssl minizip
350-
351- # Build zsign
352- git clone https://github.com/zhlynn/zsign.git
353- cd zsign/build/macos
354- make clean && make
355- ZSIGN_PATH="$(pwd)/zsign"
356- cd ../../..
357-
358- # Process each cert
359- echo "$FULL_NAMES" | while read -r FULL_NAME; do
360- if [ -z "$FULL_NAME" ]; then continue; fi
361-
362- SHORT_NAME=$(echo "$FULL_NAME" | awk '{print tolower($1)}')
363- ENCODED=$(echo "$FULL_NAME" | python3 -c 'import sys, urllib.parse; print(urllib.parse.quote(sys.stdin.read().strip()))')
364-
365- CERT_DIR="certs/$SHORT_NAME"
366- mkdir -p "$CERT_DIR"
367- cd "$CERT_DIR"
368-
369- curl -LO "https://github.com/ProStore-iOS/certificates/raw/refs/heads/main/${ENCODED}/${ENCODED}.mobileprovision"
370- curl -LO "https://github.com/ProStore-iOS/certificates/raw/refs/heads/main/${ENCODED}/${ENCODED}.p12"
371- curl -LO "https://github.com/ProStore-iOS/certificates/raw/refs/heads/main/${ENCODED}/password.txt"
372-
373- cd ../..
374-
375- SIGNED_IPA="build/com.prostoreios.prostore-signed-${SHORT_NAME}-ios.ipa"
376-
377- "$ZSIGN_PATH" -k "${CERT_DIR}/${ENCODED}.p12" \
378- -p "$(cat "${CERT_DIR}/password.txt")" \
379- -m "${CERT_DIR}/${ENCODED}.mobileprovision" \
380- -o "$SIGNED_IPA" \
381- "$UNSIGNED_IPA"
382-
383- echo "Signed IPA created: $SIGNED_IPA"
384- done
385- - name : Upload Signed IPAs
386- if : always()
387- continue-on-error : true
388- run : |
389- for ipa in build/com.prostoreios.prostore-signed-*-ios.ipa; do
390- if [ -f "$ipa" ]; then
391- SHORT_NAME=$(basename "$ipa" | sed -E 's/com\.prostoreios\.prostore-signed-(.*)-ios\.ipa/\1/')
392- echo "Uploading $ipa as artifact com.prostoreios.prostore-signed-${SHORT_NAME}-ios.ipa"
393- mkdir -p "artifact_dir/${SHORT_NAME}"
394- cp "$ipa" "artifact_dir/${SHORT_NAME}/"
395- fi
396- done
372+ fi
373+
374+ echo "Using zsign at: $ZSIGN_PATH"
375+ ls -l "$ZSIGN_PATH" || true
376+
377+ # Process each cert
378+ echo "$FULL_NAMES" | while IFS= read -r FULL_NAME; do
379+ if [ -z "$FULL_NAME" ]; then continue; fi
380+
381+ # short name used for filenames: sanitize to lowercase alnum and dashes
382+ SHORT_NAME=$(echo "$FULL_NAME" | tr '[:upper:]' '[:lower:]' | sed -E 's/[^a-z0-9]+/-/g' | sed -E 's/^-+|-+$//g')
383+
384+ # URL-encode the full display name for the GitHub path
385+ ENCODED=$(python3 -c "import sys,urllib.parse as u; print(u.quote(sys.stdin.read().strip()))" <<< "$FULL_NAME")
386+
387+ CERT_DIR="certs/$SHORT_NAME"
388+ mkdir -p "$CERT_DIR"
389+ pushd "$CERT_DIR" >/dev/null
390+
391+ # download files; if any are missing this will fail, which is likely what you want
392+ curl -fLO "https://github.com/ProStore-iOS/certificates/raw/refs/heads/main/${ENCODED}/${ENCODED}.mobileprovision"
393+ curl -fLO "https://github.com/ProStore-iOS/certificates/raw/refs/heads/main/${ENCODED}/${ENCODED}.p12"
394+ curl -fLO "https://github.com/ProStore-iOS/certificates/raw/refs/heads/main/${ENCODED}/password.txt"
395+
396+ popd >/dev/null
397+
398+ SIGNED_IPA="build/com.prostoreios.prostore-signed-${SHORT_NAME}-ios.ipa"
399+
400+ # run zsign
401+ "$ZSIGN_PATH" -k "${CERT_DIR}/${ENCODED}.p12" \
402+ -p "$(cat "${CERT_DIR}/password.txt")" \
403+ -m "${CERT_DIR}/${ENCODED}.mobileprovision" \
404+ -o "$SIGNED_IPA" \
405+ "$UNSIGNED_IPA"
406+
407+ echo "Signed IPA created: $SIGNED_IPA"
408+ done
397409 - name : Upload Artifacts
398410 if : always()
399411 continue-on-error : true
0 commit comments