screenshots-mac.sh (4764B)
1 #!/bin/bash 2 set -euo pipefail 3 4 DO_COMPOSE=false 5 while getopts "c" opt; do 6 case $opt in 7 c) DO_COMPOSE=true ;; 8 *) ;; 9 esac 10 done 11 shift $((OPTIND - 1)) 12 13 REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)" 14 SECRETS="$REPO_ROOT/.asc/secrets.sh" 15 16 if [[ ! -f "$SECRETS" ]]; then 17 echo "Error: $SECRETS not found. See Scripts/secrets.sh.example for the required format." 18 exit 1 19 fi 20 21 source "$SECRETS" 22 23 DEV_P12="$REPO_ROOT/.asc/dev.p12" 24 TMP_KEYCHAIN="$REPO_ROOT/.asc/build.keychain-db" 25 26 echo "==> Setting up temporary keychain..." 27 security delete-keychain "$TMP_KEYCHAIN" 2>/dev/null || true 28 security create-keychain -p "$TMP_KEYCHAIN_PASS" "$TMP_KEYCHAIN" 29 security unlock-keychain -p "$TMP_KEYCHAIN_PASS" "$TMP_KEYCHAIN" 30 security set-keychain-settings -lut 21600 "$TMP_KEYCHAIN" 31 security import "$DEV_P12" -k "$TMP_KEYCHAIN" -P "$DEV_P12_PASS" \ 32 -T /usr/bin/codesign -T /usr/bin/security -T /usr/bin/productbuild 33 security set-key-partition-list -S apple-tool:,apple:,codesign:,productbuild: \ 34 -s -k "$TMP_KEYCHAIN_PASS" "$TMP_KEYCHAIN" 35 security list-keychains -d user -s "$TMP_KEYCHAIN" ~/Library/Keychains/login.keychain-db 36 37 cleanup_keychain() { 38 echo "==> Restoring keychain search list..." 39 security list-keychains -d user -s ~/Library/Keychains/login.keychain-db 40 security default-keychain -d user -s ~/Library/Keychains/login.keychain-db 41 security delete-keychain "$TMP_KEYCHAIN" 2>/dev/null || true 42 } 43 trap cleanup_keychain EXIT 44 45 SCREENSHOT_TMP="/tmp/listless-screenshots" 46 FRAMED_TMP="/tmp/listless-framed" 47 MARKETING_DIR="$(pwd)/Marketing" 48 SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" 49 50 # Mac ASC canvas dimensions (16:10) 51 CANVAS_WIDTH=2880 52 CANVAS_HEIGHT=1800 53 54 CAPTIONS=( 55 "Syncs via iCloud" 56 "Dark Mode" 57 "Natural Selection" 58 ) 59 60 XCRESULT_DIR=$(mktemp -d) 61 62 # Run screenshot tests (attachments stored in xcresult bundle) 63 echo "==> Running macOS screenshot tests..." 64 xcodebuild test \ 65 -scheme "Listless macOS" \ 66 -destination "platform=macOS" \ 67 -only-testing:"Listless macOS UI Tests/ListlessMacScreenshots" \ 68 -resultBundlePath "${XCRESULT_DIR}/result.xcresult" \ 69 2>&1 70 71 # Extract attachments from xcresult bundle 72 echo "==> Extracting screenshots from xcresult..." 73 rm -rf "${SCREENSHOT_TMP}" 74 mkdir -p "${SCREENSHOT_TMP}" 75 xcrun xcresulttool export attachments \ 76 --path "${XCRESULT_DIR}/result.xcresult" \ 77 --output-path "${SCREENSHOT_TMP}" 78 79 # Rename attachments using manifest.json (attachment name -> file) 80 osascript -l JavaScript -e " 81 var manifest = JSON.parse($.NSString.alloc.initWithDataEncoding( 82 $.NSData.dataWithContentsOfFile('${SCREENSHOT_TMP}/manifest.json'), 83 $.NSUTF8StringEncoding).js); 84 var fm = $.NSFileManager.defaultManager; 85 manifest.forEach(function(entry) { 86 (entry.attachments || []).forEach(function(att) { 87 var exported = att.exportedFileName || ''; 88 var suggested = att.suggestedHumanReadableName || ''; 89 if (exported && suggested) { 90 var name = suggested.replace(/_\d+_[A-F0-9-]+\.png$/, ''); 91 var src = '${SCREENSHOT_TMP}/' + exported; 92 var dst = '${SCREENSHOT_TMP}/' + name + '.png'; 93 fm.moveItemAtPathToPathError(src, dst, null); 94 } 95 }); 96 });" 97 98 rm -rf "${XCRESULT_DIR}" 99 100 if ! ls "${SCREENSHOT_TMP}"/*.png 1>/dev/null 2>&1; then 101 echo "No screenshots found in ${SCREENSHOT_TMP}." 102 exit 1 103 fi 104 105 mkdir -p "${MARKETING_DIR}" 106 107 if [ "$DO_COMPOSE" = true ]; then 108 DESKTOP_TMP="/tmp/listless-desktop" 109 mkdir -p "${DESKTOP_TMP}" 110 mkdir -p "${FRAMED_TMP}" 111 112 echo "" 113 echo "Composing desktop images..." 114 n=0 115 for file in "${SCREENSHOT_TMP}"/0*.png; do 116 swift "${SCRIPT_DIR}/screenshots-mac-desktop.swift" "$file" "${DESKTOP_TMP}/desktop_${n}.png" "$(pwd)/Marketing/sequoia-wallpaper.jpg" 117 echo " desktop_${n}.png" 118 n=$((n + 1)) 119 done 120 121 echo "Framing screenshots..." 122 n=0 123 for file in "${DESKTOP_TMP}"/desktop_*.png; do 124 shortcuts run "Frame Screenshots" -i "$file" -o "${FRAMED_TMP}/framed_${n}.png" 125 echo " Framed screenshot ${n}" 126 n=$((n + 1)) 127 done 128 129 rm -rf "${DESKTOP_TMP}" 130 131 echo "Composing final images..." 132 n=0 133 for file in "${FRAMED_TMP}"/framed_*.png; do 134 caption="${CAPTIONS[$n]:-}" 135 swift "${SCRIPT_DIR}/screenshots-ios-compose.swift" "$file" "${MARKETING_DIR}/mac_${n}.png" "$caption" "$CANVAS_WIDTH" "$CANVAS_HEIGHT" 136 echo " mac_${n}.png — ${caption}" 137 n=$((n + 1)) 138 done 139 140 rm -rf "${FRAMED_TMP}" 141 else 142 OUTPUT_DIR="$(pwd)" 143 echo "" 144 n=0 145 for file in "${SCREENSHOT_TMP}"/0*.png; do 146 cp "$file" "${OUTPUT_DIR}/mac_${n}.png" 147 n=$((n + 1)) 148 done 149 fi 150 151 rm -rf "${SCREENSHOT_TMP}" 152 153 if [ "$DO_COMPOSE" = true ]; then 154 echo "" 155 echo "Screenshots saved to ${MARKETING_DIR}/" 156 ls -la "${MARKETING_DIR}"/mac_*.png 157 else 158 echo "" 159 echo "Screenshots saved to ${OUTPUT_DIR}/" 160 ls -la "${OUTPUT_DIR}"/mac_*.png 161 fi