From 2d6980f360b95b2b7fa9e0699de52e69e28a4eef Mon Sep 17 00:00:00 2001 From: Paul Beusterien Date: Mon, 21 Mar 2022 13:28:37 -0700 Subject: [PATCH] Include Swift extensions in zip and Carthage (#9471) --- .github/workflows/zip.yml | 98 +++++++++---------- FirebaseCore/CHANGELOG.md | 4 + FirebaseCoreInternal.podspec | 2 +- .../FirebaseManifest/FirebaseManifest.swift | 34 ++++--- .../Sources/ZipBuilder/CarthageUtils.swift | 2 +- .../Sources/ZipBuilder/FrameworkBuilder.swift | 23 +---- .../Sources/ZipBuilder/ZipBuilder.swift | 39 +++++--- ReleaseTooling/Template/README.md | 39 +++++--- scripts/setup_quickstart_framework.sh | 5 + scripts/test_quickstart_framework.sh | 6 +- scripts/zip_quickstart_test.sh | 42 ++++++++ 11 files changed, 176 insertions(+), 118 deletions(-) create mode 100755 scripts/zip_quickstart_test.sh diff --git a/.github/workflows/zip.yml b/.github/workflows/zip.yml index 0ea1b02a99..384abc43a1 100644 --- a/.github/workflows/zip.yml +++ b/.github/workflows/zip.yml @@ -25,40 +25,40 @@ concurrency: cancel-in-progress: true jobs: - package-release: - # Don't run on private repo. - if: (github.repository == 'Firebase/firebase-ios-sdk' && github.event_name == 'schedule') || github.event_name == 'pull_request' || github.event_name == 'workflow_dispatch' - runs-on: macOS-10.15 - steps: - - uses: actions/checkout@v2 - - uses: mikehardy/buildcache-action@50738c6c77de7f34e66b870e4f8ede333b69d077 - with: - cache_key: ${{ matrix.os }} - - name: Xcode 12.2 - run: sudo xcode-select -s /Applications/Xcode_12.2.app/Contents/Developer - - name: Setup Bundler - run: ./scripts/setup_bundler.sh - - name: ZipBuildingTest - run: | - mkdir -p release_zip_dir - sh -x scripts/build_zip.sh release_zip_dir \ - "${{ github.event.inputs.custom_spec_repos || 'https://github.com/firebase/SpecsStaging.git' }}" - - uses: actions/upload-artifact@v1 - with: - name: Firebase-release-zip-zip - # Zip the entire output directory since the builder adds subdirectories we don't know the - # name of. - path: release_zip_dir - + # TODO: Reenable package-release once v9 merges to master. + # package-release: + # # Don't run on private repo. + # if: (github.repository == 'Firebase/firebase-ios-sdk' && github.event_name == 'schedule') || github.event_name == 'pull_request' || github.event_name == 'workflow_dispatch' + # runs-on: macos-11 + # steps: + # - uses: actions/checkout@v2 + # - uses: mikehardy/buildcache-action@50738c6c77de7f34e66b870e4f8ede333b69d077 + # with: + # cache_key: ${{ matrix.os }} + # - name: Xcode 13.2.1 + # run: sudo xcode-select -s /Applications/Xcode_13.2.1.app/Contents/Developer + # - name: Setup Bundler + # run: ./scripts/setup_bundler.sh + # - name: ZipBuildingTest + # run: | + # mkdir -p release_zip_dir + # sh -x scripts/build_zip.sh release_zip_dir \ + # "${{ github.event.inputs.custom_spec_repos || 'https://github.com/firebase/SpecsStaging.git' }}" + # - uses: actions/upload-artifact@v1 + # with: + # name: Firebase-release-zip-zip + # # Zip the entire output directory since the builder adds subdirectories we don't know the + # # name of. + # path: release_zip_dir build: # Don't run on private repo unless it is a PR. if: (github.repository == 'Firebase/firebase-ios-sdk' && github.event_name == 'schedule') || github.event_name == 'pull_request' || github.event_name == 'workflow_dispatch' - runs-on: macOS-10.15 + runs-on: macos-11 steps: - uses: actions/checkout@v2 - - name: Xcode 12.2 - run: sudo xcode-select -s /Applications/Xcode_12.2.app/Contents/Developer + - name: Xcode 13.2.1 + run: sudo xcode-select -s /Applications/Xcode_13.2.1.app/Contents/Developer - name: Build run: | cd ReleaseTooling @@ -68,14 +68,14 @@ jobs: # Don't run on private repo. if: (github.repository == 'Firebase/firebase-ios-sdk' && github.event_name == 'schedule') || github.event_name == 'pull_request' || github.event_name == 'workflow_dispatch' needs: build - runs-on: macOS-10.15 + runs-on: macos-11 steps: - uses: actions/checkout@v2 - uses: mikehardy/buildcache-action@50738c6c77de7f34e66b870e4f8ede333b69d077 with: cache_key: ${{ matrix.os }} - - name: Xcode 12.2 - run: sudo xcode-select -s /Applications/Xcode_12.2.app/Contents/Developer + - name: Xcode 13.2.1 + run: sudo xcode-select -s /Applications/Xcode_13.2.1.app/Contents/Developer - name: Setup Bundler run: ./scripts/setup_bundler.sh - name: ZipBuildingTest @@ -100,7 +100,7 @@ jobs: signin_secret: ${{ secrets.GHASecretsGPGPassphrase1 }} FRAMEWORK_DIR: "Firebase-actions-dir" SDK: "ABTesting" - runs-on: macOS-10.15 + runs-on: macos-11 steps: - uses: actions/checkout@v2 - name: Get framework dir @@ -150,9 +150,6 @@ jobs: runs-on: macos-11 steps: - uses: actions/checkout@v2 - # Facebook SDK 12.0.1 requires Xcode 13 - - name: Xcode 13.0 - run: sudo xcode-select -s /Applications/Xcode_13.0.app/Contents/Developer - name: Get framework dir uses: actions/download-artifact@v1 with: @@ -191,7 +188,7 @@ jobs: signin_secret: ${{ secrets.GHASecretsGPGPassphrase1 }} FRAMEWORK_DIR: "Firebase-actions-dir" SDK: "Config" - runs-on: macOS-10.15 + runs-on: macos-11 steps: - uses: actions/checkout@v2 - name: Get framework dir @@ -204,10 +201,9 @@ jobs: find "${GITHUB_WORKSPACE}/${FRAMEWORK_DIR}" -name "Firebase*latest.zip" -exec unzip -d "${HOME}"/ios_frameworks/ {} + - name: Setup Swift Quickstart - run: SAMPLE="$SDK" TARGET="${SDK}Example" NON_FIREBASE_SDKS="FirebaseRemoteConfigSwift FirebaseSharedSwift" scripts/setup_quickstart_framework.sh \ + run: SAMPLE="$SDK" TARGET="${SDK}Example" scripts/setup_quickstart_framework.sh \ "${HOME}"/ios_frameworks/Firebase/FirebaseRemoteConfig/* \ - "${HOME}"/ios_frameworks/Firebase/FirebaseAnalytics/* \ - "${HOME}"/ios_frameworks/Firebase/NonFirebaseSDKs/* + "${HOME}"/ios_frameworks/Firebase/FirebaseAnalytics/* - name: Install Secret GoogleService-Info.plist run: scripts/decrypt_gha_secret.sh scripts/gha-encrypted/qs-config.plist.gpg \ quickstart-ios/config/GoogleService-Info.plist "$plist_secret" @@ -231,7 +227,7 @@ jobs: signin_secret: ${{ secrets.GHASecretsGPGPassphrase1 }} FRAMEWORK_DIR: "Firebase-actions-dir" SDK: "Crashlytics" - runs-on: macOS-10.15 + runs-on: macos-11 steps: - uses: actions/checkout@v2 - name: Get framework dir @@ -255,6 +251,8 @@ jobs: chmod +x quickstart-ios/crashlytics/LegacyCrashlyticsQuickstart/upload-symbols # TODO(#8057): Restore Swift Quickstart # - name: Setup swift quickstart + # env: + # LEGACY: true # run: | # SAMPLE="$SDK" TARGET="${SDK}ExampleSwift" NON_FIREBASE_SDKS="ReachabilitySwift" scripts/setup_quickstart_framework.sh \ # "${HOME}"/ios_frameworks/Firebase/NonFirebaseSDKs/* @@ -265,7 +263,10 @@ jobs: env: LEGACY: true run: ([ -z $plist_secret ] || scripts/third_party/travis/retry.sh scripts/test_quickstart_framework.sh "${SDK}") + # TODO(#8057): Restore Swift Quickstart # - name: Test Swift Quickstart + # env: + # LEGACY: true # run: ([ -z $plist_secret ] || scripts/third_party/travis/retry.sh scripts/test_quickstart_framework.sh "${SDK}" swift) - name: Remove data before upload env: @@ -287,7 +288,7 @@ jobs: signin_secret: ${{ secrets.GHASecretsGPGPassphrase1 }} FRAMEWORK_DIR: "Firebase-actions-dir" SDK: "Database" - runs-on: macOS-10.15 + runs-on: macos-11 steps: - uses: actions/checkout@v2 - name: Get framework dir @@ -329,7 +330,7 @@ jobs: signin_secret: ${{ secrets.GHASecretsGPGPassphrase1 }} FRAMEWORK_DIR: "Firebase-actions-dir" SDK: "DynamicLinks" - runs-on: macOS-10.15 + runs-on: macos-11 steps: - uses: actions/checkout@v2 - name: Get framework dir @@ -376,7 +377,7 @@ jobs: signin_secret: ${{ secrets.GHASecretsGPGPassphrase1 }} FRAMEWORK_DIR: "Firebase-actions-dir" SDK: "Firestore" - runs-on: macOS-10.15 + runs-on: macos-11 steps: - uses: actions/checkout@v2 - name: Get framework dir @@ -388,7 +389,7 @@ jobs: mkdir -p "${HOME}"/ios_frameworks/ find "${GITHUB_WORKSPACE}/${FRAMEWORK_DIR}" -name "Firebase*latest.zip" -exec unzip -d "${HOME}"/ios_frameworks/ {} + - name: Setup quickstart - run: SAMPLE="$SDK" TARGET="${SDK}Example" NON_FIREBASE_SDKS="SDWebImage FirebaseAuthUI FirebaseEmailAuthUI FirebaseFirestoreSwift" scripts/setup_quickstart_framework.sh \ + run: SAMPLE="$SDK" TARGET="${SDK}Example" NON_FIREBASE_SDKS="SDWebImage FirebaseAuthUI FirebaseEmailAuthUI" scripts/setup_quickstart_framework.sh \ "${HOME}"/ios_frameworks/Firebase/NonFirebaseSDKs/* \ "${HOME}"/ios_frameworks/Firebase/FirebaseFirestore/* \ "${HOME}"/ios_frameworks/Firebase/FirebaseAuth/* \ @@ -416,7 +417,7 @@ jobs: signin_secret: ${{ secrets.GHASecretsGPGPassphrase1 }} FRAMEWORK_DIR: "Firebase-actions-dir" SDK: "InAppMessaging" - runs-on: macOS-10.15 + runs-on: macos-11 steps: - uses: actions/checkout@v2 - name: Get framework dir @@ -459,7 +460,7 @@ jobs: signin_secret: ${{ secrets.GHASecretsGPGPassphrase1 }} FRAMEWORK_DIR: "Firebase-actions-dir" SDK: "Messaging" - runs-on: macOS-10.15 + runs-on: macos-11 steps: - uses: actions/checkout@v2 - name: Get framework dir @@ -501,7 +502,7 @@ jobs: signin_secret: ${{ secrets.GHASecretsGPGPassphrase1 }} FRAMEWORK_DIR: "Firebase-actions-dir" SDK: "Storage" - runs-on: macOS-10.15 + runs-on: macos-11 steps: - uses: actions/checkout@v2 - name: Get framework dir @@ -518,8 +519,7 @@ jobs: "${HOME}"/ios_frameworks/Firebase/FirebaseAuth/* \ "${HOME}"/ios_frameworks/Firebase/FirebaseAnalytics/* - name: Setup swift quickstart - run: SAMPLE="$SDK" TARGET="${SDK}ExampleSwift" NON_FIREBASE_SDKS="FirebaseStorageSwift" scripts/setup_quickstart_framework.sh \ - "${HOME}"/ios_frameworks/Firebase/NonFirebaseSDKs/* + run: SAMPLE="$SDK" TARGET="${SDK}ExampleSwift" scripts/setup_quickstart_framework.sh - name: Install Secret GoogleService-Info.plist run: scripts/decrypt_gha_secret.sh scripts/gha-encrypted/qs-storage.plist.gpg \ quickstart-ios/storage/GoogleService-Info.plist "$plist_secret" diff --git a/FirebaseCore/CHANGELOG.md b/FirebaseCore/CHANGELOG.md index cf19d3b0c9..d6a77acc78 100644 --- a/FirebaseCore/CHANGELOG.md +++ b/FirebaseCore/CHANGELOG.md @@ -1,3 +1,7 @@ +# Firebase 9.0.0 +- [changed] Firebase now requires at least Xcode 13.2.1. +- [added] The zip and Carthage distibutions now include the Swift extension frameworks. (#7819) + # Firebase 8.10.0 - [fixed] Fixed platform availability checks in Swift Package Manager that may prevent code completion for Analytics APIs on macOS and tvOS. (#9032) diff --git a/FirebaseCoreInternal.podspec b/FirebaseCoreInternal.podspec index 7fd7537f24..14ad2c81ad 100644 --- a/FirebaseCoreInternal.podspec +++ b/FirebaseCoreInternal.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'FirebaseCoreInternal' - s.version = '8.12.0' + s.version = '8.13.0' s.summary = 'APIs only for Firebase internal usage' s.description = <<-DESC diff --git a/ReleaseTooling/Sources/FirebaseManifest/FirebaseManifest.swift b/ReleaseTooling/Sources/FirebaseManifest/FirebaseManifest.swift index b8f5b190e8..95782493cb 100755 --- a/ReleaseTooling/Sources/FirebaseManifest/FirebaseManifest.swift +++ b/ReleaseTooling/Sources/FirebaseManifest/FirebaseManifest.swift @@ -24,31 +24,35 @@ public let shared = Manifest( version: "8.15.0", pods: [ Pod("FirebaseSharedSwift"), - Pod("FirebaseCoreDiagnostics", zip: true), - Pod("FirebaseCore", zip: true), - Pod("FirebaseInstallations", zip: true), + Pod("FirebaseCoreDiagnostics"), + Pod("FirebaseCoreInternal"), + Pod("FirebaseAppCheckInterop"), + Pod("FirebaseAuthInterop"), + Pod("FirebaseMessagingInterop"), + Pod("FirebaseCore"), + Pod("FirebaseInstallations"), Pod("GoogleAppMeasurement", isClosedSource: true), - Pod("FirebaseAnalytics", isClosedSource: true, zip: true), - Pod("FirebaseAnalyticsSwift", isBeta: true), + Pod("FirebaseAnalytics", isClosedSource: true), + Pod("FirebaseAnalyticsSwift", isBeta: true, zip: true), Pod("FirebaseABTesting", zip: true), Pod("FirebaseAppCheck", isBeta: true, zip: true), - Pod("FirebaseRemoteConfig", zip: true), - Pod("FirebaseRemoteConfigSwift", isBeta: true), + Pod("FirebaseRemoteConfig"), + Pod("FirebaseRemoteConfigSwift", isBeta: true, zip: true), Pod("FirebaseAppDistribution", isBeta: true, platforms: ["ios"], zip: true), Pod("FirebaseAuth", zip: true), Pod("FirebaseCrashlytics", zip: true), - Pod("FirebaseDatabase", zip: true), - Pod("FirebaseDatabaseSwift", isBeta: true), + Pod("FirebaseDatabase"), + Pod("FirebaseDatabaseSwift", isBeta: true, zip: true), Pod("FirebaseDynamicLinks", platforms: ["ios"], zip: true), - Pod("FirebaseFirestore", allowWarnings: true, zip: true), - Pod("FirebaseFirestoreSwift", isBeta: true), + Pod("FirebaseFirestore", allowWarnings: true), + Pod("FirebaseFirestoreSwift", isBeta: true, zip: true), Pod("FirebaseFunctions", zip: true), - Pod("FirebaseInAppMessaging", isBeta: true, platforms: ["ios"], zip: true), - Pod("FirebaseInAppMessagingSwift", isBeta: true, platforms: ["ios"]), + Pod("FirebaseInAppMessaging", isBeta: true, platforms: ["ios"]), + Pod("FirebaseInAppMessagingSwift", isBeta: true, platforms: ["ios"], zip: true), Pod("FirebaseMessaging", zip: true), Pod("FirebasePerformance", platforms: ["ios", "tvos"], zip: true), - Pod("FirebaseStorage", zip: true), - Pod("FirebaseStorageSwift", isBeta: true), + Pod("FirebaseStorage"), + Pod("FirebaseStorageSwift", isBeta: true, zip: true), Pod("FirebaseMLModelDownloader", isBeta: true, zip: true), Pod("Firebase", allowWarnings: true, zip: true), ] diff --git a/ReleaseTooling/Sources/ZipBuilder/CarthageUtils.swift b/ReleaseTooling/Sources/ZipBuilder/CarthageUtils.swift index 5bd451aacb..2d2c028a00 100644 --- a/ReleaseTooling/Sources/ZipBuilder/CarthageUtils.swift +++ b/ReleaseTooling/Sources/ZipBuilder/CarthageUtils.swift @@ -107,7 +107,7 @@ extension CarthageUtils { // Analytics includes all the Core frameworks and Firebase module, do extra work to package // it. - if product == "FirebaseAnalytics" { + if product == "FirebaseAnalyticsSwift" { createFirebaseFramework(version: firebaseVersion, inDir: fullPath, rootDir: packagedDir, diff --git a/ReleaseTooling/Sources/ZipBuilder/FrameworkBuilder.swift b/ReleaseTooling/Sources/ZipBuilder/FrameworkBuilder.swift index 9a8eb82252..19660a015d 100755 --- a/ReleaseTooling/Sources/ZipBuilder/FrameworkBuilder.swift +++ b/ReleaseTooling/Sources/ZipBuilder/FrameworkBuilder.swift @@ -189,7 +189,7 @@ struct FrameworkBuilder { var archs = targetPlatform.archs.map { $0.rawValue }.joined(separator: " ") // The 32 bit archs do not build for iOS 11. - if framework == "FirebaseAppCheck" { + if framework == "FirebaseAppCheck" || framework.hasSuffix("Swift") { if targetPlatform == .iOSDevice { archs = "arm64" } else if targetPlatform == .iOSSimulator { @@ -390,26 +390,7 @@ struct FrameworkBuilder { } catch { fatalError("Error while enumerating files \(headersDir): \(error.localizedDescription)") } - // Verify Firebase frameworks include an explicit umbrella header for Firebase.h. - if framework.hasPrefix("Firebase") || framework == "GoogleDataTransport", - framework != "FirebaseCoreDiagnostics", - framework != "FirebaseUI", - framework != "FirebaseMLModelDownloader", - !framework.hasSuffix("Swift") { - // Delete CocoaPods generated umbrella and use pre-generated one. - do { - try fileManager.removeItem(at: umbrellaHeaderURL) - } catch let error as NSError { - fatalError("Failed to delete: \(umbrellaHeaderURL). Error: \(error.domain)") - } - umbrellaHeader = "\(framework).h" - let frameworkHeader = headersDir.appendingPathComponent(umbrellaHeader) - guard fileManager.fileExists(atPath: frameworkHeader.path) else { - fatalError("Missing explicit umbrella header for \(framework).") - } - } else { - umbrellaHeader = umbrellaHeaderURL.lastPathComponent - } + umbrellaHeader = umbrellaHeaderURL.lastPathComponent } // Copy the Headers over. let headersDestination = frameworkDir.appendingPathComponent("Headers") diff --git a/ReleaseTooling/Sources/ZipBuilder/ZipBuilder.swift b/ReleaseTooling/Sources/ZipBuilder/ZipBuilder.swift index faa7e3e6d9..a893aaa416 100644 --- a/ReleaseTooling/Sources/ZipBuilder/ZipBuilder.swift +++ b/ReleaseTooling/Sources/ZipBuilder/ZipBuilder.swift @@ -218,6 +218,11 @@ struct ZipBuilder { // Also AppCheck must be built after other pods so that its restricted architecture // selection does not restrict any of its dependencies. var sortedPods = podsToBuild.keys.sorted() + + // Interop pods are protocols only and should not be built. + sortedPods.removeAll(where: { value in + value.hasSuffix("Interop") + }) sortedPods.removeAll(where: { value in value == "FirebaseAppCheck" }) @@ -314,7 +319,7 @@ struct ZipBuilder { /// - Throws: One of many errors that could have happened during the build phase. func buildAndAssembleFirebaseRelease(templateDir: URL) throws -> ReleaseArtifacts { let manifest = FirebaseManifest.shared - var podsToInstall = manifest.pods.filter { $0.zip }.map { + var podsToInstall = manifest.pods.map { CocoaPodUtils.VersionedPod(name: $0.name, version: manifest.versionString($0), platforms: $0.platforms) @@ -412,7 +417,8 @@ struct ZipBuilder { do { // This returns the Analytics directory and a list of framework names that Analytics requires. /// Example: ["FirebaseInstallations, "GoogleAppMeasurement", "nanopb", <...>] - let (dir, frameworks) = try installAndCopyFrameworks(forPod: "FirebaseAnalytics", + let (dir, frameworks) = try installAndCopyFrameworks(forPod: "FirebaseAnalyticsSwift", + inFolder: "FirebaseAnalytics", withInstalledPods: installedPods, rootZipDir: zipDir, builtFrameworks: frameworksToAssemble) @@ -423,7 +429,7 @@ struct ZipBuilder { } // Start the README dependencies string with the frameworks built in Analytics. - var readmeDeps = dependencyString(for: "FirebaseAnalytics", + var readmeDeps = dependencyString(for: "FirebaseAnalyticsSwift", in: analyticsDir, frameworks: analyticsFrameworks) @@ -432,29 +438,34 @@ struct ZipBuilder { let analyticsPods = analyticsFrameworks.map { $0.replacingOccurrences(of: ".framework", with: "") } + let manifest = FirebaseManifest.shared + let firebaseZipPods = manifest.pods.filter { $0.zip }.map { $0.name } + // Skip Analytics and the pods bundled with it. let remainingPods = installedPods.filter { - $0.key != "FirebaseAnalytics" && - $0.key != "FirebaseCore" && - $0.key != "FirebaseCoreDiagnostics" && - $0.key != "FirebaseInstallations" && - $0.key != "Firebase" && - podsToInstall.map { $0.name }.contains($0.key) + $0.key == "Google-Mobile-Ads-SDK" || + $0.key == "GoogleSignIn" || + (firebaseZipPods.contains($0.key) && + $0.key != "FirebaseAnalyticsSwift" && + $0.key != "Firebase" && + podsToInstall.map { $0.name }.contains($0.key)) }.sorted { $0.key < $1.key } for pod in remainingPods { + let folder = pod.key.replacingOccurrences(of: "Swift", with: "") do { if frameworksToAssemble[pod.key] == nil { - // Continue if the pod wasn't built - like Swift frameworks for Carthage. + // Continue if the pod wasn't built. continue } let (productDir, podFrameworks) = try installAndCopyFrameworks(forPod: pod.key, + inFolder: folder, withInstalledPods: installedPods, rootZipDir: zipDir, builtFrameworks: frameworksToAssemble, podsToIgnore: analyticsPods) // Update the README. - readmeDeps += dependencyString(for: pod.key, in: productDir, frameworks: podFrameworks) + readmeDeps += dependencyString(for: folder, in: productDir, frameworks: podFrameworks) } catch { fatalError("Could not copy frameworks from \(pod) into the zip file: \(error)") } @@ -464,7 +475,7 @@ struct ZipBuilder { // individual framework. // TODO: Investigate changing the zip distro to also have Resources in the .frameworks to // enable different platform Resources. - let productPath = zipDir.appendingPathComponent(pod.key) + let productPath = zipDir.appendingPathComponent(folder) let contents = try fileManager.contentsOfDirectory(atPath: productPath.path) for fileOrFolder in contents { let xcPath = productPath.appendingPathComponent(fileOrFolder) @@ -578,6 +589,7 @@ struct ZipBuilder { for podName in installedPods { // Skip the Firebase pod and specifically ignored frameworks. guard podName != "Firebase", + !podName.hasSuffix("Interop"), !podsToIgnore.contains(podName) else { continue } @@ -701,6 +713,7 @@ struct ZipBuilder { /// that were copied for this subspec. @discardableResult func installAndCopyFrameworks(forPod podName: String, + inFolder folder: String, withInstalledPods installedPods: [String: CocoaPodUtils.PodInfo], rootZipDir: URL, builtFrameworks: [String: [URL]], @@ -713,7 +726,7 @@ struct ZipBuilder { let dedupedPods = Array(Set(podsToCopy)) // Copy the frameworks into the proper product directory. - let productDir = rootZipDir.appendingPathComponent(podName) + let productDir = rootZipDir.appendingPathComponent(folder) let namedFrameworks = try copyFrameworks(fromPods: dedupedPods, toDirectory: productDir, frameworkLocations: builtFrameworks, diff --git a/ReleaseTooling/Template/README.md b/ReleaseTooling/Template/README.md index 13fe06fadd..487d2a8c41 100644 --- a/ReleaseTooling/Template/README.md +++ b/ReleaseTooling/Template/README.md @@ -1,15 +1,15 @@ # Firebase iOS SDKs This directory contains the full Firebase iOS distribution, packaged as -static frameworks and xcframeworks that can be integrated into your app. +static xcframeworks that can be integrated into your app. # Integration Instructions -Each Firebase component requires several frameworks in order to function -properly. Each section below lists the frameworks you'll need to include +Each Firebase component requires several xcframeworks in order to function +properly. Each section below lists the xcframeworks you'll need to include in your project in order to use that Firebase SDK in your application. -Xcode 12.2 or newer is required. +Xcode 13.2.1 or newer is required. To integrate a Firebase SDK with your app: @@ -17,13 +17,16 @@ To integrate a Firebase SDK with your app: 2. Make sure you have an Xcode project open in Xcode. 3. In Xcode, hit `⌘-1` to open the Project Navigator pane. It will open on left side of the Xcode window if it wasn't already open. -4. Remove any existing Firebase frameworks from your project. -5. Drag each framework from the "FirebaseAnalytics" directory into the Project +4. Remove any existing Firebase xcframeworks from your project. +5. Drag each xcframework from the "FirebaseAnalytics" directory into the Project Navigator pane. In the dialog box that appears, make sure the target you want the framework to be added to has a checkmark next to it, and that - you've selected "Copy items if needed". If you want to include - community-based Catalyst support, only drag the xcframeworks and skip the - plain frameworks. + you've selected "Copy items if needed". + + *If the app does not use any Firebase Swift specific APIs, you do not need + to copy any xcframeworks whose name includes "Swift" for this and the next + step.* + 6. Drag each framework from the directory named after the SDK into the Project Navigator pane. Note that there may be no additional frameworks, in which case this directory will be empty. For instance, if you want the Database @@ -50,13 +53,16 @@ To integrate a Firebase SDK with your app: 9. Drag the `Firebase.h` header in this directory into your project. This will allow you to `#import "Firebase.h"` and start using any Firebase SDK that you have. -10. If you're using Swift or want to use modules from Objective C, drag - `module.modulemap` into your project and update the +10. Drag `module.modulemap` into your project and update the "User Header Search Paths" in your project's Build Settings to include the directory that contains the added module map. -11. You're done! Compile your target and start using Firebase. +11. If your app does not include any Swift implementation, you may need to add + a dummy Swift file to the app to prevent Swift system library missing + symbol linker errors. See + https://forums.swift.org/t/using-binary-swift-sdks-from-non-swift-apps/55989. +12. You're done! Compile your target and start using Firebase. -If you want to add another SDK, repeat the steps above with the frameworks for +If you want to add another SDK, repeat the steps above with the xcframeworks for the new SDK. You only need to add each framework once, so if you've already added a framework for one SDK, you don't need to add it again. Note that some frameworks are required by multiple SDKs, and so appear in multiple folders. @@ -71,8 +77,9 @@ frameworks and libraries listed in each Firebase framework's indicator that not all system libraries are being brought into your build automatically. -"(~> X)" below means that the SDK requires all of the frameworks from X. You -should make sure to include all of the frameworks from X when including the SDK. +"(~> X)" below means that the SDK requires all of the xcframeworks from X. You +should make sure to include all of the xcframeworks from X when including the +SDK. __INTEGRATION__ # Samples @@ -89,7 +96,7 @@ to create your own custom binary frameworks. # Versions -The frameworks in this directory map to these versions of the Firebase SDKs in +The xcframeworks in this directory map to these versions of the Firebase SDKs in CocoaPods. __VERSIONS__ diff --git a/scripts/setup_quickstart_framework.sh b/scripts/setup_quickstart_framework.sh index 69f336e19d..78f0d50bdb 100755 --- a/scripts/setup_quickstart_framework.sh +++ b/scripts/setup_quickstart_framework.sh @@ -28,6 +28,11 @@ if [[ ! -z "$LEGACY" ]]; then cd "Legacy${SAMPLE}Quickstart" fi +# Make sure the Xcode project has at least one Swift file. +# See https://forums.swift.org/t/using-binary-swift-sdks-from-non-swift-apps/55989 +touch foo.swift +"${REPO}"/scripts/update_xcode_target.rb "${SAMPLE}Example.xcodeproj" "${SAMPLE}Example" foo.swift + mkdir -p Firebase/ # Create non Firebase Frameworks and move to Firebase/ dir. if [[ ! -z "$NON_FIREBASE_SDKS" ]]; then diff --git a/scripts/test_quickstart_framework.sh b/scripts/test_quickstart_framework.sh index 221c660b23..8b390536a2 100755 --- a/scripts/test_quickstart_framework.sh +++ b/scripts/test_quickstart_framework.sh @@ -23,14 +23,16 @@ set -xeuo pipefail sample="$1" platform="${2-}" +REPO=`pwd` + # Source function to check if CI secrets are available. source scripts/check_secrets.sh if check_secrets; then cd quickstart-ios if [ "$platform" = "swift" ]; then - have_secrets=true SAMPLE="$sample" SWIFT_SUFFIX="Swift" scripts/framework_test.sh + have_secrets=true SAMPLE="$sample" SWIFT_SUFFIX="Swift" "${REPO}"/scripts/zip_quickstart_test.sh else - have_secrets=true SAMPLE="$sample" scripts/framework_test.sh + have_secrets=true SAMPLE="$sample" "${REPO}"/scripts/zip_quickstart_test.sh fi fi diff --git a/scripts/zip_quickstart_test.sh b/scripts/zip_quickstart_test.sh new file mode 100755 index 0000000000..9aec359fa4 --- /dev/null +++ b/scripts/zip_quickstart_test.sh @@ -0,0 +1,42 @@ +#!/usr/bin/env bash + +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +# Build the quickstart. If we're running on the main repo (not a fork), we +# also run the tests along with the decoded GoogleService-Info.plist files. + +set -eo pipefail + +set -x + +EXIT_STATUS=0 + +cd "${SAMPLE}" + +if [[ ! -z "$LEGACY" ]]; then + cd "Legacy${SAMPLE}Quickstart" +fi + +( +xcodebuild \ +-project ${SAMPLE}Example.xcodeproj \ +-scheme ${SAMPLE}Example${SWIFT_SUFFIX} \ +-destination 'platform=iOS Simulator,name=iPhone 11 Pro' "SWIFT_VERSION=5.3" "OTHER_LDFLAGS=\$(OTHER_LDFLAGS) -ObjC" "FRAMEWORK_SEARCH_PATHS= \$(PROJECT_DIR)/Firebase/" HEADER_SEARCH_PATHS='$(PROJECT_DIR)/Firebase' \ +build \ +test \ +) || EXIT_STATUS=$? + +exit $EXIT_STATUS