diff --git a/.github/workflows/tmp-write-apple-issuer.yml b/.github/workflows/tmp-write-apple-issuer.yml new file mode 100644 index 00000000..e25cc2a2 --- /dev/null +++ b/.github/workflows/tmp-write-apple-issuer.yml @@ -0,0 +1,26 @@ +name: Write Apple API issuer (local runner) +on: + workflow_dispatch: +jobs: + write: + runs-on: [self-hosted, macOS, ARM64, edgeever-mobile] + steps: + - name: Write issuer and key id to local config (no log of values) + env: + ISSUER: ${{ secrets.EDGEEVER_APPLE_API_ISSUER }} + KEY_ID: ${{ secrets.EDGEEVER_APPLE_API_KEY_ID }} + KEY_B64: ${{ secrets.EDGEEVER_APPLE_API_KEY_BASE64 }} + run: | + set -euo pipefail + mkdir -p "$HOME/.config/edgeever/ios" + umask 077 + test -n "${ISSUER:-}" + test -n "${KEY_ID:-}" + test -n "${KEY_B64:-}" + printf '%s' "$ISSUER" > "$HOME/.config/edgeever/ios/apple-api-issuer" + printf '%s' "$KEY_ID" > "$HOME/.config/edgeever/ios/apple-api-key-id" + printf '%s' "$KEY_B64" | base64 -D > "$HOME/.config/edgeever/ios/AuthKey_${KEY_ID}.p8" + chmod 600 "$HOME/.config/edgeever/ios/apple-api-issuer" \ + "$HOME/.config/edgeever/ios/apple-api-key-id" \ + "$HOME/.config/edgeever/ios/AuthKey_${KEY_ID}.p8" + echo "ok issuer_bytes=$(wc -c < "$HOME/.config/edgeever/ios/apple-api-issuer") key_id_bytes=$(wc -c < "$HOME/.config/edgeever/ios/apple-api-key-id")" diff --git a/apps/ios/Config/Version.xcconfig b/apps/ios/Config/Version.xcconfig index 3d76c33c..35fa1772 100644 --- a/apps/ios/Config/Version.xcconfig +++ b/apps/ios/Config/Version.xcconfig @@ -1,4 +1,5 @@ // Bump MARKETING_VERSION with monorepo release X.Y.Z when shipping App Store builds. // CURRENT_PROJECT_VERSION must increase for every store upload (TestFlight / App Store). -MARKETING_VERSION = 1.0.0 -CURRENT_PROJECT_VERSION = 1 +// Build 30+ marks the native SwiftUI client (RN EAS builds ended at 29). +MARKETING_VERSION = 1.12.6 +CURRENT_PROJECT_VERSION = 30 diff --git a/apps/ios/ExportOptions.plist b/apps/ios/ExportOptions.plist new file mode 100644 index 00000000..e35e7386 --- /dev/null +++ b/apps/ios/ExportOptions.plist @@ -0,0 +1,25 @@ + + + + + destination + export + method + app-store-connect + signingStyle + manual + teamID + 9KA3NM38B6 + uploadSymbols + + manageAppVersionAndBuildNumber + + provisioningProfiles + + org.edgeever.mobile + *[expo] org.edgeever.mobile AppStore 2026-08-01T04:08:38.265Z + org.edgeever.mobile.expo-sharing-extension + *[expo] org.edgeever.mobile.expo-sharing-extension AppStore 2026-08-01T04:09:04.014Z + + + diff --git a/apps/ios/Scripts/archive-app-store.sh b/apps/ios/Scripts/archive-app-store.sh new file mode 100755 index 00000000..6ecac60a --- /dev/null +++ b/apps/ios/Scripts/archive-app-store.sh @@ -0,0 +1,48 @@ +#!/usr/bin/env bash +# Archive and export a signed App Store IPA from apps/ios. +set -euo pipefail + +ROOT="$(cd "$(dirname "$0")/.." && pwd)" +DERIVED="${EDGE_EVER_IOS_DERIVED:-$ROOT/build}" +ARCHIVE_PATH="${EDGE_EVER_IOS_ARCHIVE:-$DERIVED/EdgeEver.xcarchive}" +EXPORT_PATH="${EDGE_EVER_IOS_EXPORT:-$DERIVED/export}" +EXPORT_OPTIONS="${EDGE_EVER_IOS_EXPORT_OPTIONS:-$ROOT/ExportOptions.plist}" + +cd "$ROOT" + +if [[ "${EDGE_EVER_IOS_SKIP_EDITOR_BUILD:-0}" != "1" ]]; then + bash "$ROOT/Scripts/build-editor-bundle.sh" +fi + +if command -v xcodegen >/dev/null 2>&1; then + xcodegen generate +fi + +mkdir -p "$DERIVED" +rm -rf "$ARCHIVE_PATH" "$EXPORT_PATH" + +echo "Archiving EdgeEver for App Store..." +xcodebuild \ + -project "$ROOT/EdgeEver.xcodeproj" \ + -scheme EdgeEver \ + -configuration Release \ + -destination "generic/platform=iOS" \ + -archivePath "$ARCHIVE_PATH" \ + -derivedDataPath "$DERIVED/DerivedData" \ + archive + +echo "Exporting IPA..." +xcodebuild \ + -exportArchive \ + -archivePath "$ARCHIVE_PATH" \ + -exportPath "$EXPORT_PATH" \ + -exportOptionsPlist "$EXPORT_OPTIONS" + +IPA="$(find "$EXPORT_PATH" -name '*.ipa' | head -1)" +if [[ -z "$IPA" || ! -f "$IPA" ]]; then + echo "Export did not produce an IPA under $EXPORT_PATH" >&2 + exit 1 +fi + +echo "IPA=$IPA" +echo "ARCHIVE=$ARCHIVE_PATH" diff --git a/apps/ios/fastlane/Fastfile b/apps/ios/fastlane/Fastfile new file mode 100644 index 00000000..91316605 --- /dev/null +++ b/apps/ios/fastlane/Fastfile @@ -0,0 +1,33 @@ +opt_out_usage + +default_platform(:ios) + +platform :ios do + desc "Submit an uploaded App Store Connect build to App Review and release it automatically after approval" + lane :submit_review do + version = ENV.fetch("APP_STORE_VERSION") + build_number = ENV.fetch("APP_STORE_BUILD_NUMBER") + + api_key = app_store_connect_api_key( + key_id: ENV.fetch("APP_STORE_CONNECT_API_KEY_ID"), + issuer_id: ENV.fetch("APP_STORE_CONNECT_API_ISSUER_ID"), + key_content: ENV.fetch("APP_STORE_CONNECT_API_KEY_P8_BASE64"), + is_key_content_base64: true, + in_house: false + ) + + deliver( + api_key: api_key, + app_identifier: "org.edgeever.mobile", + app_version: version, + build_number: build_number, + submit_for_review: true, + automatic_release: true, + phased_release: false, + force: true, + skip_binary_upload: true, + skip_metadata: true, + skip_screenshots: true + ) + end +end diff --git a/apps/ios/project.yml b/apps/ios/project.yml index 1f5a426f..58572e90 100644 --- a/apps/ios/project.yml +++ b/apps/ios/project.yml @@ -20,9 +20,11 @@ settings: TARGETED_DEVICE_FAMILY: "1" SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD: false IPHONEOS_DEPLOYMENT_TARGET: "17.0" - CURRENT_PROJECT_VERSION: 1 - MARKETING_VERSION: 1.0.0 - DEVELOPMENT_TEAM: "" + CURRENT_PROJECT_VERSION: 30 + MARKETING_VERSION: 1.12.6 + # Team enables Automatic signing for local Debug/simulator; App Store + # archives override to Manual + distribution profiles in archive-app-store.sh. + DEVELOPMENT_TEAM: 9KA3NM38B6 CODE_SIGN_STYLE: Automatic configs: Debug: debug @@ -64,6 +66,12 @@ targets: ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME: AccentColor SWIFT_STRICT_CONCURRENCY: complete ENABLE_TESTABILITY: true + DEVELOPMENT_TEAM: 9KA3NM38B6 + configs: + Release: + CODE_SIGN_STYLE: Manual + CODE_SIGN_IDENTITY: "Apple Distribution" + PROVISIONING_PROFILE_SPECIFIER: "*[expo] org.edgeever.mobile AppStore 2026-08-01T04:08:38.265Z" info: path: EdgeEver/Resources/Info.plist properties: @@ -104,13 +112,20 @@ targets: - Info.plist settings: base: - PRODUCT_BUNDLE_IDENTIFIER: org.edgeever.mobile.share-extension + # Keep the existing App Store App ID used by the previous RN share extension. + PRODUCT_BUNDLE_IDENTIFIER: org.edgeever.mobile.expo-sharing-extension PRODUCT_NAME: ShareExtension INFOPLIST_FILE: ShareExtension/Info.plist CODE_SIGN_ENTITLEMENTS: ShareExtension/ShareExtension.entitlements GENERATE_INFOPLIST_FILE: false SKIP_INSTALL: true LD_RUNPATH_SEARCH_PATHS: "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks" + DEVELOPMENT_TEAM: 9KA3NM38B6 + configs: + Release: + CODE_SIGN_STYLE: Manual + CODE_SIGN_IDENTITY: "Apple Distribution" + PROVISIONING_PROFILE_SPECIFIER: "*[expo] org.edgeever.mobile.expo-sharing-extension AppStore 2026-08-01T04:09:04.014Z" entitlements: path: ShareExtension/ShareExtension.entitlements properties: