Last active
December 1, 2022 01:30
-
-
Save petrbela/79f4a75d087239eb8b904a27cfa28feb to your computer and use it in GitHub Desktop.
React Native deployment
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# This file contains the fastlane.tools configuration | |
# You can find the documentation at https://docs.fastlane.tools | |
# | |
# For a list of all available actions, check out | |
# | |
# https://docs.fastlane.tools/actions | |
# | |
# Uncomment the line if you want fastlane to automatically update itself | |
# update_fastlane | |
default_platform(:ios) | |
############################### | |
######## i O S ######## | |
############################### | |
platform :ios do | |
before_all do | |
IOS_VERSION = get_version_number(xcodeproj: 'ios/flex.xcodeproj', target: 'flex') | |
IOS_BUILD = get_build_number(xcodeproj: 'ios/flex.xcodeproj') | |
end | |
desc 'Synchronize certificates for signing the iOS app' | |
lane :update_certificates do | |
ENV['APP_IDENTIFIER'] = 'com.sweatflex.flex.development' | |
match(app_identifier: ios_app_identifiers, type: 'development') | |
ENV['APP_IDENTIFIER'] = 'com.sweatflex.flex.staging' | |
match(app_identifier: ios_app_identifiers, type: 'appstore') | |
ENV['APP_IDENTIFIER'] = 'com.sweatflex.flex' | |
match(app_identifier: ios_app_identifiers, type: 'appstore') | |
end | |
desc 'Run tests' | |
lane :test do | |
run_tests(scheme: 'flexTests') | |
end | |
desc 'Set up for development' | |
lane :dev do | |
Dotenv.overload('../.env') | |
ios_update_identifiers | |
match(app_identifier: ios_app_identifiers, type: 'development', readonly: true) | |
update_xcodeproj( | |
xcodeproj: 'ios/flex.xcodeproj', | |
options: { | |
'CODE_SIGN_STYLE' => 'Automatic', | |
'CODE_SIGN_IDENTITY' => 'iPhone Developer', | |
'DEVELOPMENT_TEAM' => '', | |
'PROVISIONING_PROFILE' => '', | |
'PROVISIONING_PROFILE_SPECIFIER' => '', | |
} | |
) | |
# build_app( | |
# workspace: 'ios/flex.xcworkspace', | |
# configuration: 'Debug', | |
# scheme: 'flex', | |
# skip_profile_detection: true, | |
# export_method: 'development', | |
# ) | |
# add_badge(shield: "#{IOS_VERSION}-#{IOS_BUILD}-blue") | |
# install_on_device | |
puts 'Configuration was set for development. Open XCode and run from there.' | |
end | |
desc 'Push a staging build to TestFlight' | |
lane :staging do | |
Dotenv.overload('../.env.staging') | |
ios_update_identifiers | |
match(app_identifier: ios_app_identifiers, type: 'appstore', readonly: true) | |
ios_update_build_settings | |
ios_build_app | |
upload_to_testflight(skip_waiting_for_build_processing: true) | |
clean_build_artifacts | |
dev # invoke dev lane to restore dev setting | |
end | |
desc 'Push a beta build to TestFlight' | |
lane :beta do | |
Dotenv.overload('../.env.production') | |
ios_update_identifiers | |
match(app_identifier: ios_app_identifiers, type: 'appstore', readonly: true) | |
ios_update_build_settings | |
# increment_version_number(xcodeproj: 'ios/flex.xcodeproj') | |
# increment_build_number(xcodeproj: 'ios/flex.xcodeproj') | |
ios_build_app | |
# add_badge | |
upload_to_testflight(skip_waiting_for_build_processing: true) | |
clean_build_artifacts | |
dev # invoke dev lane to restore dev setting | |
end | |
desc 'Deploy to AppStore' | |
lane :production do | |
Dotenv.overload('../.env.production') | |
ios_update_identifiers | |
match(app_identifier: ios_app_identifiers, type: 'appstore', readonly: true) | |
ios_update_build_settings | |
ios_build_app | |
upload_to_app_store | |
clean_build_artifacts | |
dev # invoke dev lane to restore dev setting | |
end | |
desc 'Upload dSYM files to Bugsnag and Crashlytics' | |
lane :refresh_dsyms do | |
download_dsyms(version: IOS_VERSION) # Download dSYM files from iTC | |
upload_symbols_to_bugsnag | |
upload_symbols_to_crashlytics(binary_path: 'ios/Pods/Fabric/upload-symbols') | |
clean_build_artifacts | |
end | |
desc 'Deploy to staging via CodePush' | |
lane :codepush_staging do | |
Dotenv.overload('../.env.staging') | |
codepush(env: 'Staging') | |
end | |
desc 'Deploy to production via CodePush' | |
lane :codepush_production do | |
Dotenv.overload('../.env.production') | |
codepush(env: 'Production') | |
end | |
private_lane :codepush do |env:| | |
last_build_id = `appcenter codepush deployment history #{env} | tail -2 | head -n 1 | awk '{print $2}'` | |
build_id = "v#{last_build_id[1..-1].to_i + 1}" | |
ENV['BUGSNAG_BUNDLE_ID'] = "#{env}-#{IOS_VERSION}-#{build_id}" | |
Dir.chdir('..') do | |
sh "appcenter codepush release-react -m -o build -d #{env}" | |
sh "bugsnag-sourcemaps upload \ | |
--api-key #{ENV['BUGSNAG_API_KEY']} \ | |
--code-bundle-id #{ENV['BUGSNAG_BUNDLE_ID']} \ | |
--minified-file build/CodePush/main.jsbundle \ | |
--minified-url main.jsbundle \ | |
--source-map build/CodePush/main.jsbundle.map \ | |
--upload-sources \ | |
--add-wildcard-prefix" | |
end | |
end | |
lane :sourcemaps do | |
Dir.chdir('..') do | |
sh "react-native bundle \ | |
--platform ios \ | |
--dev false \ | |
--entry-file index.js \ | |
--bundle-output build/ios-release.bundle \ | |
--sourcemap-output build/ios-release.bundle.map" | |
sh "bugsnag-sourcemaps upload \ | |
--api-key #{ENV['BUGSNAG_API_KEY']} \ | |
--app-version #{IOS_VERSION} \ | |
--minified-file build/ios-release.bundle \ | |
--source-map build/ios-release.bundle.map \ | |
--minified-url main.jsbundle \ | |
--upload-sources \ | |
--add-wildcard-prefix" | |
end | |
end | |
end | |
def ios_update_identifiers | |
update_info_plist( | |
xcodeproj: 'ios/flex.xcodeproj', | |
plist_path: 'flex/Info.plist', | |
block: lambda { |plist| | |
plist['branch_app_domain'] = ENV['BRANCH_APP_DOMAIN'] | |
plist['branch_key'] = ENV['BRANCH_KEY'] | |
plist['CFBundleDisplayName'] = ENV['APP_NAME'] | |
plist['CFBundleIdentifier'] = ENV['APP_IDENTIFIER'] | |
plist['CodePushDeploymentKey'] = ENV['CODEPUSH_KEY'] || '' | |
plist['FacebookAppID'] = ENV['FB_APP_ID'] | |
plist['FacebookDisplayName'] = ENV['APP_NAME'] | |
} | |
) | |
update_url_schemes( | |
path: 'ios/flex/Info.plist', | |
url_schemes: [ENV['APP_SCHEME'], "fb#{ENV['FB_APP_ID']}"] | |
) | |
# FIXME | |
sh "mv ../ios/flex/flex.entitlements ../ios/flex/flex.entitlements.plist" | |
update_info_plist( | |
xcodeproj: 'ios/flex.xcodeproj', | |
plist_path: 'flex/flex.entitlements.plist', | |
block: lambda { |plist| | |
plist['com.apple.developer.associated-domains'] = [ | |
"applinks:#{ENV['BRANCH_APP_SUBDOMAIN']}.app.link", | |
"applinks:#{ENV['BRANCH_APP_SUBDOMAIN']}-alternate.app.link", | |
"applinks:#{ENV['BRANCH_APP_SUBDOMAIN']}.test-app.link", | |
"applinks:#{ENV['BRANCH_APP_SUBDOMAIN']}-alternate.test-app.link", | |
] | |
} | |
) | |
sh "mv ../ios/flex/flex.entitlements.plist ../ios/flex/flex.entitlements" | |
update_info_plist( | |
xcodeproj: 'ios/flex.xcodeproj', | |
plist_path: 'Watch/Info.plist', | |
block: lambda { |plist| | |
plist['CFBundleDisplayName'] = ENV['APP_NAME'] | |
plist['CFBundleIdentifier'] = "#{ENV['APP_IDENTIFIER']}.watchkitapp" | |
plist['WKCompanionAppBundleIdentifier'] = ENV['APP_IDENTIFIER'] | |
} | |
) | |
update_info_plist( | |
xcodeproj: 'ios/flex.xcodeproj', | |
plist_path: 'Watch Extension/Info.plist', | |
block: lambda { |plist| | |
plist['CFBundleDisplayName'] = ENV['APP_NAME'] | |
plist['CFBundleIdentifier'] = "#{ENV['APP_IDENTIFIER']}.watchkitapp.watchkitextension" | |
plist['NSExtension']['NSExtensionAttributes']['WKAppBundleIdentifier'] = "#{ENV['APP_IDENTIFIER']}.watchkitapp" | |
} | |
) | |
end | |
def ios_app_identifiers | |
[ | |
ENV['APP_IDENTIFIER'], | |
"#{ENV['APP_IDENTIFIER']}.watchkitapp", | |
"#{ENV['APP_IDENTIFIER']}.watchkitapp.watchkitextension" | |
] | |
end | |
def ios_update_build_settings | |
update_xcodeproj( | |
xcodeproj: 'ios/flex.xcodeproj', | |
options: { | |
'CODE_SIGN_STYLE' => 'Manual', | |
'CODE_SIGN_IDENTITY' => 'iPhone Distribution', | |
'DEVELOPMENT_TEAM' => 'G382HP35RL', | |
} | |
) | |
update_xcodeproj( | |
xcodeproj: 'ios/flex.xcodeproj', | |
target_filter: 'flex', | |
options: { | |
'PROVISIONING_PROFILE' => ENV['APP_PROVISIONING_PROFILE'], | |
'PROVISIONING_PROFILE_SPECIFIER' => "match AppStore #{ENV['APP_IDENTIFIER']}", | |
} | |
) | |
update_xcodeproj( | |
xcodeproj: 'ios/flex.xcodeproj', | |
target_filter: 'Watch', | |
options: { | |
'PROVISIONING_PROFILE' => ENV['APP_WATCH_PROVISIONING_PROFILE'], | |
'PROVISIONING_PROFILE_SPECIFIER' => "match AppStore #{ENV['APP_IDENTIFIER']}.watchkitapp", | |
} | |
) | |
update_xcodeproj( | |
xcodeproj: 'ios/flex.xcodeproj', | |
target_filter: 'Watch Extension', | |
options: { | |
'PROVISIONING_PROFILE' => ENV['APP_EXTENSION_PROVISIONING_PROFILE'], | |
'PROVISIONING_PROFILE_SPECIFIER' => "match AppStore #{ENV['APP_IDENTIFIER']}.watchkitapp.watchkitextension", | |
} | |
) | |
end | |
def ios_build_app | |
build_app( | |
workspace: 'ios/flex.xcworkspace', | |
scheme: 'flex', | |
skip_profile_detection: true, | |
export_options: { | |
method: 'app-store', | |
provisioningProfiles: { | |
ENV['APP_IDENTIFIER'] => "match AppStore #{ENV['APP_IDENTIFIER']}", | |
"#{ENV['APP_IDENTIFIER']}.watchkitapp" => "match AppStore #{ENV['APP_IDENTIFIER']}.watchkitapp", | |
"#{ENV['APP_IDENTIFIER']}.watchkitapp.watchkitextension" => "match AppStore #{ENV['APP_IDENTIFIER']}.watchkitapp.watchkitextension", | |
}, | |
}, | |
) | |
end | |
############################### | |
######## A n d r o i d ######## | |
############################### | |
platform :android do | |
before_all do | |
update_fastlane | |
ANDROID_VERSION_NAME = get_version_name( | |
gradle_file_path: 'android/app/build.gradle', | |
ext_constant_name: 'versionName' | |
) | |
ANDROID_VERSION_CODE = get_version_code( | |
gradle_file_path: 'android/app/build.gradle', | |
ext_constant_name: 'versionCode' | |
) | |
end | |
desc 'Runs all the tests' | |
lane :test do | |
gradle(task: 'test') | |
end | |
desc 'Build and run on connected device' | |
lane :dev do | |
gradle(task: 'clean', project_dir: 'android/') | |
gradle(task: 'assemble', build_type: 'Debug', project_dir: 'android/') | |
# add_badge( | |
# glob: "/android/app/src/main/res/mipmap-*/ic_launcher.png", | |
# shield: "#{ANDROID_VERSION_NAME}-#{ANDROID_VERSION_CODE}- | |
# blue", | |
# shield_scale: '0.75', | |
# ) | |
sh `adb shell am start -n com.sweatflex.flex/com.sweatflex.flex.MainActivity` | |
end | |
lane :staging do | |
gradle(task: 'clean', project_dir: 'android/') | |
gradle(task: 'assembleRelease', project_dir: 'android/') | |
# add_badge( | |
# glob: "/android/app/src/main/res/mipmap-*/ic_launcher.png", | |
# shield: "#{ANDROID_VERSION_NAME}-#{ANDROID_VERSION_CODE}- | |
# blue", | |
# shield_scale: '0.75', | |
# ) | |
# upload_to_play_store(track: 'alpha', apk: 'android/app/build/outputs/apk/app-release.apk') | |
sh `adb install android/app/build/outputs/apk/app-release.apk` | |
# sh `adb shell am start -n com.sweatflex.flex/com.sweatflex.flex.MainActivity` | |
end | |
desc 'Submit a new build to Google Play Beta' | |
lane :beta do | |
gradle(task: 'clean', project_dir: 'android/') | |
gradle(task: 'assembleRelease', project_dir: 'android/') | |
upload_to_play_store(track: 'beta', apk: 'android/app/build/outputs/apk/app-release.apk') | |
send_build_to_bugsnag | |
# sh 'your_script.sh' | |
# You can also use other beta testing services here | |
end | |
desc 'Deploy a new version to the Google Play' | |
lane :deploy do | |
gradle(task: 'assembleRelease', project_dir: 'android/') | |
upload_to_play_store(apk: 'android/app/build/outputs/apk/app-release.apk') | |
send_build_to_bugsnag | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Autogenerated by fastlane | |
# | |
# Ensure this file is checked in to source control! | |
gem 'fastlane-plugin-bugsnag' | |
gem 'fastlane-plugin-get_version_name' | |
gem 'fastlane-plugin-get_version_code' | |
gem 'fastlane-plugin-update_xcodeproj', github: 'flextv/fastlane-plugin-update_xcodeproj', branch: 'target_filter' |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment