Fastfile 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323
  1. # This file contains the fastlane.tools configuration
  2. # You can find the documentation at https://docs.fastlane.tools
  3. #
  4. # For a list of all available actions, check out
  5. #
  6. # https://docs.fastlane.tools/actions
  7. #
  8. # For a list of all available plugins, check out
  9. #
  10. # https://docs.fastlane.tools/plugins/available-plugins
  11. #
  12. # Uncomment the line if you want fastlane to automatically update itself
  13. # update_fastlane
  14. default_platform(:ios)
  15. platform :ios do
  16. # Development
  17. desc "Lint code"
  18. lane :lint_code do
  19. puts("Lint code using SwfitLint")
  20. swiftlint(
  21. mode: :lint,
  22. executable: "./Pods/SwiftLint/swiftlint", # The SwiftLint binary path (optional). Important if you've installed it via CocoaPods
  23. config_file: './Moments/.swiftlint.yml',
  24. raise_if_swiftlint_error: true)
  25. end
  26. desc "Lint and format code"
  27. lane :format_code do
  28. puts("Lint and format code using SwfitLint")
  29. swiftlint(
  30. mode: :autocorrect,
  31. executable: "./Pods/SwiftLint/swiftlint", # The SwiftLint binary path (optional). Important if you've installed it via CocoaPods
  32. config_file: './Moments/.swiftlint.yml',
  33. raise_if_swiftlint_error: true)
  34. end
  35. desc "Sort Xcode project files"
  36. lane :sort_files do
  37. puts("Sort the files for the Xcode project")
  38. sh "../scripts/sort-Xcode-project-file.pl ../Moments/Moments.xcodeproj"
  39. end
  40. desc "Prepare for a pull request"
  41. lane :prepare_pr do
  42. format_code
  43. sort_files
  44. end
  45. desc "Build development app"
  46. lane :build_dev_app do
  47. puts("Build development app")
  48. gym(scheme: "Moments",
  49. workspace: "Moments.xcworkspace",
  50. export_method: "development",
  51. configuration: "Debug",
  52. xcargs: "-allowProvisioningUpdates")
  53. end
  54. # Test
  55. desc "Run unit tests"
  56. lane :tests do
  57. puts("Run the tests")
  58. scan(
  59. scheme: "Moments",
  60. workspace: "Moments.xcworkspace",
  61. output_directory: "./fastlane/dist",
  62. output_types: "html",
  63. buildlog_path: "./fastlane/dist")
  64. end
  65. # Profile
  66. desc "Download certificates and profiles"
  67. lane :download_profiles do
  68. keychain_name = "TemporaryKeychain"
  69. keychain_password = "TemporaryKeychainPassword"
  70. create_keychain(
  71. name: keychain_name,
  72. password: keychain_password,
  73. default_keychain: false,
  74. timeout: 3600,
  75. unlock: true,
  76. )
  77. match(
  78. type: "adhoc",
  79. readonly: true,
  80. keychain_name: keychain_name,
  81. keychain_password: keychain_password,
  82. storage_mode: "git",
  83. git_url: "https://github.com/JakeLin/moments-codesign",
  84. app_identifier: "com.ibanimatable.moments.internal",
  85. team_id: "6HLFCRTYQU"
  86. )
  87. match(
  88. type: "appstore",
  89. readonly: true,
  90. keychain_name: keychain_name,
  91. keychain_password: keychain_password,
  92. storage_mode: "git",
  93. git_url: "https://github.com/JakeLin/moments-codesign",
  94. app_identifier: "com.ibanimatable.moments",
  95. team_id: "6HLFCRTYQU"
  96. )
  97. end
  98. desc "Create all new provisioning profiles managed by fastlane match"
  99. lane :create_new_profiles do
  100. api_key = get_app_store_connect_api_key
  101. keychain_name = "TemporaryKeychain"
  102. keychain_password = "TemporaryKeychainPassword"
  103. create_keychain(
  104. name: keychain_name,
  105. password: keychain_password,
  106. default_keychain: false,
  107. timeout: 3600,
  108. unlock: true,
  109. )
  110. match(
  111. type: "adhoc",
  112. keychain_name: keychain_name,
  113. keychain_password: keychain_password,
  114. storage_mode: "git",
  115. git_url: "https://github.com/JakeLin/moments-codesign",
  116. app_identifier: "com.ibanimatable.moments.internal",
  117. team_id: "6HLFCRTYQU",
  118. api_key: api_key
  119. )
  120. match(
  121. type: "appstore",
  122. keychain_name: keychain_name,
  123. keychain_password: keychain_password,
  124. storage_mode: "git",
  125. git_url: "https://github.com/JakeLin/moments-codesign",
  126. app_identifier: "com.ibanimatable.moments",
  127. team_id: "6HLFCRTYQU",
  128. api_key: api_key
  129. )
  130. end
  131. desc "Nuke all provisioning profiles managed by fastlane match"
  132. lane :nuke_profiles do
  133. api_key = get_app_store_connect_api_key
  134. keychain_name = "TemporaryKeychain"
  135. keychain_password = "TemporaryKeychainPassword"
  136. create_keychain(
  137. name: keychain_name,
  138. password: keychain_password,
  139. default_keychain: false,
  140. timeout: 3600,
  141. unlock: true,
  142. )
  143. match_nuke(
  144. type: "adhoc",
  145. keychain_name: keychain_name,
  146. keychain_password: keychain_password,
  147. storage_mode: "git",
  148. git_url: "https://github.com/JakeLin/moments-codesign",
  149. app_identifier: "com.ibanimatable.moments.internal",
  150. team_id: "6HLFCRTYQU",
  151. api_key: api_key
  152. )
  153. match_nuke(
  154. type: "appstore",
  155. keychain_name: keychain_name,
  156. keychain_password: keychain_password,
  157. storage_mode: "git",
  158. git_url: "https://github.com/JakeLin/moments-codesign",
  159. app_identifier: "com.ibanimatable.moments",
  160. team_id: "6HLFCRTYQU",
  161. api_key: api_key
  162. )
  163. end
  164. desc "Add a new device to provisioning profile"
  165. lane :add_device do |options|
  166. name = options[:name]
  167. udid = options[:udid]
  168. # Add to App Store Connect
  169. api_key = get_app_store_connect_api_key
  170. register_device(
  171. name: name,
  172. udid: udid,
  173. team_id: "6HLFCRTYQU",
  174. api_key: api_key
  175. )
  176. # Update the profiles to Git private repo
  177. match(
  178. type: "adhoc",
  179. force: true,
  180. storage_mode: "git",
  181. git_url: "https://github.com/JakeLin/moments-codesign",
  182. app_identifier: "com.ibanimatable.moments.internal",
  183. team_id: "6HLFCRTYQU",
  184. api_key: api_key
  185. )
  186. end
  187. # Archive
  188. desc 'Creates an archive of the Internal app for testing'
  189. lane :archive_internal do
  190. unlock_keychain(
  191. path: "TemporaryKeychain-db",
  192. password: "TemporaryKeychainPassword")
  193. update_code_signing_settings(
  194. use_automatic_signing: false,
  195. path: "Moments/Moments.xcodeproj",
  196. code_sign_identity: "iPhone Distribution",
  197. bundle_identifier: "com.ibanimatable.moments.internal",
  198. profile_name: "match AdHoc com.ibanimatable.moments.internal")
  199. puts("Create an archive for Internal testing")
  200. gym(scheme: "Moments-Internal",
  201. workspace: "Moments.xcworkspace",
  202. export_method: "ad-hoc",
  203. output_directory: './build',
  204. output_name: "Moments.ipa",
  205. xcargs: "-allowProvisioningUpdates")
  206. update_code_signing_settings(
  207. use_automatic_signing: true,
  208. path: "Moments/Moments.xcodeproj")
  209. puts("If you run this lane on your local machine, should not commit the changes for your project file to Git")
  210. end
  211. desc 'Creates an archive of the Production app with Appstore distribution'
  212. lane :archive_appstore do
  213. unlock_keychain(
  214. path: "TemporaryKeychain-db",
  215. password: "TemporaryKeychainPassword")
  216. update_code_signing_settings(
  217. use_automatic_signing: false,
  218. path: "Moments/Moments.xcodeproj",
  219. code_sign_identity: "iPhone Distribution",
  220. bundle_identifier: "com.ibanimatable.moments",
  221. profile_name: "match AppStore com.ibanimatable.moments")
  222. puts("Create an archive for AppStore submission")
  223. gym(scheme: "Moments-AppStore",
  224. workspace: "Moments.xcworkspace",
  225. export_method: "app-store",
  226. xcargs: "-allowProvisioningUpdates")
  227. update_code_signing_settings(
  228. use_automatic_signing: true,
  229. path: "Moments/Moments.xcodeproj")
  230. puts("If you run this lane on your local machine, should not commit the changes for your project file to Git")
  231. end
  232. # Crash report symbols
  233. desc 'Upload symbols to Crashlytics for Internal app'
  234. lane :upload_symbols_to_crashlytics_internal do
  235. upload_symbols_to_crashlytics(
  236. dsym_path: "./Moments.app.dSYM.zip",
  237. gsp_path: "./Moments/Moments/Configurations/Firebase/GoogleService-Info-Internal.plist",
  238. api_token: ENV["FIREBASE_API_TOKEN"]
  239. )
  240. end
  241. desc 'Upload symbols to Crashlytics for Production app'
  242. lane :upload_symbols_to_crashlytics_appstore do
  243. upload_symbols_to_crashlytics(
  244. dsym_path: "./Moments.app.dSYM.zip",
  245. gsp_path: "./Moments/Moments/Configurations/Firebase/GoogleService-Info-AppStore.plist",
  246. api_token: ENV["FIREBASE_API_TOKEN"]
  247. )
  248. end
  249. # Deploy
  250. desc 'Deploy the Internal app to Firebase Distribution'
  251. lane :deploy_internal do
  252. firebase_app_distribution(
  253. app: "1:374168413412:ios:912d89b30767d8e5a038f1",
  254. ipa_path: "Moments.ipa",
  255. groups: "internal-testers",
  256. release_notes: "A new build for the Internal App", # Can customize it using Git history.
  257. firebase_cli_token: ENV["FIREBASE_API_TOKEN"]
  258. )
  259. end
  260. desc 'Deploy the Production app to TestFlight and App Store'
  261. lane :deploy_appstore do
  262. api_key = get_app_store_connect_api_key
  263. upload_to_app_store(
  264. api_key: api_key,
  265. app_identifier: "com.ibanimatable.moments",
  266. skip_metadata: true,
  267. skip_screenshots: true,
  268. precheck_include_in_app_purchases: false,
  269. )
  270. end
  271. desc 'Get App Store Connect API key'
  272. private_lane :get_app_store_connect_api_key do
  273. # The key needs to have App Manager role, see https://github.com/fastlane/fastlane/issues/17066
  274. key_content = ENV["APP_STORE_CONNECT_API_CONTENT"] # Make sure setting this environment variable before call this lane.
  275. api_key = app_store_connect_api_key(
  276. key_id: "D9B979RR69",
  277. issuer_id: "69a6de7b-13fb-47e3-e053-5b8c7c11a4d1",
  278. key_content: "-----BEGIN EC PRIVATE KEY-----\n" + key_content + "\n-----END EC PRIVATE KEY-----",
  279. duration: 1200,
  280. in_house: false
  281. )
  282. api_key
  283. end
  284. end