build.sh 15 KB

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