build.sh 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637
  1. #!/usr/bin/env bash
  2. # Copyright 2018 Google
  3. #
  4. # Licensed under the Apache License, Version 2.0 (the "License");
  5. # you may not use this file except in compliance with the License.
  6. # You may obtain a copy of the License at
  7. #
  8. # http://www.apache.org/licenses/LICENSE-2.0
  9. #
  10. # Unless required by applicable law or agreed to in writing, software
  11. # distributed under the License is distributed on an "AS IS" BASIS,
  12. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. # See the License for the specific language governing permissions and
  14. # limitations under the License.
  15. # USAGE: build.sh product [platform] [method]
  16. #
  17. # Builds the given product for the given platform using the given build method
  18. function pod_gen() {
  19. # Call pod gen with a podspec and additional optional arguments.
  20. bundle exec pod gen --local-sources=./ --sources=https://github.com/firebase/SpecsDev.git,https://github.com/firebase/SpecsStaging.git,https://cdn.cocoapods.org/ "$@"
  21. }
  22. set -euo pipefail
  23. if [[ $# -lt 1 ]]; then
  24. cat 1>&2 <<EOF
  25. USAGE: $0 product [platform] [method]
  26. product can be one of:
  27. Firebase
  28. Firestore
  29. InAppMessaging
  30. Messaging
  31. MessagingSample
  32. MLModelDownloaderSample
  33. RemoteConfig
  34. RemoteConfigSample
  35. Storage
  36. StorageSwift
  37. SymbolCollision
  38. GoogleDataTransport
  39. Performance
  40. platform can be one of:
  41. iOS (default)
  42. macOS
  43. tvOS
  44. watchOS
  45. catalyst
  46. method can be one of:
  47. xcodebuild (default)
  48. cmake
  49. unit
  50. integration
  51. spm
  52. Optionally, reads the environment variable SANITIZERS. If set, it is expected to
  53. be a string containing a space-separated list with some of the following
  54. elements:
  55. asan
  56. tsan
  57. ubsan
  58. EOF
  59. exit 1
  60. fi
  61. product="$1"
  62. platform="iOS"
  63. if [[ $# -gt 1 ]]; then
  64. platform="$2"
  65. fi
  66. method="xcodebuild"
  67. if [[ $# -gt 2 ]]; then
  68. method="$3"
  69. fi
  70. echo "Building $product for $platform using $method"
  71. if [[ -n "${SANITIZERS:-}" ]]; then
  72. echo "Using sanitizers: $SANITIZERS"
  73. fi
  74. scripts_dir=$(dirname "${BASH_SOURCE[0]}")
  75. firestore_emulator="${scripts_dir}/run_firestore_emulator.sh"
  76. database_emulator="${scripts_dir}/run_database_emulator.sh"
  77. system=$(uname -s)
  78. case "$system" in
  79. Darwin)
  80. xcode_version=$(xcodebuild -version | head -n 1)
  81. xcode_version="${xcode_version/Xcode /}"
  82. xcode_major="${xcode_version/.*/}"
  83. ;;
  84. *)
  85. xcode_major="0"
  86. ;;
  87. esac
  88. # Source function to check if CI secrets are available.
  89. source scripts/check_secrets.sh
  90. # Runs xcodebuild with the given flags, piping output to xcpretty
  91. # If xcodebuild fails with known error codes, retries once.
  92. function RunXcodebuild() {
  93. echo xcodebuild "$@"
  94. xcpretty_cmd=(xcpretty)
  95. if [[ -n "${TRAVIS:-}" ]]; then
  96. # The formatter argument takes a file location of a formatter.
  97. # The xcpretty-travis-formatter binary prints its location on stdout.
  98. xcpretty_cmd+=(-f $(xcpretty-travis-formatter))
  99. fi
  100. result=0
  101. xcodebuild "$@" | tee xcodebuild.log | "${xcpretty_cmd[@]}" || result=$?
  102. if [[ $result == 65 ]]; then
  103. ExportLogs "$@"
  104. echo "xcodebuild exited with 65, retrying" 1>&2
  105. sleep 5
  106. result=0
  107. xcodebuild "$@" | tee xcodebuild.log | "${xcpretty_cmd[@]}" || result=$?
  108. fi
  109. if [[ $result != 0 ]]; then
  110. echo "xcodebuild exited with $result" 1>&2
  111. ExportLogs "$@"
  112. return $result
  113. fi
  114. }
  115. # Exports any logs output captured in the xcresult
  116. function ExportLogs() {
  117. python "${scripts_dir}/xcresult_logs.py" "$@"
  118. }
  119. if [[ "$xcode_major" -lt 11 ]]; then
  120. ios_flags=(
  121. -sdk 'iphonesimulator'
  122. -destination 'platform=iOS Simulator,name=iPhone 7'
  123. )
  124. else
  125. ios_flags=(
  126. -sdk 'iphonesimulator'
  127. -destination 'platform=iOS Simulator,name=iPhone 11'
  128. )
  129. fi
  130. ipad_flags=(
  131. -sdk 'iphonesimulator'
  132. -destination 'platform=iOS Simulator,name=iPad Pro (9.7-inch)'
  133. )
  134. macos_flags=(
  135. -sdk 'macosx'
  136. -destination 'platform=OS X,arch=x86_64'
  137. )
  138. tvos_flags=(
  139. -sdk "appletvsimulator"
  140. -destination 'platform=tvOS Simulator,name=Apple TV'
  141. )
  142. watchos_flags=(
  143. -destination 'platform=iOS Simulator,name=iPhone 11 Pro'
  144. )
  145. catalyst_flags=(
  146. ARCHS=x86_64 VALID_ARCHS=x86_64 SUPPORTS_MACCATALYST=YES -sdk macosx
  147. -destination platform="macOS,variant=Mac Catalyst" TARGETED_DEVICE_FAMILY=2
  148. CODE_SIGN_IDENTITY=- CODE_SIGNING_REQUIRED=NO CODE_SIGNING_ALLOWED=NO
  149. )
  150. # Compute standard flags for all platforms
  151. case "$platform" in
  152. iOS)
  153. xcb_flags=("${ios_flags[@]}")
  154. gen_platform=ios
  155. ;;
  156. iPad)
  157. xcb_flags=("${ipad_flags[@]}")
  158. ;;
  159. macOS)
  160. xcb_flags=("${macos_flags[@]}")
  161. gen_platform=macos
  162. ;;
  163. tvOS)
  164. xcb_flags=("${tvos_flags[@]}")
  165. gen_platform=tvos
  166. ;;
  167. watchOS)
  168. xcb_flags=("${watchos_flags[@]}")
  169. ;;
  170. catalyst)
  171. xcb_flags=("${catalyst_flags[@]}")
  172. ;;
  173. all)
  174. xcb_flags=()
  175. ;;
  176. Linux)
  177. xcb_flags=()
  178. ;;
  179. *)
  180. echo "Unknown platform '$platform'" 1>&2
  181. exit 1
  182. ;;
  183. esac
  184. xcb_flags+=(
  185. ONLY_ACTIVE_ARCH=YES
  186. CODE_SIGNING_REQUIRED=NO
  187. CODE_SIGNING_ALLOWED=YES
  188. COMPILER_INDEX_STORE_ENABLE=NO
  189. )
  190. # TODO(varconst): Add --warn-unused-vars and --warn-uninitialized.
  191. # Right now, it makes the log overflow on Travis because many of our
  192. # dependencies don't build cleanly this way.
  193. cmake_options=(
  194. -Wdeprecated
  195. -DCMAKE_BUILD_TYPE=Debug
  196. )
  197. if [[ -n "${SANITIZERS:-}" ]]; then
  198. for sanitizer in $SANITIZERS; do
  199. case "$sanitizer" in
  200. asan)
  201. xcb_flags+=(
  202. -enableAddressSanitizer YES
  203. )
  204. cmake_options+=(
  205. -DWITH_ASAN=ON
  206. )
  207. ;;
  208. tsan)
  209. xcb_flags+=(
  210. -enableThreadSanitizer YES
  211. )
  212. cmake_options+=(
  213. -DWITH_TSAN=ON
  214. )
  215. ;;
  216. ubsan)
  217. xcb_flags+=(
  218. -enableUndefinedBehaviorSanitizer YES
  219. )
  220. cmake_options+=(
  221. -DWITH_UBSAN=ON
  222. )
  223. ;;
  224. *)
  225. echo "Unknown sanitizer '$sanitizer'" 1>&2
  226. exit 1
  227. ;;
  228. esac
  229. done
  230. fi
  231. case "$product-$platform-$method" in
  232. FirebasePod-iOS-*)
  233. RunXcodebuild \
  234. -workspace 'CoreOnly/Tests/FirebasePodTest/FirebasePodTest.xcworkspace' \
  235. -scheme "FirebasePodTest" \
  236. "${xcb_flags[@]}" \
  237. build
  238. ;;
  239. Auth-*-xcodebuild)
  240. if check_secrets; then
  241. RunXcodebuild \
  242. -workspace 'FirebaseAuth/Tests/Sample/AuthSample.xcworkspace' \
  243. -scheme "Auth_ApiTests" \
  244. "${xcb_flags[@]}" \
  245. build \
  246. test
  247. RunXcodebuild \
  248. -workspace 'FirebaseAuth/Tests/Sample/AuthSample.xcworkspace' \
  249. -scheme "SwiftApiTests" \
  250. "${xcb_flags[@]}" \
  251. build \
  252. test
  253. fi
  254. ;;
  255. InAppMessaging-*-xcodebuild)
  256. RunXcodebuild \
  257. -workspace 'FirebaseInAppMessaging/Tests/Integration/DefaultUITestApp/InAppMessagingDisplay-Sample.xcworkspace' \
  258. -scheme 'FiamDisplaySwiftExample' \
  259. "${xcb_flags[@]}" \
  260. build \
  261. test
  262. ;;
  263. Firestore-*-xcodebuild)
  264. "${firestore_emulator}" start
  265. trap '"${firestore_emulator}" stop' ERR EXIT
  266. RunXcodebuild \
  267. -workspace 'Firestore/Example/Firestore.xcworkspace' \
  268. -scheme "Firestore_IntegrationTests_$platform" \
  269. -enableCodeCoverage YES \
  270. "${xcb_flags[@]}" \
  271. build \
  272. test
  273. ;;
  274. Firestore-macOS-cmake | Firestore-Linux-cmake)
  275. "${firestore_emulator}" start
  276. trap '"${firestore_emulator}" stop' ERR EXIT
  277. (
  278. test -d build || mkdir build
  279. cd build
  280. echo "Preparing cmake build ..."
  281. cmake -G Ninja "${cmake_options[@]}" ..
  282. echo "Building cmake build ..."
  283. ninja -k 10 all
  284. ctest --output-on-failure
  285. )
  286. ;;
  287. SymbolCollision-*-*)
  288. RunXcodebuild \
  289. -workspace 'SymbolCollisionTest/SymbolCollisionTest.xcworkspace' \
  290. -scheme "SymbolCollisionTest" \
  291. "${xcb_flags[@]}" \
  292. build
  293. ;;
  294. Messaging-*-xcodebuild)
  295. pod_gen FirebaseMessaging.podspec --platforms=ios
  296. RunXcodebuild \
  297. -workspace 'gen/FirebaseMessaging/FirebaseMessaging.xcworkspace' \
  298. -scheme "FirebaseMessaging-Unit-unit" \
  299. "${ios_flags[@]}" \
  300. "${xcb_flags[@]}" \
  301. build \
  302. test
  303. if check_secrets; then
  304. # Integration tests are only run on iOS to minimize flake failures.
  305. RunXcodebuild \
  306. -workspace 'gen/FirebaseMessaging/FirebaseMessaging.xcworkspace' \
  307. -scheme "FirebaseMessaging-Unit-integration" \
  308. "${ios_flags[@]}" \
  309. "${xcb_flags[@]}" \
  310. build \
  311. test
  312. fi
  313. pod_gen FirebaseMessaging.podspec --platforms=macos --clean
  314. RunXcodebuild \
  315. -workspace 'gen/FirebaseMessaging/FirebaseMessaging.xcworkspace' \
  316. -scheme "FirebaseMessaging-Unit-unit" \
  317. "${macos_flags[@]}" \
  318. "${xcb_flags[@]}" \
  319. build \
  320. test
  321. pod_gen FirebaseMessaging.podspec --platforms=tvos --clean
  322. RunXcodebuild \
  323. -workspace 'gen/FirebaseMessaging/FirebaseMessaging.xcworkspace' \
  324. -scheme "FirebaseMessaging-Unit-unit" \
  325. "${tvos_flags[@]}" \
  326. "${xcb_flags[@]}" \
  327. build \
  328. test
  329. ;;
  330. MessagingSample-*-*)
  331. if check_secrets; then
  332. RunXcodebuild \
  333. -workspace 'FirebaseMessaging/Apps/Sample/Sample.xcworkspace' \
  334. -scheme "Sample" \
  335. "${xcb_flags[@]}" \
  336. build
  337. fi
  338. ;;
  339. MLModelDownloaderSample-*-*)
  340. if check_secrets; then
  341. RunXcodebuild \
  342. -workspace 'FirebaseMLModelDownloader/Apps/Sample/MLDownloaderTestApp.xcworkspace' \
  343. -scheme "MLDownloaderTestApp" \
  344. "${xcb_flags[@]}" \
  345. build
  346. fi
  347. ;;
  348. SegmentationSample-*-*)
  349. RunXcodebuild \
  350. -workspace 'FirebaseSegmentation/Tests/Sample/SegmentationSampleApp.xcworkspace' \
  351. -scheme "SegmentationSampleApp" \
  352. "${xcb_flags[@]}" \
  353. build
  354. ;;
  355. Database-*-unit)
  356. pod_gen FirebaseDatabase.podspec --platforms="${gen_platform}"
  357. RunXcodebuild \
  358. -workspace 'gen/FirebaseDatabase/FirebaseDatabase.xcworkspace' \
  359. -scheme "FirebaseDatabase-Unit-unit" \
  360. "${xcb_flags[@]}" \
  361. build \
  362. test
  363. ;;
  364. Database-*-integration)
  365. "${database_emulator}" start
  366. trap '"${database_emulator}" stop' ERR EXIT
  367. pod_gen FirebaseDatabase.podspec --platforms="${gen_platform}"
  368. RunXcodebuild \
  369. -workspace 'gen/FirebaseDatabase/FirebaseDatabase.xcworkspace' \
  370. -scheme "FirebaseDatabase-Unit-integration" \
  371. "${xcb_flags[@]}" \
  372. build \
  373. test
  374. ;;
  375. RemoteConfig-*-unit)
  376. pod_gen FirebaseRemoteConfig.podspec --platforms="${gen_platform}"
  377. RunXcodebuild \
  378. -workspace 'gen/FirebaseRemoteConfig/FirebaseRemoteConfig.xcworkspace' \
  379. -scheme "FirebaseRemoteConfig-Unit-unit" \
  380. "${xcb_flags[@]}" \
  381. build \
  382. test
  383. ;;
  384. RemoteConfig-*-fakeconsole)
  385. pod_gen FirebaseRemoteConfig.podspec --platforms="${gen_platform}"
  386. RunXcodebuild \
  387. -workspace 'gen/FirebaseRemoteConfig/FirebaseRemoteConfig.xcworkspace' \
  388. -scheme "FirebaseRemoteConfig-Unit-fake-console-tests" \
  389. "${xcb_flags[@]}" \
  390. build \
  391. test
  392. ;;
  393. RemoteConfig-*-integration)
  394. pod_gen FirebaseRemoteConfig.podspec --platforms="${gen_platform}"
  395. RunXcodebuild \
  396. -workspace 'gen/FirebaseRemoteConfig/FirebaseRemoteConfig.xcworkspace' \
  397. -scheme "FirebaseRemoteConfig-Unit-swift-api-tests" \
  398. "${xcb_flags[@]}" \
  399. build \
  400. test
  401. ;;
  402. RemoteConfigSample-*-*)
  403. RunXcodebuild \
  404. -workspace 'FirebaseRemoteConfig/Tests/Sample/RemoteConfigSampleApp.xcworkspace' \
  405. -scheme "RemoteConfigSampleApp" \
  406. "${xcb_flags[@]}" \
  407. build
  408. ;;
  409. Storage-*-xcodebuild)
  410. pod_gen FirebaseStorage.podspec --platforms=ios
  411. RunXcodebuild \
  412. -workspace 'gen/FirebaseStorage/FirebaseStorage.xcworkspace' \
  413. -scheme "FirebaseStorage-Unit-unit" \
  414. "${ios_flags[@]}" \
  415. "${xcb_flags[@]}" \
  416. build \
  417. test
  418. if check_secrets; then
  419. # Integration tests are only run on iOS to minimize flake failures.
  420. RunXcodebuild \
  421. -workspace 'gen/FirebaseStorage/FirebaseStorage.xcworkspace' \
  422. -scheme "FirebaseStorage-Unit-integration" \
  423. "${ios_flags[@]}" \
  424. "${xcb_flags[@]}" \
  425. build \
  426. test
  427. RunXcodebuild \
  428. -workspace 'gen/FirebaseStorage/FirebaseStorage.xcworkspace' \
  429. -scheme "FirebaseStorage-Unit-swift-integration" \
  430. "${ios_flags[@]}" \
  431. "${xcb_flags[@]}" \
  432. build \
  433. test
  434. fi
  435. pod_gen FirebaseStorage.podspec --platforms=macos --clean
  436. RunXcodebuild \
  437. -workspace 'gen/FirebaseStorage/FirebaseStorage.xcworkspace' \
  438. -scheme "FirebaseStorage-Unit-unit" \
  439. "${macos_flags[@]}" \
  440. "${xcb_flags[@]}" \
  441. build \
  442. test
  443. pod_gen FirebaseStorage.podspec --platforms=tvos --clean
  444. RunXcodebuild \
  445. -workspace 'gen/FirebaseStorage/FirebaseStorage.xcworkspace' \
  446. -scheme "FirebaseStorage-Unit-unit" \
  447. "${tvos_flags[@]}" \
  448. "${xcb_flags[@]}" \
  449. build \
  450. test
  451. ;;
  452. StorageSwift-*-xcodebuild)
  453. pod_gen FirebaseStorageSwift.podspec --platforms=ios
  454. if check_secrets; then
  455. # Integration tests are only run on iOS to minimize flake failures.
  456. RunXcodebuild \
  457. -workspace 'gen/FirebaseStorageSwift/FirebaseStorageSwift.xcworkspace' \
  458. -scheme "FirebaseStorageSwift-Unit-integration" \
  459. "${ios_flags[@]}" \
  460. "${xcb_flags[@]}" \
  461. build \
  462. test
  463. fi
  464. ;;
  465. GoogleDataTransport-watchOS-xcodebuild)
  466. RunXcodebuild \
  467. -workspace 'GoogleDataTransport/GDTWatchOSTestApp/GDTWatchOSTestApp.xcworkspace' \
  468. -scheme "GDTWatchOSTestAppWatchKitApp" \
  469. "${xcb_flags[@]}" \
  470. build
  471. RunXcodebuild \
  472. -workspace 'GoogleDataTransport/GDTCCTWatchOSTestApp/GDTCCTWatchOSTestApp.xcworkspace' \
  473. -scheme "GDTCCTWatchOSIndependentTestAppWatchKitApp" \
  474. "${xcb_flags[@]}" \
  475. build
  476. RunXcodebuild \
  477. -workspace 'GoogleDataTransport/GDTCCTWatchOSTestApp/GDTCCTWatchOSTestApp.xcworkspace' \
  478. -scheme "GDTCCTWatchOSCompanionTestApp" \
  479. "${xcb_flags[@]}" \
  480. build
  481. ;;
  482. Performance-*-unit)
  483. # Run unit tests on prod environment with unswizzle capabilities.
  484. export FPR_UNSWIZZLE_AVAILABLE="1"
  485. export FPR_AUTOPUSH_ENV="0"
  486. pod_gen FirebasePerformance.podspec --platforms="${gen_platform}"
  487. RunXcodebuild \
  488. -workspace 'gen/FirebasePerformance/FirebasePerformance.xcworkspace' \
  489. -scheme "FirebasePerformance-Unit-unit" \
  490. "${xcb_flags[@]}" \
  491. build \
  492. test
  493. ;;
  494. Performance-*-proddev)
  495. # Build the prod dev test app.
  496. export FPR_UNSWIZZLE_AVAILABLE="0"
  497. export FPR_AUTOPUSH_ENV="0"
  498. pod_gen FirebasePerformance.podspec --platforms="${gen_platform}"
  499. RunXcodebuild \
  500. -workspace 'gen/FirebasePerformance/FirebasePerformance.xcworkspace' \
  501. -scheme "FirebasePerformance-TestApp" \
  502. "${xcb_flags[@]}" \
  503. build
  504. ;;
  505. Performance-*-integration)
  506. # Generate the workspace for the SDK to generate Protobuf files.
  507. export FPR_UNSWIZZLE_AVAILABLE="0"
  508. pod_gen FirebasePerformance.podspec --platforms=ios --clean
  509. # Perform "pod install" to install the relevant dependencies
  510. cd FirebasePerformance/Tests/FIRPerfE2E; pod install; cd -
  511. # Run E2E Integration Tests for Autopush.
  512. RunXcodebuild \
  513. -workspace 'FirebasePerformance/Tests/FIRPerfE2E/FIRPerfE2E.xcworkspace' \
  514. -scheme "FIRPerfE2EAutopush" \
  515. FPR_AUTOPUSH_ENV=1 \
  516. "${ios_flags[@]}" \
  517. "${xcb_flags[@]}" \
  518. build \
  519. test
  520. # Run E2E Integration Tests for Prod.
  521. RunXcodebuild \
  522. -workspace 'FirebasePerformance/Tests/FIRPerfE2E/FIRPerfE2E.xcworkspace' \
  523. -scheme "FIRPerfE2EProd" \
  524. "${ios_flags[@]}" \
  525. "${xcb_flags[@]}" \
  526. build \
  527. test
  528. ;;
  529. *-*-spm)
  530. RunXcodebuild \
  531. -scheme $product \
  532. "${xcb_flags[@]}" \
  533. test
  534. ;;
  535. *-*-spmbuildonly)
  536. RunXcodebuild \
  537. -scheme $product \
  538. "${xcb_flags[@]}" \
  539. build
  540. ;;
  541. *)
  542. echo "Don't know how to build this product-platform-method combination" 1>&2
  543. echo " product=$product" 1>&2
  544. echo " platform=$platform" 1>&2
  545. echo " method=$method" 1>&2
  546. exit 1
  547. ;;
  548. esac