Merge pull request #186 from TouchInstinct/feature/SyncSymbols_lane

add SyncSymbols lane
This commit is contained in:
Ivan Smolin 2020-04-29 17:19:59 +03:00 committed by GitHub
commit 5e4283a1ac
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 183 additions and 81 deletions

View File

@ -1,5 +1,7 @@
$appName = File.basename(Dir['../*.xcworkspace'].first, '.*')
require_relative 'fastlane/touchlane/lib/touchlane'
private_lane :installDependencies do |options|
podsReposPath = File.expand_path "~/.cocoapods/repos/master/"
lockFilePath = "#{podsReposPath}/.git/index.lock"
@ -52,13 +54,24 @@ private_lane :uploadToFirebase do |options|
sh("yarn install")
app_target_folder_name = options[:appName] || $appName
configuration_type = Touchlane::ConfigurationType.from_type(options[:type])
gsp_plist_path = get_google_services_plist_path(app_target_folder_name, configuration_type)
google_app_id = get_info_plist_value(path: gsp_plist_path, key: "GOOGLE_APP_ID")
firebase_app_distribution(
app: get_google_app_identifier(options),
app: google_app_id,
ipa_path: options[:ipa_path],
groups: "touch-instinct",
release_notes_file: releaseNotesFile,
firebase_cli_path: File.expand_path("../node_modules/firebase-tools/lib/bin/firebase.js")
)
upload_symbols_to_crashlytics(
gsp_path: get_google_services_plist_path(app_target_folder_name, configuration_type)
)
end
private_lane :uploadToAppStore do |options|
@ -75,13 +88,17 @@ end
private_lane :buildConfiguration do |options|
appName = options[:appName] || $appName
lane_name = lane_context[SharedValues::LANE_NAME]
options[:scheme] = appName
options[:xcconfig_name] = lane_name
configuration = options[:configuration] || lane_context[SharedValues::LANE_NAME]
options = options.merge(make_options_for_lane_name(configuration))
options = merge_options_with_config_file(options)
configuration_type = Touchlane::ConfigurationType.from_lane_name(lane_name)
configuration = get_configuration_for_type(configuration_type.type)
options = options.merge(get_keychain_options(options))
options = configuration.to_options
.merge(get_keychain_options(options))
.merge(options)
openKeychain(options)
@ -103,7 +120,6 @@ private_lane :buildConfiguration do |options|
installDependencies(options)
if !(options[:uploadToFabric] || options[:uploadToAppStore])
options = merge_options_with_config_file(options)
options[:skip_package_ipa] = true
syncCodeSigning(options)
@ -112,8 +128,6 @@ private_lane :buildConfiguration do |options|
end
if options[:uploadToFabric]
options = merge_options_with_config_file(options)
syncCodeSigning(options)
buildArchive(options)
@ -123,8 +137,6 @@ private_lane :buildConfiguration do |options|
if options[:uploadToAppStore]
options[:compileBitcode] = options[:compileBitcode].nil? ? true : options[:compileBitcode]
options[:include_symbols] = options[:include_symbols].nil? ? true : options[:include_symbols]
options = options.merge(make_options_for_lane_name("AppStore"))
options = merge_options_with_config_file(options)
syncCodeSigning(options)
@ -138,11 +150,11 @@ private_lane :buildArchive do |options|
exportOptions = icloudEnvironment.to_s.empty? ? {} : {iCloudContainerEnvironment: icloudEnvironment}
exportOptions[:compileBitcode] = options[:compileBitcode] || false
xcconfig_name = options[:configuration]
configuration_name = options[:configuration_name]
xcconfig_name = options[:xcconfig_name]
configuration = options[:configuration]
xcodeproj_path = options[:xcodeproj_path]
set_xcconfig_for_configuration_of_project(xcconfig_name, configuration_name, xcodeproj_path)
set_xcconfig_for_configuration_of_project(xcconfig_name, configuration, xcodeproj_path)
gym(
clean: true,
@ -151,8 +163,8 @@ private_lane :buildArchive do |options|
archive_path: "./",
output_directory: "./",
output_name: options[:output_name],
configuration: configuration_name,
export_method: options[:method],
configuration: configuration,
export_method: options[:export_method],
export_options: exportOptions,
skip_package_ipa: options[:skip_package_ipa],
include_symbols: options[:include_symbols] || false,
@ -189,6 +201,8 @@ lane :syncCodeSigning do |options|
storage_mode: "git",
git_url: options[:git_url],
git_branch: "fastlane_certificates",
shallow_clone: true,
clone_branch_directly: true,
keychain_name: options[:keychain_name],
keychain_password: options[:keychain_password],
skip_docs: true,
@ -196,6 +210,36 @@ lane :syncCodeSigning do |options|
)
end
lane :SyncSymbols do |options|
configuration = get_configuration_for_type(options[:type])
options = configuration.to_options.merge(options)
appName = options[:appName] || $appName
xcodeproj_path = File.expand_path "../#{appName}.xcodeproj"
version_number = options[:version] || get_version_number(xcodeproj: xcodeproj_path, target: appName)
build_number = options[:build_number] || get_build_number(xcodeproj: xcodeproj_path)
if configuration.type.is_app_store
download_dsyms(
username: options[:username],
app_identifier: options[:app_identifier].first,
team_id: options[:itc_team_id],
version: version_number,
build_number: build_number
)
end
app_target_folder_name = appName
upload_symbols_to_crashlytics(
gsp_path: get_google_services_plist_path(app_target_folder_name, configuration.type)
)
clean_build_artifacts
end
private_lane :openKeychain do |options|
if is_ci?
# workaround to avoid duplication problem
@ -305,74 +349,17 @@ def get_keychain_options(options)
return {:keychain_name => keychain_name, :keychain_password => keychain_password}
end
def configuration_type_from_lane_name(lane_name)
case
when lane_name.start_with?("Enterprise")
"enterprise"
when lane_name.start_with?("AppStore")
"app-store"
else
"development"
end
def get_configuration_for_type(type)
config_path = File.expand_path "configurations.yaml"
configuration = Touchlane::Configuration.from_file(config_path, type)
end
def profile_type_from_configuration_type(configuration_type)
configuration_type.gsub("-", "") # "app-store" => "appstore"
def get_google_services_plist_path(app_target_folder_name, configuration_type)
File.expand_path "../#{app_target_folder_name}/Resources/#{configuration_type.prefix}-GoogleService-Info.plist"
end
def make_options_for_lane_name(lane_name)
method = configuration_type_from_lane_name(lane_name)
return {
:configuration => lane_name.start_with?("AppStore") ? "AppStore" : lane_name,
:configuration_name => lane_name.start_with?("AppStore") ? "AppStore" : "Release",
:method => method,
:type => profile_type_from_configuration_type(method)
}
end
def merge_options_with_config_file(options)
type = options[:type] || "development"
options_override = load_options_from("configurations.yaml")
return options.merge(options_override[type.to_sym])
end
def load_options_from(file_path)
if File.exists? file_path
require "yaml"
options = YAML.load_file(file_path)
return symbolize_keys(options)
end
return nil
end
# http://www.virtuouscode.com/2009/07/14/recursively-symbolize-keys/
def symbolize_keys(hash)
hash.inject({}){|result, (key, value)|
new_key = case key
when String then key.to_sym
else key
end
new_value = case value
when Hash then symbolize_keys(value)
else value
end
result[new_key] = new_value
result
}
end
def get_google_app_identifier(options)
file_name_prefix = options[:type].capitalize
appName = options[:appName] || $appName
file_path = File.expand_path "../#{appName}/Resources/#{file_name_prefix}-GoogleService-Info.plist"
get_info_plist_value(path: file_path, key: "GOOGLE_APP_ID")
end
def set_xcconfig_for_configuration_of_project(xcconfig_name, configuration_name, xcodeproj_path)
def set_xcconfig_for_configuration_of_project(xcconfig_name, configuration, xcodeproj_path)
require 'xcodeproj'
project = Xcodeproj::Project.open(xcodeproj_path)
@ -383,12 +370,12 @@ def set_xcconfig_for_configuration_of_project(xcconfig_name, configuration_name,
Xcodeproj::Constants::PRODUCT_TYPE_UTI[:app_extension]
]
return !t.test_target_type? && supported_product_types.include?(t.product_type)
end
end
application_targets = project.native_targets.select(&target_to_modify_selector)
application_targets.each do |target|
build_configuration = target.build_configuration_list[configuration_name]
build_configuration = target.build_configuration_list[configuration]
config_name = target.name + xcconfig_name
build_configuration_reference = project.files.select { |f| f.path.start_with?(config_name) }.first
build_configuration.base_configuration_reference = build_configuration_reference

View File

@ -0,0 +1,48 @@
require "yaml"
module Touchlane
class Configuration
def initialize(type, app_identifier, apple_id, team_id, itc_team_id)
@type = type
@app_identifier = app_identifier
@apple_id = apple_id
@team_id = team_id
@itc_team_id = itc_team_id
end
attr_reader :type, :app_identifier, :apple_id, :team_id, :itc_team_id
def self.from_file(path, type)
hash_of_types = load_hash_of_types_from_file(path)
attrs_hash = hash_of_types[type]
unless attrs_hash
raise "There is no configuration with type #{type}. Available types: #{attrs_hash.keys}"
else
config_type = Touchlane::ConfigurationType.from_type(type)
new(config_type, attrs_hash["app_identifier"], attrs_hash["apple_id"], attrs_hash["team_id"], attrs_hash["itc_team_id"])
end
end
def self.load_hash_of_types_from_file(path)
unless File.exists? path
raise "Unable to load configurations from file at #{path}"
else
YAML.load_file(path)
end
end
private_class_method :new, :load_hash_of_types_from_file
def to_options
{
:app_identifier => @app_identifier,
:apple_id => @apple_id,
:username => @apple_id,
:team_id => @team_id,
:itc_team_id => @itc_team_id,
}
.merge(type.to_options)
end
end
end

View File

@ -0,0 +1,63 @@
module Touchlane
class ConfigurationType
DEVELOPMENT = "development"
ENTERPRISE = "enterprise"
APP_STORE = "appstore"
DEVELOPMENT_PREFIX = "Standard"
ENTERPRISE_PREFIX = "Enterprise"
APP_STORE_PREFIX = "AppStore"
private_constant :DEVELOPMENT, :ENTERPRISE, :APP_STORE
private_constant :DEVELOPMENT_PREFIX, :ENTERPRISE_PREFIX, :APP_STORE_PREFIX
def initialize(type)
@type = type
case type
when DEVELOPMENT, ENTERPRISE
@export_method = type
@configuration = type == DEVELOPMENT ? "Debug" : "Release"
@is_app_store = false
@prefix = type == DEVELOPMENT ? DEVELOPMENT_PREFIX : ENTERPRISE_PREFIX
when APP_STORE
@export_method = "app-store"
@configuration = "AppStore"
@is_app_store = true
@prefix = APP_STORE_PREFIX
else
raise "Unknown type passed #{type}"
end
end
private_class_method :new
attr_reader :export_method, :type, :configuration, :is_app_store, :prefix
def self.from_lane_name(lane_name)
case
when lane_name.start_with?(ENTERPRISE_PREFIX)
from_type(ENTERPRISE)
when lane_name.start_with?(APP_STORE_PREFIX)
from_type(APP_STORE)
when lane_name.start_with?(DEVELOPMENT_PREFIX)
from_type(DEVELOPMENT)
else
raise "Unable to map #{lane_name} to #{ConfigurationType.class}."
+ "Available prefixes: #{DEVELOPMENT_PREFIX}, #{ENTERPRISE_PREFIX}, #{APP_STORE_PREFIX}"
end
end
def self.from_type(type)
new(type)
end
def to_options
{
:type => @type,
:export_method => @export_method,
:configuration => @configuration
}
end
end
end

View File

@ -0,0 +1,4 @@
module Touchlane
require_relative "configuration_type"
require_relative "configuration"
end