Merge pull request #92 from TouchInstinct/feature/fastlane_match
fastlane match & upload to App Store
This commit is contained in:
commit
631d186d50
|
|
@ -1,7 +1,6 @@
|
|||
$appName = File.basename(Dir['../*.xcworkspace'].first, '.*')
|
||||
|
||||
before_all do |lane, options|
|
||||
appName = options[:appName] || $appName
|
||||
private_lane :installDependencies do |options|
|
||||
podsReposPath = File.expand_path "~/.cocoapods/repos/master/"
|
||||
lockFilePath = "#{podsReposPath}/.git/index.lock"
|
||||
|
||||
|
|
@ -15,62 +14,251 @@ before_all do |lane, options|
|
|||
end
|
||||
|
||||
cocoapods(
|
||||
clean: true,
|
||||
repo_update: true
|
||||
)
|
||||
|
||||
set_info_plist_value(
|
||||
path: "./#{appName}/Info.plist",
|
||||
key: "CFBundleVersion",
|
||||
value: options[:buildNumber] || 10000
|
||||
repo_update: false
|
||||
)
|
||||
end
|
||||
|
||||
after_all do |lane, options|
|
||||
if options[:uploadToFabric]
|
||||
appName = options[:appName] || $appName
|
||||
private_lane :uploadToFabric do |options|
|
||||
token, secret = fabric_keys_from_xcodeproj(options[:xcodeproj_path])
|
||||
|
||||
token = sh("cat ../#{appName}.xcodeproj/project.pbxproj | grep 'Fabric/run' | awk '{print $4}' | tr -d '\\n'")
|
||||
secret = sh("printf `cat ../#{appName}.xcodeproj/project.pbxproj | grep 'Fabric/run' | awk '{print $5}' | sed 's/..$//'` | tr -d '\\n'")
|
||||
releaseNotesFile = "release-notes.txt"
|
||||
sh("touch ../#{releaseNotesFile}")
|
||||
|
||||
releaseNotesFile = "release-notes.txt"
|
||||
sh("touch ../#{releaseNotesFile}")
|
||||
crashlytics(
|
||||
ipa_path: options[:ipa_path],
|
||||
crashlytics_path: "./Pods/Crashlytics/submit",
|
||||
api_token: token,
|
||||
build_secret: secret,
|
||||
notes_path: releaseNotesFile,
|
||||
groups: "touch-instinct"
|
||||
)
|
||||
|
||||
crashlytics(
|
||||
ipa_path: "./#{appName}.ipa",
|
||||
crashlytics_path: "./Pods/Crashlytics/",
|
||||
api_token: token,
|
||||
build_secret: secret,
|
||||
notes_path: releaseNotesFile,
|
||||
groups: "touch-instinct"
|
||||
)
|
||||
upload_symbols_to_crashlytics(
|
||||
dsym_path: options[:dsym_path],
|
||||
api_token: token
|
||||
)
|
||||
end
|
||||
|
||||
upload_symbols_to_crashlytics(
|
||||
dsym_path: "./#{appName}.app.dSYM.zip",
|
||||
api_token: token
|
||||
)
|
||||
end
|
||||
private_lane :uploadToAppStore do |options|
|
||||
upload_to_app_store(
|
||||
username: options[:username] || options[:apple_id],
|
||||
ipa: options[:ipa_path],
|
||||
force: true, # skip metainfo prompt
|
||||
skip_metadata: true,
|
||||
team_id: options[:itc_team_id],
|
||||
dev_portal_team_id: options[:team_id]
|
||||
)
|
||||
end
|
||||
|
||||
private_lane :buildConfiguration do |options|
|
||||
configuration = lane_context[SharedValues::LANE_NAME]
|
||||
method = configuration.start_with?("Enterprise") ? "enterprise" : "development"
|
||||
appName = options[:appName] || $appName
|
||||
uploadToFabric = options[:uploadToFabric]
|
||||
|
||||
options[:scheme] = appName
|
||||
|
||||
configuration = options[:configuration] || lane_context[SharedValues::LANE_NAME]
|
||||
options = options.merge(make_options_for_lane_name(configuration))
|
||||
options = merge_options_with_config_file(options)
|
||||
|
||||
options = options.merge(get_keychain_options(options))
|
||||
|
||||
openKeychain(options)
|
||||
|
||||
if is_ci
|
||||
increment_build_number(
|
||||
build_number: options[:buildNumber]
|
||||
)
|
||||
end
|
||||
|
||||
ipa_name = "#{appName}.ipa"
|
||||
options[:output_name] = ipa_name
|
||||
|
||||
options[:ipa_path] = "./#{ipa_name}"
|
||||
options[:dsym_path] = "./#{appName}.app.dSYM.zip"
|
||||
|
||||
options[:xcodeproj_path] = "../#{appName}.xcodeproj"
|
||||
options[:workspace] = "./#{appName}.xcworkspace"
|
||||
|
||||
installDependencies(options)
|
||||
|
||||
if !(options[:uploadToFabric] || options[:uploadToAppStore])
|
||||
options = merge_options_with_config_file(options)
|
||||
options[:skip_package_ipa] = true
|
||||
|
||||
syncCodeSigning(options)
|
||||
|
||||
buildArchive(options) # check build failures and static analysis
|
||||
end
|
||||
|
||||
if options[:uploadToFabric]
|
||||
options = merge_options_with_config_file(options)
|
||||
|
||||
buildArchive(options)
|
||||
syncCodeSigning(options)
|
||||
|
||||
uploadToFabric(options)
|
||||
end
|
||||
|
||||
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)
|
||||
|
||||
buildArchive(options)
|
||||
uploadToAppStore(options)
|
||||
end
|
||||
end
|
||||
|
||||
private_lane :buildArchive do |options|
|
||||
icloudEnvironment = options[:iCloudContainerEnvironment] || ""
|
||||
exportOptions = icloudEnvironment.to_s.empty? ? {} : {iCloudContainerEnvironment: icloudEnvironment}
|
||||
exportOptions[:compileBitcode] = options[:compileBitcode] || false
|
||||
|
||||
gym(
|
||||
clean: true,
|
||||
workspace: "./#{appName}.xcworkspace",
|
||||
scheme: appName,
|
||||
workspace: options[:workspace],
|
||||
scheme: options[:scheme],
|
||||
archive_path: "./",
|
||||
output_directory: "./",
|
||||
output_name: "#{appName}.ipa",
|
||||
configuration: configuration,
|
||||
export_method: method,
|
||||
output_name: options[:output_name],
|
||||
configuration: options[:configuration],
|
||||
export_method: options[:method],
|
||||
export_options: exportOptions,
|
||||
skip_package_ipa: !uploadToFabric
|
||||
skip_package_ipa: options[:skip_package_ipa],
|
||||
include_symbols: options[:include_symbols] || false,
|
||||
include_bitcode: options[:compileBitcode] || false,
|
||||
)
|
||||
end
|
||||
|
||||
lane :СreatePushCertificate do |options|
|
||||
certificates_path = File.expand_path "../Certificates"
|
||||
Dir.mkdir(certificates_path) unless File.directory?(certificates_path)
|
||||
|
||||
get_push_certificate(
|
||||
development: options[:development] || true,
|
||||
generate_p12: true,
|
||||
active_days_limit: 30, # create new certificate if old one will expire in 30 days
|
||||
save_private_key: false,
|
||||
app_identifier: options[:app_identifier],
|
||||
p12_password: "123", # empty password won't work with Pusher
|
||||
output_path: certificates_path
|
||||
)
|
||||
end
|
||||
|
||||
lane :syncCodeSigning do |options|
|
||||
match(
|
||||
app_identifier: options[:app_identifier],
|
||||
username: options[:username] || options[:apple_id],
|
||||
team_id: options[:team_id],
|
||||
type: options[:type],
|
||||
readonly: options[:readonly] || true,
|
||||
storage_mode: "git",
|
||||
git_url: options[:git_url],
|
||||
git_branch: "fastlane_certificates",
|
||||
keychain_name: options[:keychain_name],
|
||||
keychain_password: options[:keychain_password],
|
||||
skip_docs: true,
|
||||
platform: "ios"
|
||||
)
|
||||
end
|
||||
|
||||
private_lane :openKeychain do |options|
|
||||
if is_ci?
|
||||
create_keychain(
|
||||
name: options[:keychain_name],
|
||||
password: options[:keychain_password],
|
||||
unlock: true
|
||||
)
|
||||
else
|
||||
unlock_keychain(
|
||||
path: options[:keychain_name],
|
||||
password: options[:keychain_password]
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
def get_keychain_options(options)
|
||||
keychain_name = options[:keychain_name]
|
||||
keychain_password = options[:keychain_password]
|
||||
|
||||
if is_ci?
|
||||
keychain_name = keychain_name || "ci.keychain"
|
||||
keychain_password = keychain_password || ""
|
||||
else
|
||||
keychain_password = keychain_password || prompt(
|
||||
text: "Please enter your keychain password (account password): ",
|
||||
secure_text: true
|
||||
)
|
||||
end
|
||||
|
||||
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
|
||||
end
|
||||
|
||||
def profile_type_from_configuration_type(configuration_type)
|
||||
configuration_type.gsub("-", "") # "app-store" => "appstore"
|
||||
end
|
||||
|
||||
def make_options_for_lane_name(lane_name)
|
||||
method = configuration_type_from_lane_name(lane_name)
|
||||
return {
|
||||
:configuration => lane_name,
|
||||
: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 fabric_keys_from_xcodeproj(xcodeproj_path)
|
||||
fabric_keys_from_shell_script(sh("cat #{xcodeproj_path}/project.pbxproj | grep 'Fabric/run'"))
|
||||
end
|
||||
|
||||
def fabric_keys_from_shell_script(shell_script_contents)
|
||||
shell_script_contents.partition('Fabric/run\" ').last.partition('";').first.split(" ")
|
||||
end
|
||||
|
|
|
|||
Loading…
Reference in New Issue