Skip to content

Commit

Permalink
[CI] Share fastlane lanes across platforms
Browse files Browse the repository at this point in the history
  • Loading branch information
testableapple committed Aug 13, 2024
1 parent 2c8d222 commit 961d71e
Show file tree
Hide file tree
Showing 5 changed files with 22 additions and 175 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/cron-checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ name: Cron Checks

on:
schedule:
# Runs "At 02:00 every night"
- cron: '0 2 * * *'
# Runs "At 02:00 every night except weekends"
- cron: '0 2 * * 1-5'

workflow_dispatch:

Expand Down
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ fastlane/screenshots
fastlane/test_output
fastlane/allurectl
fastlane/xcresults
fastlane/metrics
**/metrics/
fastlane/recordings
StreamChatCore.framework.coverage.txt
StreamChatCoreTests.xctest.coverage.txt
Expand Down
4 changes: 2 additions & 2 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ GEM
fastlane
pry
fastlane-plugin-sonarcloud_metric_kit (0.2.1)
fastlane-plugin-stream_actions (0.3.38)
fastlane-plugin-stream_actions (0.3.54)
xctest_list (= 1.2.1)
fastlane-plugin-versioning (0.5.2)
ffi (1.17.0)
Expand Down Expand Up @@ -427,7 +427,7 @@ DEPENDENCIES
fastlane-plugin-create_xcframework
fastlane-plugin-lizard
fastlane-plugin-sonarcloud_metric_kit
fastlane-plugin-stream_actions (= 0.3.38)
fastlane-plugin-stream_actions (= 0.3.54)
fastlane-plugin-versioning
jazzy
json
Expand Down
185 changes: 16 additions & 169 deletions fastlane/Fastfile
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,15 @@ github_repo = ENV['GITHUB_REPOSITORY'] || 'GetStream/stream-chat-swiftui'
derived_data_path = 'derived_data'
source_packages_path = 'spm_cache'
metrics_git = '[email protected]:GetStream/stream-internal-metrics.git'
sdk_size_path = "metrics/#{github_repo.split('/').last}-size.json"
buildcache_xcargs = 'CC=clang CPLUSPLUS=clang++ LD=clang LDPLUSPLUS=clang++'
is_localhost = !is_ci
project_package_resolved = "#{xcode_project}/project.xcworkspace/xcshareddata/swiftpm/Package.resolved"
@force_check = false

warning_status = '🟡' # Warning if a branch is #{max_tolerance} less performant than the benchmark
fail_status = '🔴' # Failure if a branch is more than #{max_tolerance} less performant than the benchmark
success_status = '🟢' # Success if a branch is more performant or equals to the benchmark
outstanding_status = '🚀' # Outstanding performance

before_all do |lane|
if is_ci
setup_ci
sh('git config --global user.name "Stream Bot"')
setup_git_config
xcversion(version: xcode_version) unless [:publish_release, :allure_launch, :allure_upload, :copyright, :pod_lint].include?(lane)
end
end
Expand Down Expand Up @@ -152,7 +146,7 @@ lane :merge_release_to_main do |options|

comment = "[Publication of the release](https://github.com/#{github_repo}/actions/workflows/release-publish.yml) has been launched 👍"
UI.important(comment)
create_pr_comment(pr_num: ENV.fetch('GITHUB_PR_NUM'), text: comment)
pr_comment(text: comment)
end

lane :merge_main_to_develop do
Expand Down Expand Up @@ -234,7 +228,7 @@ lane :test_ui do |options|
png_files.each { |png| sh("git add #{png}") || true }
sh('git restore .')

create_pr(
pr_create(
title: '[CI] Snapshots',
base_branch: current_branch,
head_branch: "#{current_branch}-snapshots"
Expand Down Expand Up @@ -448,21 +442,7 @@ lane :rubocop do
end

lane :install_runtime do |options|
runtimes = `xcrun simctl runtime list -j`
UI.message("👉 Runtime list:\n#{runtimes}")
simulators = JSON.parse(runtimes).select do |_, sim|
sim['platformIdentifier'].end_with?('iphonesimulator') && sim['version'] == options[:ios] && sim['state'] == 'Ready'
end

if simulators.empty?
Dir.chdir('..') do
sh("echo 'iOS #{options[:ios]} Simulator' | ipsw download xcode --sim") if Dir['*.dmg'].first.nil?
sh("./Scripts/install_ios_runtime.sh #{Dir['*.dmg'].first}")
UI.success("iOS #{options[:ios]} Runtime successfuly installed")
end
else
UI.important("iOS #{options[:ios]} Runtime already exists")
end
install_ios_runtime(version: options[:ios], custom_script: 'Scripts/install_ios_runtime.sh')
end

desc 'Remove UI Snapshots'
Expand Down Expand Up @@ -492,92 +472,26 @@ lane :copyright do
update_copyright(ignore: [derived_data_path, source_packages_path, 'vendor/'])
next unless is_ci

create_pr(
pr_create(
title: '[CI] Update Copyright',
head_branch: "ci/update-copyright-#{Time.now.to_i}"
)
end

desc 'Show current frameworks size'
lane :show_frameworks_sizes do |options|
next unless is_check_required(sources: sources_matrix[:size], force_check: @force_check)

['metrics/'].each { |dir| FileUtils.remove_dir(dir, force: true) }

sh("git clone #{metrics_git} #{File.dirname(sdk_size_path)}")
is_release = current_branch.include?('release/')
benchmark_config = JSON.parse(File.read(sdk_size_path))
benchmark_key = is_release ? 'release' : 'develop'
benchmark_sizes = benchmark_config[benchmark_key]
branch_sizes = options[:sizes] || frameworks_sizes

table_header = '## SDK Size'
markdown_table = "#{table_header}\n| `title` | `#{is_release ? 'previous release' : 'develop'}` | `#{is_release ? 'current release' : 'branch'}` | `diff` | `status` |\n| - | - | - | - | - |\n"
sdk_names.each do |title|
benchmark_value = benchmark_sizes[title]
branch_value = branch_sizes[title.to_sym]
max_tolerance = 0.5 # Max Tolerance is 0.5MB
fine_tolerance = 0.25 # Fine Tolerance is 0.25MB

diff = (branch_value - benchmark_value).round(2)

status_emoji =
if diff < 0
outstanding_status
elsif diff >= max_tolerance
fail_status
elsif diff >= fine_tolerance
warning_status
else
success_status
end

markdown_table << "|#{title}|#{benchmark_value}MB|#{branch_value}MB|#{diff}MB|#{status_emoji}|\n"
end

FastlaneCore::PrintTable.print_values(title: 'Benchmark', config: benchmark_sizes)
FastlaneCore::PrintTable.print_values(title: 'SDK Size', config: branch_sizes)

if is_ci
if is_release || ENV['GITHUB_EVENT_NAME'].to_s == 'push'
benchmark_config[benchmark_key] = branch_sizes
File.write(sdk_size_path, JSON.pretty_generate(benchmark_config))
Dir.chdir(File.dirname(sdk_size_path)) do
if sh('git status -s', log: false).to_s.empty?
UI.important('No changes in SDK sizes benchmarks.')
else
sh('git add -A')
sh("git commit -m 'Update #{sdk_size_path}'")
sh('git push')
end
end
end

create_pr_comment(pr_num: ENV.fetch('GITHUB_PR_NUM'), text: markdown_table, edit_last_comment_with_text: table_header)
end

UI.user_error!("#{table_header} benchmark failed.") if markdown_table.include?(fail_status)
sizes = options[:sizes] || frameworks_sizes
show_sdk_size(branch_sizes: sizes, github_repo: github_repo)
update_img_shields_sdk_sizes(sizes: sizes, open_pr: options[:open_pr]) if options[:update_readme]
end

desc 'Update img shields SDK size labels'
lane :update_img_shields_sdk_sizes do
sizes = frameworks_sizes

# Read the file into a string
readme_path = '../README.md'
readme_content = File.read(readme_path)

# Define the new value for the badge
stream_chat_swiftui_size = "#{sizes[:StreamChatSwiftUI]}MB"

# Replace the value in the badge URL
readme_content.gsub!(%r{(https://img.shields.io/badge/StreamChatSwiftUI-)(.*?)(-blue)}, "\\1#{stream_chat_swiftui_size}\\3")

# Write the updated content back to the file
File.write(readme_path, readme_content)

# Notify success
UI.success('Successfully updated the SDK size labels in README.md!')
lane :update_img_shields_sdk_sizes do |options|
update_sdk_size_in_readme(
open_pr: options[:open_pr] || false,
readme_path: 'README.md',
sizes: options[:sizes] || frameworks_sizes
)
end

def frameworks_sizes
Expand All @@ -603,74 +517,7 @@ def frameworks_sizes

frameworks_path = "../#{archive_dir}/Products/Applications/DemoAppSwiftUI.app/Frameworks"
stream_chat_swiftui_size = File.size("#{frameworks_path}/StreamChatSwiftUI.framework/StreamChatSwiftUI")
stream_chat_swiftui_size_mb = ((stream_chat_swiftui_size + assets_thinned_size).to_f / 1024 / 1024).round(2)

{
StreamChatSwiftUI: stream_chat_swiftui_size_mb
}
end

private_lane :create_pr do |options|
options[:base_branch] ||= 'develop'
sh("git checkout -b #{options[:head_branch]}")
sh('git add -A')
sh("git commit -m '#{options[:title]}'")
push_to_git_remote(tags: false)

create_pull_request(
api_token: ENV.fetch('GITHUB_TOKEN', nil),
repo: github_repo,
title: options[:title],
head: options[:head_branch],
base: options[:base_branch],
body: 'This PR was created automatically by CI.'
)
end

private_lane :create_pr_comment do |options|
if is_ci && !options[:pr_num].to_s.empty?
last_comment = sh("gh pr view #{options[:pr_num]} --json comments --jq '.comments | map(select(.author.login == \"Stream-SDK-Bot\")) | last'")
edit_last_comment = options[:edit_last_comment_with_text] && last_comment.include?(options[:edit_last_comment_with_text]) ? '--edit-last' : ''
sh("gh pr comment #{options[:pr_num]} #{edit_last_comment} -b '#{options[:text]}'")
end
end

lane :current_branch do
branch = if ENV['GITHUB_PR_NUM'].to_s.empty?
git_branch
else
sh("gh pr view #{ENV.fetch('GITHUB_PR_NUM')} --json headRefName -q .headRefName").strip
end

UI.important("Current branch: #{branch} 🕊️")
branch
end

private_lane :git_status do |options|
UI.user_error!('Extension should be provided') unless options[:ext]

untracked_files = sh('git status -s', log: false).split("\n").map(&:strip)
UI.important("Git Status: #{untracked_files}")
stream_chat_swiftui_size_kb = ((stream_chat_swiftui_size + assets_thinned_size).to_f / 1024)

deleted_files = select_files_from(files: untracked_files, with_extension: options[:ext], that_start_with: 'D')
added_files = select_files_from(files: untracked_files, with_extension: options[:ext], that_start_with: ['A', '??'])
renamed_files = select_files_from(files: untracked_files, with_extension: options[:ext], that_start_with: 'R')
modified_files = select_files_from(files: untracked_files, with_extension: options[:ext], that_start_with: 'M')

renamed_files.each do |renamed_file|
content = renamed_file.split.drop(1).join.split('->').map(&:strip)
deleted_files << content.first
added_files << content.last
end
{ a: added_files, d: deleted_files, m: modified_files }
end

def select_files_from(files:, with_extension:, that_start_with:)
files.select do |f|
f.start_with?(*that_start_with)
end.map do |f|
f.split.drop(1).join(' ')
end.select do |f|
f.gsub(/['"]/, '').end_with?(with_extension)
end
{ StreamChatSwiftUI: stream_chat_swiftui_size_kb }
end
2 changes: 1 addition & 1 deletion fastlane/Pluginfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@

gem 'fastlane-plugin-versioning'
gem 'fastlane-plugin-sonarcloud_metric_kit'
gem 'fastlane-plugin-stream_actions', '0.3.38'
gem 'fastlane-plugin-stream_actions', '0.3.54'
gem 'fastlane-plugin-create_xcframework'

0 comments on commit 961d71e

Please sign in to comment.