build.sh 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636
  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/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. "${xcb_flags[@]}" \
  270. build \
  271. test
  272. ;;
  273. Firestore-macOS-cmake | Firestore-Linux-cmake)
  274. "${firestore_emulator}" start
  275. trap '"${firestore_emulator}" stop' ERR EXIT
  276. (
  277. test -d build || mkdir build
  278. cd build
  279. echo "Preparing cmake build ..."
  280. cmake -G Ninja "${cmake_options[@]}" ..
  281. echo "Building cmake build ..."
  282. ninja -k 10 all
  283. ctest --output-on-failure
  284. )
  285. ;;
  286. SymbolCollision-*-*)
  287. RunXcodebuild \
  288. -workspace 'SymbolCollisionTest/SymbolCollisionTest.xcworkspace' \
  289. -scheme "SymbolCollisionTest" \
  290. "${xcb_flags[@]}" \
  291. build
  292. ;;
  293. Messaging-*-xcodebuild)
  294. pod_gen FirebaseMessaging.podspec --platforms=ios
  295. RunXcodebuild \
  296. -workspace 'gen/FirebaseMessaging/FirebaseMessaging.xcworkspace' \
  297. -scheme "FirebaseMessaging-Unit-unit" \
  298. "${ios_flags[@]}" \
  299. "${xcb_flags[@]}" \
  300. build \
  301. test
  302. if check_secrets; then
  303. # Integration tests are only run on iOS to minimize flake failures.
  304. RunXcodebuild \
  305. -workspace 'gen/FirebaseMessaging/FirebaseMessaging.xcworkspace' \
  306. -scheme "FirebaseMessaging-Unit-integration" \
  307. "${ios_flags[@]}" \
  308. "${xcb_flags[@]}" \
  309. build \
  310. test
  311. fi
  312. pod_gen FirebaseMessaging.podspec --platforms=macos --clean
  313. RunXcodebuild \
  314. -workspace 'gen/FirebaseMessaging/FirebaseMessaging.xcworkspace' \
  315. -scheme "FirebaseMessaging-Unit-unit" \
  316. "${macos_flags[@]}" \
  317. "${xcb_flags[@]}" \
  318. build \
  319. test
  320. pod_gen FirebaseMessaging.podspec --platforms=tvos --clean
  321. RunXcodebuild \
  322. -workspace 'gen/FirebaseMessaging/FirebaseMessaging.xcworkspace' \
  323. -scheme "FirebaseMessaging-Unit-unit" \
  324. "${tvos_flags[@]}" \
  325. "${xcb_flags[@]}" \
  326. build \
  327. test
  328. ;;
  329. MessagingSample-*-*)
  330. if check_secrets; then
  331. RunXcodebuild \
  332. -workspace 'FirebaseMessaging/Apps/Sample/Sample.xcworkspace' \
  333. -scheme "Sample" \
  334. "${xcb_flags[@]}" \
  335. build
  336. fi
  337. ;;
  338. MLModelDownloaderSample-*-*)
  339. if check_secrets; then
  340. RunXcodebuild \
  341. -workspace 'FirebaseMLModelDownloader/Apps/Sample/MLDownloaderTestApp.xcworkspace' \
  342. -scheme "MLDownloaderTestApp" \
  343. "${xcb_flags[@]}" \
  344. build
  345. fi
  346. ;;
  347. SegmentationSample-*-*)
  348. RunXcodebuild \
  349. -workspace 'FirebaseSegmentation/Tests/Sample/SegmentationSampleApp.xcworkspace' \
  350. -scheme "SegmentationSampleApp" \
  351. "${xcb_flags[@]}" \
  352. build
  353. ;;
  354. Database-*-unit)
  355. pod_gen FirebaseDatabase.podspec --platforms="${gen_platform}"
  356. RunXcodebuild \
  357. -workspace 'gen/FirebaseDatabase/FirebaseDatabase.xcworkspace' \
  358. -scheme "FirebaseDatabase-Unit-unit" \
  359. "${xcb_flags[@]}" \
  360. build \
  361. test
  362. ;;
  363. Database-*-integration)
  364. "${database_emulator}" start
  365. trap '"${database_emulator}" stop' ERR EXIT
  366. pod_gen FirebaseDatabase.podspec --platforms="${gen_platform}"
  367. RunXcodebuild \
  368. -workspace 'gen/FirebaseDatabase/FirebaseDatabase.xcworkspace' \
  369. -scheme "FirebaseDatabase-Unit-integration" \
  370. "${xcb_flags[@]}" \
  371. build \
  372. test
  373. ;;
  374. RemoteConfig-*-unit)
  375. pod_gen FirebaseRemoteConfig.podspec --platforms="${gen_platform}"
  376. RunXcodebuild \
  377. -workspace 'gen/FirebaseRemoteConfig/FirebaseRemoteConfig.xcworkspace' \
  378. -scheme "FirebaseRemoteConfig-Unit-unit" \
  379. "${xcb_flags[@]}" \
  380. build \
  381. test
  382. ;;
  383. RemoteConfig-*-fakeconsole)
  384. pod_gen FirebaseRemoteConfig.podspec --platforms="${gen_platform}"
  385. RunXcodebuild \
  386. -workspace 'gen/FirebaseRemoteConfig/FirebaseRemoteConfig.xcworkspace' \
  387. -scheme "FirebaseRemoteConfig-Unit-fake-console-tests" \
  388. "${xcb_flags[@]}" \
  389. build \
  390. test
  391. ;;
  392. RemoteConfig-*-integration)
  393. pod_gen FirebaseRemoteConfig.podspec --platforms="${gen_platform}"
  394. RunXcodebuild \
  395. -workspace 'gen/FirebaseRemoteConfig/FirebaseRemoteConfig.xcworkspace' \
  396. -scheme "FirebaseRemoteConfig-Unit-swift-api-tests" \
  397. "${xcb_flags[@]}" \
  398. build \
  399. test
  400. ;;
  401. RemoteConfigSample-*-*)
  402. RunXcodebuild \
  403. -workspace 'FirebaseRemoteConfig/Tests/Sample/RemoteConfigSampleApp.xcworkspace' \
  404. -scheme "RemoteConfigSampleApp" \
  405. "${xcb_flags[@]}" \
  406. build
  407. ;;
  408. Storage-*-xcodebuild)
  409. pod_gen FirebaseStorage.podspec --platforms=ios
  410. RunXcodebuild \
  411. -workspace 'gen/FirebaseStorage/FirebaseStorage.xcworkspace' \
  412. -scheme "FirebaseStorage-Unit-unit" \
  413. "${ios_flags[@]}" \
  414. "${xcb_flags[@]}" \
  415. build \
  416. test
  417. if check_secrets; then
  418. # Integration tests are only run on iOS to minimize flake failures.
  419. RunXcodebuild \
  420. -workspace 'gen/FirebaseStorage/FirebaseStorage.xcworkspace' \
  421. -scheme "FirebaseStorage-Unit-integration" \
  422. "${ios_flags[@]}" \
  423. "${xcb_flags[@]}" \
  424. build \
  425. test
  426. RunXcodebuild \
  427. -workspace 'gen/FirebaseStorage/FirebaseStorage.xcworkspace' \
  428. -scheme "FirebaseStorage-Unit-swift-integration" \
  429. "${ios_flags[@]}" \
  430. "${xcb_flags[@]}" \
  431. build \
  432. test
  433. fi
  434. pod_gen FirebaseStorage.podspec --platforms=macos --clean
  435. RunXcodebuild \
  436. -workspace 'gen/FirebaseStorage/FirebaseStorage.xcworkspace' \
  437. -scheme "FirebaseStorage-Unit-unit" \
  438. "${macos_flags[@]}" \
  439. "${xcb_flags[@]}" \
  440. build \
  441. test
  442. pod_gen FirebaseStorage.podspec --platforms=tvos --clean
  443. RunXcodebuild \
  444. -workspace 'gen/FirebaseStorage/FirebaseStorage.xcworkspace' \
  445. -scheme "FirebaseStorage-Unit-unit" \
  446. "${tvos_flags[@]}" \
  447. "${xcb_flags[@]}" \
  448. build \
  449. test
  450. ;;
  451. StorageSwift-*-xcodebuild)
  452. pod_gen FirebaseStorageSwift.podspec --platforms=ios
  453. if check_secrets; then
  454. # Integration tests are only run on iOS to minimize flake failures.
  455. RunXcodebuild \
  456. -workspace 'gen/FirebaseStorageSwift/FirebaseStorageSwift.xcworkspace' \
  457. -scheme "FirebaseStorageSwift-Unit-integration" \
  458. "${ios_flags[@]}" \
  459. "${xcb_flags[@]}" \
  460. build \
  461. test
  462. fi
  463. ;;
  464. GoogleDataTransport-watchOS-xcodebuild)
  465. RunXcodebuild \
  466. -workspace 'GoogleDataTransport/GDTWatchOSTestApp/GDTWatchOSTestApp.xcworkspace' \
  467. -scheme "GDTWatchOSTestAppWatchKitApp" \
  468. "${xcb_flags[@]}" \
  469. build
  470. RunXcodebuild \
  471. -workspace 'GoogleDataTransport/GDTCCTWatchOSTestApp/GDTCCTWatchOSTestApp.xcworkspace' \
  472. -scheme "GDTCCTWatchOSIndependentTestAppWatchKitApp" \
  473. "${xcb_flags[@]}" \
  474. build
  475. RunXcodebuild \
  476. -workspace 'GoogleDataTransport/GDTCCTWatchOSTestApp/GDTCCTWatchOSTestApp.xcworkspace' \
  477. -scheme "GDTCCTWatchOSCompanionTestApp" \
  478. "${xcb_flags[@]}" \
  479. build
  480. ;;
  481. Performance-*-unit)
  482. # Run unit tests on prod environment with unswizzle capabilities.
  483. export FPR_UNSWIZZLE_AVAILABLE="1"
  484. export FPR_AUTOPUSH_ENV="0"
  485. pod_gen FirebasePerformance.podspec --platforms="${gen_platform}"
  486. RunXcodebuild \
  487. -workspace 'gen/FirebasePerformance/FirebasePerformance.xcworkspace' \
  488. -scheme "FirebasePerformance-Unit-unit" \
  489. "${xcb_flags[@]}" \
  490. build \
  491. test
  492. ;;
  493. Performance-*-proddev)
  494. # Build the prod dev test app.
  495. export FPR_UNSWIZZLE_AVAILABLE="0"
  496. export FPR_AUTOPUSH_ENV="0"
  497. pod_gen FirebasePerformance.podspec --platforms="${gen_platform}"
  498. RunXcodebuild \
  499. -workspace 'gen/FirebasePerformance/FirebasePerformance.xcworkspace' \
  500. -scheme "FirebasePerformance-TestApp" \
  501. "${xcb_flags[@]}" \
  502. build
  503. ;;
  504. Performance-*-integration)
  505. # Generate the workspace for the SDK to generate Protobuf files.
  506. export FPR_UNSWIZZLE_AVAILABLE="0"
  507. pod_gen FirebasePerformance.podspec --platforms=ios --clean
  508. # Perform "pod install" to install the relevant dependencies
  509. cd FirebasePerformance/Tests/FIRPerfE2E; pod install; cd -
  510. # Run E2E Integration Tests for Autopush.
  511. RunXcodebuild \
  512. -workspace 'FirebasePerformance/Tests/FIRPerfE2E/FIRPerfE2E.xcworkspace' \
  513. -scheme "FIRPerfE2EAutopush" \
  514. FPR_AUTOPUSH_ENV=1 \
  515. "${ios_flags[@]}" \
  516. "${xcb_flags[@]}" \
  517. build \
  518. test
  519. # Run E2E Integration Tests for Prod.
  520. RunXcodebuild \
  521. -workspace 'FirebasePerformance/Tests/FIRPerfE2E/FIRPerfE2E.xcworkspace' \
  522. -scheme "FIRPerfE2EProd" \
  523. "${ios_flags[@]}" \
  524. "${xcb_flags[@]}" \
  525. build \
  526. test
  527. ;;
  528. *-*-spm)
  529. RunXcodebuild \
  530. -scheme $product \
  531. "${xcb_flags[@]}" \
  532. test
  533. ;;
  534. *-*-spmbuildonly)
  535. RunXcodebuild \
  536. -scheme $product \
  537. "${xcb_flags[@]}" \
  538. build
  539. ;;
  540. *)
  541. echo "Don't know how to build this product-platform-method combination" 1>&2
  542. echo " product=$product" 1>&2
  543. echo " platform=$platform" 1>&2
  544. echo " method=$method" 1>&2
  545. exit 1
  546. ;;
  547. esac