Skip to content

Instantly share code, notes, and snippets.

@petrbela
Last active December 1, 2022 01:30
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save petrbela/79f4a75d087239eb8b904a27cfa28feb to your computer and use it in GitHub Desktop.
Save petrbela/79f4a75d087239eb8b904a27cfa28feb to your computer and use it in GitHub Desktop.
React Native deployment
# 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
# 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