Merge pull request #132 from TouchInstinct/feature/experimential_configuration_select
build Release configuration with specific xcconfig
This commit is contained in:
commit
a88561ce7f
|
|
@ -13,19 +13,37 @@ private_lane :installDependencies do |options|
|
|||
bundle_install(path: "../.gem")
|
||||
end
|
||||
|
||||
if File.exists? "../Cartfile"
|
||||
begin
|
||||
carthage(command: "bootstrap", platform: "iOS")
|
||||
rescue
|
||||
# workaround for https://github.com/Carthage/Carthage/issues/2298
|
||||
sh("rm -rf ~/Library/Caches/org.carthage.CarthageKit")
|
||||
carthage(command: "update", platform: "iOS")
|
||||
end
|
||||
end
|
||||
|
||||
cocoapods(
|
||||
repo_update: true
|
||||
)
|
||||
|
||||
if File.exists? "../Cartfile"
|
||||
use_rome = File.exists? "../Romefile"
|
||||
|
||||
swift_version = sh("xcrun swift --version | head -1 | sed 's/.*\\(\(.*\)\\).*/\\1/' | tr -d \"()\" | tr \" \" \"-\"").chop
|
||||
rome_path = "Pods/Rome/rome"
|
||||
rome_options = "--platform iOS --cache-prefix #{swift_version} --romefile Romefile"
|
||||
|
||||
carthage_install = lambda do
|
||||
if use_rome
|
||||
sh("cd .. && #{rome_path} download #{rome_options}")
|
||||
end
|
||||
|
||||
carthage(command: "bootstrap", platform: "iOS", cache_builds: true)
|
||||
|
||||
if use_rome
|
||||
sh("cd .. && #{rome_path} list --missing #{rome_options} | awk '{print $1}' | xargs -I framework_name #{rome_path} upload framework_name #{rome_options}")
|
||||
end
|
||||
end
|
||||
|
||||
begin
|
||||
carthage_install.call
|
||||
rescue
|
||||
# workaround for https://github.com/Carthage/Carthage/issues/2298
|
||||
sh("rm -rf ~/Library/Caches/org.carthage.CarthageKit")
|
||||
carthage_install.call
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private_lane :uploadToFabric do |options|
|
||||
|
|
@ -126,6 +144,12 @@ 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]
|
||||
xcodeproj_path = options[:xcodeproj_path]
|
||||
|
||||
set_xcconfig_for_configuration_of_project(xcconfig_name, configuration_name, xcodeproj_path)
|
||||
|
||||
gym(
|
||||
clean: true,
|
||||
workspace: options[:workspace],
|
||||
|
|
@ -133,7 +157,7 @@ private_lane :buildArchive do |options|
|
|||
archive_path: "./",
|
||||
output_directory: "./",
|
||||
output_name: options[:output_name],
|
||||
configuration: options[:configuration],
|
||||
configuration: configuration_name,
|
||||
export_method: options[:method],
|
||||
export_options: exportOptions,
|
||||
skip_package_ipa: options[:skip_package_ipa],
|
||||
|
|
@ -212,7 +236,7 @@ lane :ManuallyUpdateCodeSigning do |options|
|
|||
shallow_clone = false
|
||||
branch = 'fastlane_certificates'
|
||||
|
||||
storage_conf = lambda do
|
||||
storage_conf = lambda do
|
||||
new_storage = Match::Storage.for_mode('git', { git_url: git_url, shallow_clone: shallow_clone, git_branch: branch, clone_branch_directly: false})
|
||||
new_storage.download
|
||||
return new_storage
|
||||
|
|
@ -255,7 +279,7 @@ lane :ManuallyUpdateCodeSigning do |options|
|
|||
storage = storage_conf.call
|
||||
encryption = encryption_conf_for_storage.call(storage)
|
||||
|
||||
files_to_delete = files_diff.map do |file|
|
||||
files_to_delete = files_diff.map do |file|
|
||||
old_file = file
|
||||
old_file.slice! old_directory
|
||||
new_file = File.join(storage.working_directory, old_file)
|
||||
|
|
@ -305,7 +329,8 @@ end
|
|||
def make_options_for_lane_name(lane_name)
|
||||
method = configuration_type_from_lane_name(lane_name)
|
||||
return {
|
||||
:configuration => lane_name,
|
||||
: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)
|
||||
}
|
||||
|
|
@ -353,3 +378,29 @@ end
|
|||
def fabric_keys_from_shell_script(shell_script_contents)
|
||||
shell_script_contents.gsub("\\n", "").partition('Fabric/run\" ').last.partition('";').first.split(" ")
|
||||
end
|
||||
|
||||
def set_xcconfig_for_configuration_of_project(xcconfig_name, configuration_name, xcodeproj_path)
|
||||
require 'xcodeproj'
|
||||
|
||||
project = Xcodeproj::Project.open(xcodeproj_path)
|
||||
|
||||
target_to_modify_selector = lambda do |t|
|
||||
supported_product_types = [
|
||||
Xcodeproj::Constants::PRODUCT_TYPE_UTI[:application],
|
||||
Xcodeproj::Constants::PRODUCT_TYPE_UTI[:app_extension]
|
||||
]
|
||||
return !t.test_target_type? && supported_product_types.include?(t.product_type)
|
||||
end
|
||||
|
||||
application_targets = project.native_targets.select(&target_to_modify_selector)
|
||||
|
||||
application_targets.each do |target|
|
||||
build_configuration = target.build_configuration_list[configuration_name]
|
||||
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
|
||||
end
|
||||
|
||||
|
||||
project.save()
|
||||
end
|
||||
|
|
|
|||
|
|
@ -0,0 +1,25 @@
|
|||
{
|
||||
"targets": [
|
||||
{
|
||||
"YOUR_TARGET_NAME": {
|
||||
"Standard": {
|
||||
"PROVISIONING_PROFILE_SPECIFIER": "",
|
||||
"PRODUCT_BUNDLE_IDENTIFIER": "",
|
||||
"CODE_SIGN_ENTITLEMENTS": ""
|
||||
},
|
||||
|
||||
"Enterprise": {
|
||||
"PROVISIONING_PROFILE_SPECIFIER": "",
|
||||
"PRODUCT_BUNDLE_IDENTIFIER": "",
|
||||
"CODE_SIGN_ENTITLEMENTS": ""
|
||||
},
|
||||
|
||||
"AppStore": {
|
||||
"DEVELOPMENT_TEAM": "",
|
||||
"PRODUCT_BUNDLE_IDENTIFIER": "",
|
||||
"CODE_SIGN_ENTITLEMENTS": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,94 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import unicode_literals # python 2/3 support
|
||||
|
||||
from itertools import chain
|
||||
import json
|
||||
|
||||
distribution_options = ["Enterprise", "Standard"]
|
||||
server_type_options = ["Mock", "Touchin", "Customer"]
|
||||
server_environment_options = ["Dev", "Test", "Stage", "Prod"]
|
||||
ssl_pinning_options = ["WithSSLPinning", "WithoutSSLPinning"]
|
||||
build_type_options = ["Debug", "Release"]
|
||||
|
||||
all_options = [
|
||||
distribution_options,
|
||||
server_type_options,
|
||||
server_environment_options,
|
||||
ssl_pinning_options,
|
||||
build_type_options
|
||||
]
|
||||
|
||||
def combine_string_with_options(all_options, string="", applied_options=[]):
|
||||
if len(all_options) == 0:
|
||||
yield string, applied_options
|
||||
return
|
||||
|
||||
for current_option in chain.from_iterable(all_options[:1]):
|
||||
for result_tuple in combine_string_with_options(all_options[1:], string + current_option, applied_options + [current_option]):
|
||||
yield result_tuple
|
||||
|
||||
yield ("AppStoreRelease", ['AppStore', 'Customer', 'Prod', 'WithSSLPinning', 'Release'])
|
||||
|
||||
def make_config_dict(args):
|
||||
config_name, applied_options = args
|
||||
|
||||
if "Enterprise" in applied_options:
|
||||
account_type = "Enterprise"
|
||||
elif "Standard" in applied_options:
|
||||
account_type = "Standard"
|
||||
else:
|
||||
account_type = "AppStore"
|
||||
|
||||
if "Debug" in applied_options:
|
||||
build_type = "debug"
|
||||
elif "AppStore" in applied_options:
|
||||
build_type = "appstore"
|
||||
else:
|
||||
build_type = "release"
|
||||
|
||||
return {
|
||||
"name": config_name,
|
||||
"build_type": build_type,
|
||||
"account_type": account_type,
|
||||
"xcconfig_options": [
|
||||
{
|
||||
"key": "SWIFT_ACTIVE_COMPILATION_CONDITIONS",
|
||||
"value": " ".join(map(lambda option: option.upper(), applied_options))
|
||||
},
|
||||
{
|
||||
"key": "DEBUG_INFORMATION_FORMAT",
|
||||
"value": "dwarf" if "Debug" in applied_options else "dwarf-with-dsym"
|
||||
},
|
||||
{
|
||||
"key": "VALIDATE_PRODUCT",
|
||||
"value": "NO" if "Debug" in applied_options else "YES"
|
||||
},
|
||||
{
|
||||
"key": "ENABLE_TESTABILITY",
|
||||
"value": "YES" if "Debug" in applied_options else "NO"
|
||||
},
|
||||
{
|
||||
"key": "CODE_SIGN_IDENTITY",
|
||||
"value": "iPhone Developer" if account_type == "Standard" else "iPhone Distribution"
|
||||
},
|
||||
{
|
||||
"key": "GCC_OPTIMIZATION_LEVEL",
|
||||
"value": "0" if "Debug" in applied_options else "s"
|
||||
},
|
||||
{
|
||||
"key": "SWIFT_OPTIMIZATION_LEVEL",
|
||||
"value": "-Onone" if "Debug" in applied_options else "-O"
|
||||
},
|
||||
{
|
||||
"key": "SWIFT_COMPILATION_MODE",
|
||||
"value": "singlefile" if "Debug" in applied_options else "wholemodule"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
config_dicts = map(make_config_dict, combine_string_with_options(all_options))
|
||||
|
||||
print(json.dumps({"configurations": config_dicts}, indent=4))
|
||||
|
|
@ -0,0 +1,116 @@
|
|||
require 'json'
|
||||
require 'mustache'
|
||||
|
||||
# Constants
|
||||
$configs_folder_name = "TargetConfigurations"
|
||||
$standard_dev_team = "D4HA43V467"
|
||||
$enterprise_dev_team = "228J5MMU7S"
|
||||
$standard_bundle_prefix = "ru.touchin."
|
||||
$enterprise_bundle_prefix = "com.touchin."
|
||||
$bundle_id_key = "PRODUCT_BUNDLE_IDENTIFIER"
|
||||
|
||||
# create config directory if needed
|
||||
Dir.mkdir($configs_folder_name) unless Dir.exist?($configs_folder_name)
|
||||
|
||||
# call python script and generate configs to config file
|
||||
system("python gen_configurations.py > configs_data.json")
|
||||
|
||||
|
||||
# open settings + template file
|
||||
settings = JSON.load(File.open("custom_settings.json"))
|
||||
target_xcconfig_tempate = File.read("target_xcconfig.mustache")
|
||||
|
||||
|
||||
# set global property
|
||||
targets = settings["targets"]
|
||||
|
||||
# make tuple of key and value become mustache template element
|
||||
def config_option(key, value)
|
||||
return { "key" => key, "value" => value }
|
||||
end
|
||||
|
||||
# return empty array or generated dev team hash
|
||||
def generate_development_team(development_team_key, account_type)
|
||||
team_value = account_type == "Standard" ? $standard_dev_team : $enterprise_dev_team
|
||||
return config_option(development_team_key, team_value)
|
||||
end
|
||||
|
||||
# return empty array or generated provisioning profile hash
|
||||
def generate_provisioning_profile(provisioning_key, bundle_id, account_type)
|
||||
if account_type == "AppStore"
|
||||
app_store_profiile = "match AppStore " + bundle_id
|
||||
return config_option(provisioning_key, app_store_profiile)
|
||||
else
|
||||
return config_option(provisioning_key, bundle_id)
|
||||
end
|
||||
end
|
||||
|
||||
def generate_bundle_id(target_name, account_type)
|
||||
bundle_id_prefix = account_type == "Standard" ? $standard_bundle_prefix : $enterprise_bundle_prefix
|
||||
bundle_id = bundle_id_prefix + target_name
|
||||
return config_option($bundle_id_key, bundle_id)
|
||||
end
|
||||
|
||||
# generate missing properties if needed
|
||||
def generate_missing_properties(target_name, properties, account_type)
|
||||
result = []
|
||||
development_team_key = "DEVELOPMENT_TEAM"
|
||||
provisioning_key = "PROVISIONING_PROFILE_SPECIFIER"
|
||||
|
||||
unless properties.key?($bundle_id_key)
|
||||
bundle_id_config = generate_bundle_id(target_name, account_type)
|
||||
bundle_id = bundle_id_config["value"]
|
||||
result.append(bundle_id_config)
|
||||
else
|
||||
bundle_id = properties[$bundle_id_key]
|
||||
end
|
||||
|
||||
unless properties.key?(development_team_key)
|
||||
result.append(generate_development_team(development_team_key, account_type))
|
||||
end
|
||||
|
||||
unless properties.key?(provisioning_key)
|
||||
result.append(generate_provisioning_profile(provisioning_key, bundle_id, account_type))
|
||||
end
|
||||
|
||||
return result
|
||||
end
|
||||
|
||||
# run through all target in project
|
||||
targets.each do |target|
|
||||
|
||||
# need open everytime, because script make some changes only for this target
|
||||
configs = JSON.load(File.open("configs_data.json"))["configurations"]
|
||||
|
||||
# run through all configs
|
||||
configs.each do |config|
|
||||
|
||||
# take default values
|
||||
account_type = config["account_type"]
|
||||
target_name = target.keys.first
|
||||
properties = target[target_name][account_type]
|
||||
|
||||
# add properties from settings file
|
||||
properties.each do |key, value|
|
||||
config["xcconfig_options"].append(config_option(key, value))
|
||||
end
|
||||
|
||||
# add missing properties if needed
|
||||
config["xcconfig_options"].concat(generate_missing_properties(target_name, properties, account_type))
|
||||
|
||||
# create settings pack
|
||||
config_data = {
|
||||
"target_name": target_name,
|
||||
"configuration": config
|
||||
}
|
||||
|
||||
# create file for every setting in loop
|
||||
File.open($configs_folder_name + "/" + target_name + config["name"] + ".xcconfig", 'w') { |file|
|
||||
file.puts(Mustache.render(target_xcconfig_tempate, config_data))
|
||||
}
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
# remove config file, it's trash
|
||||
File.delete("configs_data.json") if File.exist?("configs_data.json")
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
#include "Pods/Target Support Files/Pods-{{target_name}}/Pods-{{target_name}}.{{configuration.build_type}}.xcconfig"
|
||||
|
||||
{{#configuration.xcconfig_options}}
|
||||
{{key}} = {{value}}
|
||||
{{/configuration.xcconfig_options}}
|
||||
|
||||
CODE_SIGN_STYLE = Manual
|
||||
Loading…
Reference in New Issue