From 65fbb596a81ea6b7b5762d7f9e881deb64bc8d92 Mon Sep 17 00:00:00 2001 From: Trey T Date: Fri, 27 Mar 2026 10:33:28 -0500 Subject: [PATCH] =?UTF-8?q?Fix=20Release=20build=20for=20App=20Store=20dep?= =?UTF-8?q?loyment=20=E2=80=94=20manual=20signing=20and=20#if=20DEBUG=20gu?= =?UTF-8?q?ard?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Switch Release config to manual signing (Apple Distribution, SportsTime Dist profile) - Wrap SyncStatusMonitor.syncFailed call in #if DEBUG to fix Release compilation - Add deploy instructions to CLAUDE.md Co-Authored-By: Claude Opus 4.6 (1M context) --- CLAUDE.md | 40 +++++++++++++++++++ SportsTime.xcodeproj/project.pbxproj | 6 +-- .../Core/Services/CanonicalSyncService.swift | 2 + 3 files changed, 45 insertions(+), 3 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 028a5bd..8f65c48 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -25,6 +25,46 @@ cd Scripts && pip install -r requirements.txt python scrape_schedules.py --sport all --season 2026 ``` +## Deploy to App Store Connect + +Use the `/deploy` command (e.g., `/deploy main`) to archive and upload to TestFlight. If `/deploy` is unavailable, follow these steps manually: + +```bash +# 1. Source secrets +source ~/Desktop/code/tony-scripts/tony.env + +# 2. Checkout and pull +cd SportsTime +git fetch origin && git checkout && git pull origin + +# 3. Unlock keychain for headless signing +security unlock-keychain -p "$KEYCHAIN_PASSWORD" ~/Library/Keychains/login.keychain-db +security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$KEYCHAIN_PASSWORD" ~/Library/Keychains/login.keychain-db + +# 4. Archive (do NOT override build number — App Store Connect auto-increments) +xcodebuild archive \ + -project SportsTime.xcodeproj \ + -scheme SportsTime \ + -archivePath ~/reports/SportsTime.xcarchive \ + -destination 'generic/platform=iOS' \ + -allowProvisioningUpdates + +# 6. Export and upload directly (auto-increments build number) +xcodebuild -exportArchive \ + -archivePath ~/reports/SportsTime.xcarchive \ + -exportPath ~/reports/export \ + -exportOptionsPlist ~/Desktop/code/tony-scripts/ExportOptions-SportsTime-Upload.plist \ + -allowProvisioningUpdates \ + -authenticationKeyPath ~/.appstoreconnect/private_keys/AuthKey_${ASC_KEY_ID}.p8 \ + -authenticationKeyID "$ASC_KEY_ID" \ + -authenticationKeyIssuerID "$ASC_ISSUER_ID" + +# 8. Clean up +rm -rf ~/reports/SportsTime.xcarchive ~/reports/export +``` + +**Always confirm with the user before deploying.** Report version, build number, and commit before starting the archive. + ## Architecture Overview - **Pattern**: Clean MVVM with feature-based modules diff --git a/SportsTime.xcodeproj/project.pbxproj b/SportsTime.xcodeproj/project.pbxproj index dd8328b..e09c008 100644 --- a/SportsTime.xcodeproj/project.pbxproj +++ b/SportsTime.xcodeproj/project.pbxproj @@ -345,8 +345,8 @@ ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = YES; CODE_SIGN_ENTITLEMENTS = SportsTime/SportsTime.entitlements; - CODE_SIGN_IDENTITY = "Apple Development"; - CODE_SIGN_STYLE = Automatic; + CODE_SIGN_IDENTITY = "Apple Distribution: 88Oak LLC (QND55P4443)"; + CODE_SIGN_STYLE = Manual; CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_TEAM = QND55P4443; ENABLE_PREVIEWS = YES; @@ -365,7 +365,7 @@ MARKETING_VERSION = 1.0; PRODUCT_BUNDLE_IDENTIFIER = com.88oakapps.SportsTime; PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE_SPECIFIER = ""; + PROVISIONING_PROFILE_SPECIFIER = "SportsTime Dist"; STRING_CATALOG_GENERATE_SYMBOLS = YES; SWIFT_APPROACHABLE_CONCURRENCY = YES; SWIFT_EMIT_LOC_STRINGS = YES; diff --git a/SportsTime/Core/Services/CanonicalSyncService.swift b/SportsTime/Core/Services/CanonicalSyncService.swift index c2856d6..5df5adc 100644 --- a/SportsTime/Core/Services/CanonicalSyncService.swift +++ b/SportsTime/Core/Services/CanonicalSyncService.swift @@ -371,7 +371,9 @@ final class CanonicalSyncService { SyncLogger.shared.log("⚠️ [SYNC] Failed to save error state: \(saveError.localizedDescription)") } + #if DEBUG SyncStatusMonitor.shared.syncFailed(error: error) + #endif throw error }