Release 1.2.1: iCloud sync improvements + ASO multilingual metadata
iCloud sync: - Force viewContext.refreshAllObjects() on remote change notifications so data from other devices is picked up immediately without app restart - Call refreshFromCloudKit() on foreground to merge any changes made while the device was inactive - Wait up to 10s for initial CloudKit sync on launch before showing onboarding (shows "Checking iCloud..." during the wait) - New OnboardingICloudCheckView: shown on fresh installs with iCloud available, lets user restore from iCloud before starting onboarding from scratch Localization: - Added de, fr, it, ja, pt-BR lproj folders - New iCloud onboarding strings in en + es-ES (+ button literals) ASO metadata (fastlane): - Updated en-US: new subtitle, keywords, description (fixed "no cloud sync" claim), promotional text, release notes - Added full metadata for es-ES, de-DE, fr-FR, it, ja, pt-BR (63 files total) - All keyword fields validated ≤100 Unicode chars Infrastructure: - Gemfile + Gemfile.lock for fastlane - Scripts/archive_and_upload_appstore.sh for CI/CD Version: 1.2.1 (build 7) Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Executable
+132
@@ -0,0 +1,132 @@
|
||||
#!/bin/zsh
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
ROOT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
|
||||
PROJECT_PATH="${PROJECT_PATH:-$ROOT_DIR/PortfolioJournal.xcodeproj}"
|
||||
SCHEME="${SCHEME:-PortfolioJournal}"
|
||||
CONFIGURATION="${CONFIGURATION:-Release}"
|
||||
ARCHIVE_DIR="${ARCHIVE_DIR:-$ROOT_DIR/build/appstore}"
|
||||
ARCHIVE_PATH="${ARCHIVE_PATH:-$ARCHIVE_DIR/${SCHEME}.xcarchive}"
|
||||
EXPORT_PATH="${EXPORT_PATH:-$ARCHIVE_DIR/export}"
|
||||
EXPORT_OPTIONS_PLIST="${EXPORT_OPTIONS_PLIST:-$ARCHIVE_DIR/ExportOptions.plist}"
|
||||
KEY_ID="${APPSTORE_KEY_ID:-YJLSGZGP79}"
|
||||
ISSUER_ID="${APPSTORE_ISSUER_ID:-33f82bb1-0dbd-4b3f-a0ef-1a863dfd9453}"
|
||||
TEAM_ID="${DEVELOPMENT_TEAM_ID:-2825Q76T7H}"
|
||||
P8_PATH="${APPSTORE_P8_PATH:-}"
|
||||
P8_DIR=""
|
||||
|
||||
fail() {
|
||||
echo "Error: $*" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
find_p8_file() {
|
||||
if [[ -n "$P8_PATH" ]]; then
|
||||
[[ -f "$P8_PATH" ]] || fail "No existe el fichero APPSTORE_P8_PATH=$P8_PATH"
|
||||
echo "$P8_PATH"
|
||||
return
|
||||
fi
|
||||
|
||||
local default_path="$HOME/AuthKey_${KEY_ID}.p8"
|
||||
if [[ -f "$default_path" ]]; then
|
||||
echo "$default_path"
|
||||
return
|
||||
fi
|
||||
|
||||
local matches=("${HOME}"/*.p8(N))
|
||||
if (( ${#matches[@]} == 1 )); then
|
||||
echo "${matches[1]}"
|
||||
return
|
||||
fi
|
||||
|
||||
if (( ${#matches[@]} > 1 )); then
|
||||
fail "Hay varios ficheros .p8 en $HOME. Define APPSTORE_P8_PATH con la ruta correcta."
|
||||
fi
|
||||
|
||||
fail "No se encontro AuthKey_${KEY_ID}.p8 ni un unico fichero .p8 en $HOME."
|
||||
}
|
||||
|
||||
create_export_options() {
|
||||
mkdir -p "$ARCHIVE_DIR"
|
||||
cat > "$EXPORT_OPTIONS_PLIST" <<EOF
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "https://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>destination</key>
|
||||
<string>export</string>
|
||||
<key>manageAppVersionAndBuildNumber</key>
|
||||
<false/>
|
||||
<key>method</key>
|
||||
<string>app-store-connect</string>
|
||||
<key>signingStyle</key>
|
||||
<string>automatic</string>
|
||||
<key>stripSwiftSymbols</key>
|
||||
<true/>
|
||||
<key>teamID</key>
|
||||
<string>${TEAM_ID}</string>
|
||||
<key>uploadSymbols</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
EOF
|
||||
}
|
||||
|
||||
archive_app() {
|
||||
echo "==> Archivando ${SCHEME}"
|
||||
xcodebuild \
|
||||
-project "$PROJECT_PATH" \
|
||||
-scheme "$SCHEME" \
|
||||
-configuration "$CONFIGURATION" \
|
||||
-archivePath "$ARCHIVE_PATH" \
|
||||
-destination "generic/platform=iOS" \
|
||||
clean archive
|
||||
}
|
||||
|
||||
export_ipa() {
|
||||
echo "==> Exportando IPA"
|
||||
xcodebuild \
|
||||
-exportArchive \
|
||||
-archivePath "$ARCHIVE_PATH" \
|
||||
-exportPath "$EXPORT_PATH" \
|
||||
-exportOptionsPlist "$EXPORT_OPTIONS_PLIST"
|
||||
}
|
||||
|
||||
upload_ipa() {
|
||||
local ipa
|
||||
ipa="$(find "$EXPORT_PATH" -maxdepth 1 -name '*.ipa' -print -quit)"
|
||||
[[ -n "$ipa" ]] || fail "No se encontro ningun .ipa en $EXPORT_PATH"
|
||||
|
||||
echo "==> Subiendo $(basename "$ipa") a App Store Connect"
|
||||
API_PRIVATE_KEYS_DIR="$P8_DIR" \
|
||||
xcrun altool \
|
||||
--upload-app \
|
||||
--type ios \
|
||||
--file "$ipa" \
|
||||
--apiKey "$KEY_ID" \
|
||||
--apiIssuer "$ISSUER_ID"
|
||||
}
|
||||
|
||||
main() {
|
||||
command -v xcodebuild >/dev/null 2>&1 || fail "xcodebuild no esta disponible"
|
||||
command -v xcrun >/dev/null 2>&1 || fail "xcrun no esta disponible"
|
||||
|
||||
P8_PATH="$(find_p8_file)"
|
||||
P8_DIR="$(dirname "$P8_PATH")"
|
||||
|
||||
echo "Usando proyecto: $PROJECT_PATH"
|
||||
echo "Usando scheme: $SCHEME"
|
||||
echo "Usando clave API: $KEY_ID"
|
||||
echo "Usando fichero .p8: $P8_PATH"
|
||||
|
||||
rm -rf "$ARCHIVE_PATH" "$EXPORT_PATH"
|
||||
create_export_options
|
||||
archive_app
|
||||
export_ipa
|
||||
upload_ipa
|
||||
|
||||
echo "==> Proceso completado"
|
||||
}
|
||||
|
||||
main "$@"
|
||||
Reference in New Issue
Block a user