@@ -13,11 +13,18 @@ sdk_names = ['StreamChatSwiftUI']
1313github_repo = ENV [ 'GITHUB_REPOSITORY' ] || 'GetStream/stream-chat-swiftui'
1414derived_data_path = 'derived_data'
1515source_packages_path = 'spm_cache'
16+ metrics_git = '[email protected] :GetStream/apple-internal-metrics.git' 17+ sdk_size_path = "metrics/#{ github_repo . split ( '/' ) . last } -size.json"
1618buildcache_xcargs = 'CC=clang CPLUSPLUS=clang++ LD=clang LDPLUSPLUS=clang++'
1719is_localhost = !is_ci
1820project_package_resolved = "#{ xcode_project } /project.xcworkspace/xcshareddata/swiftpm/Package.resolved"
1921@force_check = false
2022
23+ warning_status = '🟡' # Warning if a branch is #{max_tolerance} less performant than the benchmark
24+ fail_status = '🔴' # Failure if a branch is more than #{max_tolerance} less performant than the benchmark
25+ success_status = '🟢' # Success if a branch is more performant or equals to the benchmark
26+ outstanding_status = '🚀' # Outstanding performance
27+
2128before_all do |lane |
2229 if is_ci
2330 setup_ci
@@ -463,7 +470,8 @@ lane :sources_matrix do
463470 e2e : [ 'Sources' , 'StreamChatSwiftUITestsAppTests' , 'StreamChatSwiftUITestsApp' ] ,
464471 ui : [ 'Sources' , 'StreamChatSwiftUITests' , xcode_project ] ,
465472 sample_apps : [ 'Sources' , 'DemoAppSwiftUI' , xcode_project ] ,
466- ruby : [ 'fastlane' , 'Gemfile' , 'Gemfile.lock' ]
473+ ruby : [ 'fastlane' , 'Gemfile' , 'Gemfile.lock' ] ,
474+ size : [ 'Sources' , xcode_project ]
467475 }
468476end
469477
@@ -477,6 +485,93 @@ lane :copyright do
477485 )
478486end
479487
488+ desc 'Show current frameworks size'
489+ lane :show_frameworks_sizes do |options |
490+ next unless is_check_required ( sources : sources_matrix [ :size ] , force_check : @force_check )
491+
492+ [ 'metrics/' ] . each { |dir | FileUtils . remove_dir ( dir , force : true ) }
493+
494+ sh ( "git clone #{ metrics_git } #{ File . dirname ( sdk_size_path ) } " )
495+ develop_sizes = JSON . parse ( File . read ( sdk_size_path ) )
496+ branch_sizes = options [ :sizes ] || frameworks_sizes
497+
498+ table_header = '## SDK Size'
499+ markdown_table = "#{ table_header } \n | `title` | `develop` | `branch` | `diff` | `status` |\n | - | - | - | - | - |\n "
500+ sdk_names . each do |title |
501+ benchmark_value = develop_sizes [ title ]
502+ branch_value = branch_sizes [ title . to_sym ]
503+ max_tolerance = 0.5 # Max Tolerance is 0.5MB
504+ fine_tolerance = 0.25 # Fine Tolerance is 0.25MB
505+
506+ diff = ( branch_value - benchmark_value ) . round ( 2 )
507+
508+ status_emoji =
509+ if diff < 0
510+ outstanding_status
511+ elsif diff >= max_tolerance
512+ fail_status
513+ elsif diff >= fine_tolerance
514+ warning_status
515+ else
516+ success_status
517+ end
518+
519+ markdown_table << "|#{ title } |#{ benchmark_value } MB|#{ branch_value } MB|#{ diff } MB|#{ status_emoji } |\n "
520+ end
521+
522+ FastlaneCore ::PrintTable . print_values ( title : 'Benchmark' , config : develop_sizes )
523+ FastlaneCore ::PrintTable . print_values ( title : 'SDK Size' , config : branch_sizes )
524+
525+ if is_ci
526+ if ENV [ 'GITHUB_EVENT_NAME' ] . to_s == 'push'
527+ File . write ( sdk_size_path , JSON . pretty_generate ( branch_sizes ) )
528+ Dir . chdir ( File . dirname ( sdk_size_path ) ) do
529+ if sh ( 'git status -s' , log : false ) . to_s . empty?
530+ UI . important ( 'No changes in SDK sizes benchmarks.' )
531+ else
532+ sh ( 'git add -A' )
533+ sh ( "git commit -m 'Update #{ sdk_size_path } '" )
534+ sh ( 'git push' )
535+ end
536+ end
537+ end
538+
539+ create_pr_comment ( pr_num : ENV . fetch ( 'GITHUB_PR_NUM' ) , text : markdown_table , edit_last_comment_with_text : table_header )
540+ end
541+
542+ UI . user_error! ( "#{ table_header } benchmark failed." ) if markdown_table . include? ( fail_status )
543+ end
544+
545+ def frameworks_sizes
546+ root_dir = 'Build/SDKSize'
547+ archive_dir = "#{ root_dir } /DemoApp.xcarchive"
548+
549+ FileUtils . rm_rf ( "../#{ root_dir } /" )
550+
551+ match_me
552+
553+ gym (
554+ scheme : 'DemoAppSwiftUI' ,
555+ archive_path : archive_dir ,
556+ export_method : 'ad-hoc' ,
557+ export_options : 'fastlane/sdk_size_export_options.plist'
558+ )
559+
560+ # Parse the thinned size of Assets.car from Packaging.log
561+ assets_size_regex = %r{\b (\d +)\s bytes\s for\s ./Payload/DemoAppSwiftUI.app/Frameworks/StreamChatSwiftUI.framework/Assets.car\b }
562+ packaging_log_content = File . read ( "#{ Gym . cache [ :temporary_output_path ] } /Packaging.log" )
563+ match = packaging_log_content . match ( assets_size_regex )
564+ assets_thinned_size = match [ 1 ] . to_i
565+
566+ frameworks_path = "../#{ archive_dir } /Products/Applications/DemoAppSwiftUI.app/Frameworks"
567+ stream_chat_swiftui_size = File . size ( "#{ frameworks_path } /StreamChatSwiftUI.framework/StreamChatSwiftUI" )
568+ stream_chat_swiftui_size_mb = ( ( stream_chat_swiftui_size + assets_thinned_size ) . to_f / 1024 / 1024 ) . round ( 2 )
569+
570+ {
571+ StreamChatSwiftUI : stream_chat_swiftui_size_mb
572+ }
573+ end
574+
480575private_lane :create_pr do |options |
481576 options [ :base_branch ] ||= 'develop'
482577 sh ( "git checkout -b #{ options [ :head_branch ] } " )
@@ -494,6 +589,14 @@ private_lane :create_pr do |options|
494589 )
495590end
496591
592+ private_lane :create_pr_comment do |options |
593+ if is_ci && !options [ :pr_num ] . to_s . empty?
594+ last_comment = sh ( "gh pr view #{ options [ :pr_num ] } --json comments --jq '.comments | map(select(.author.login == \" Stream-iOS-Bot\" )) | last'" )
595+ edit_last_comment = last_comment . include? ( options [ :edit_last_comment_with_text ] ) ? '--edit-last' : ''
596+ sh ( "gh pr comment #{ options [ :pr_num ] } #{ edit_last_comment } -b '#{ options [ :text ] } '" )
597+ end
598+ end
599+
497600private_lane :current_branch do
498601 ENV [ 'BRANCH_NAME' ] . to_s . empty? ? git_branch : ENV . fetch ( 'BRANCH_NAME' )
499602end
0 commit comments