From e44811d1b73f48a1b2c12456dfe0823a5151a953 Mon Sep 17 00:00:00 2001 From: Ivan Smolin Date: Wed, 17 Jan 2024 12:25:46 +0300 Subject: [PATCH 1/2] remove unused actions and methods --- xcode/commonFastfile | 52 ------------------- .../touchlane/lib/touchlane/features.rb | 26 ---------- xcode/managers/lib/file_manager.rb | 33 ------------ xcode/managers/lib/template_manager.rb | 19 ------- xcode/managers/managers.rb | 4 -- xcode/templates/templates.rb | 3 -- .../templates/templates/features_templates.rb | 34 ------------ 7 files changed, 171 deletions(-) delete mode 100644 xcode/fastlane/touchlane/lib/touchlane/features.rb delete mode 100644 xcode/managers/lib/file_manager.rb delete mode 100644 xcode/managers/lib/template_manager.rb delete mode 100644 xcode/managers/managers.rb delete mode 100644 xcode/templates/templates.rb delete mode 100755 xcode/templates/templates/features_templates.rb diff --git a/xcode/commonFastfile b/xcode/commonFastfile index e95320d..09e8757 100644 --- a/xcode/commonFastfile +++ b/xcode/commonFastfile @@ -1,7 +1,6 @@ $appName = File.basename(Dir['../*.xcworkspace'].first, '.*') require_relative 'fastlane/touchlane/lib/touchlane' -require_relative 'managers/managers' # ugly hack to add support for custom storage @@ -120,7 +119,6 @@ private_lane :buildConfiguration do |options| installDependencies(options) run_code_generation_phase_if_needed(options) - generate_enabled_features_extension_if_needed(options) if !(options[:uploadToFabric] || options[:uploadToAppStore]) options[:skip_package_ipa] = true @@ -194,28 +192,6 @@ private_lane :buildArchive do |options| ) end -lane :CreatePushCertificate do |options| - configuration = get_configuration_for_type(options[:type] || "development") - options = configuration.to_options.merge(options) - - certificates_path = File.expand_path "../Certificates" - Dir.mkdir(certificates_path) unless File.directory?(certificates_path) - - app_identifier = options[:app_identifier] - - get_push_certificate( - development: options[:development].nil? ? true : options[:development], - generate_p12: true, - active_days_limit: 30, # create new certificate if old one will expire in 30 days - save_private_key: false, - app_identifier: (app_identifier.is_a? Array) ? app_identifier.first : app_identifier, - username: options[:username] || options[:apple_id], - team_id: options[:team_id], - p12_password: "123", # empty password won't work with Pusher - output_path: certificates_path - ) -end - lane :SyncCodeSigning do |options| configuration_type = Touchlane::ConfigurationType.from_type(options[:type]) options = fill_up_options_using_configuration_type(options, configuration_type) @@ -414,34 +390,6 @@ def get_google_services_plist_path(app_target_folder_name, configuration_type) File.expand_path "../#{app_target_folder_name}/Resources/GoogleService-Info.plist" end -def generate_enabled_features_extension_if_needed(options) - app_target_folder_name = options[:appName] || $appName - - project_enabled_features_file_path = File.expand_path "../#{app_target_folder_name}/Resources/Features/Enabled.swift" - build_settings_file_path = File.expand_path "../common/build_settings.yaml" - - unless is_feature_extension_needed?(options, project_enabled_features_file_path) - return - end - - if options[:features].nil? - builder_features_list = [] # If Enabled.swift exists and features option is nil we need to create empty extension to avoid unexpected features - else - builder_features_list = options[:features] - .split(",").map { |feature_name| feature_name.strip } # [ "Feature1", "Feature2", "Feature3" ] - end - - build_settings_features_list = Managers::FileManager.load_from_file_YAML(build_settings_file_path)["features"] - - enabled_features_extension = Touchlane::Features.generate_enabled_features_extension(builder_features_list, build_settings_features_list) - - Managers::FileManager.save_data_to_file(project_enabled_features_file_path, enabled_features_extension) -end - -def is_feature_extension_needed?(options, project_enabled_features_file_path) - !options[:features].nil? || File.exists?(project_enabled_features_file_path) -end - def set_xcconfig_for_configuration_of_project(lane_name, configuration, xcodeproj_path) require 'xcodeproj' diff --git a/xcode/fastlane/touchlane/lib/touchlane/features.rb b/xcode/fastlane/touchlane/lib/touchlane/features.rb deleted file mode 100644 index cadfb0f..0000000 --- a/xcode/fastlane/touchlane/lib/touchlane/features.rb +++ /dev/null @@ -1,26 +0,0 @@ -require_relative '../../../../managers/managers' -require_relative '../../../../templates/templates' - -module Touchlane - class Features - - def self.generate_enabled_features_extension(builder_features_list, build_settings_features_list) - - # Check is entered features contains in configuration file - features_diff = builder_features_list - build_settings_features_list - - unless features_diff.empty? - raise "Unexpected features: " + features_diff.join(', ') - end - - # Generate enabled features extension from feature names - enabled_features_extension_template = Templates::FeatureTemplates.enabled_features_extension - utils = Managers::TemplateManager.new(builder_features_list) - - utils.render(enabled_features_extension_template).strip - end - - private_class_method :new - - end -end diff --git a/xcode/managers/lib/file_manager.rb b/xcode/managers/lib/file_manager.rb deleted file mode 100644 index 45bdda8..0000000 --- a/xcode/managers/lib/file_manager.rb +++ /dev/null @@ -1,33 +0,0 @@ -require 'yaml' -require 'json' - -module Managers - class FileManager - - def self.save_data_to_file(path, data) - unless File.exists? path - raise "Unable to save data to file at #{path}" - else - File.open(path, "w") do |f| - f.write(data) - end - end - end - - def self.load_from_file_YAML(path) - unless File.exists? path - raise "Unable to load data from file at #{path}" - else - YAML.load_file(path) - end - end - - def self.save_data_to_file_in_json(path, data) - json_data = JSON.pretty_generate(data) - save_data_to_file(path, json_data) - end - - private_class_method :new - - end -end diff --git a/xcode/managers/lib/template_manager.rb b/xcode/managers/lib/template_manager.rb deleted file mode 100644 index adb59c5..0000000 --- a/xcode/managers/lib/template_manager.rb +++ /dev/null @@ -1,19 +0,0 @@ -require 'erb' - -module Managers - class TemplateManager - - include ERB::Util - - attr_accessor :items - - def initialize(items) - @items = items - end - - def render(template) - ERB.new(template).result(binding) - end - - end -end diff --git a/xcode/managers/managers.rb b/xcode/managers/managers.rb deleted file mode 100644 index 9c3c53d..0000000 --- a/xcode/managers/managers.rb +++ /dev/null @@ -1,4 +0,0 @@ -module Managers - require_relative "lib/file_manager" - require_relative "lib/template_manager" -end diff --git a/xcode/templates/templates.rb b/xcode/templates/templates.rb deleted file mode 100644 index c26788d..0000000 --- a/xcode/templates/templates.rb +++ /dev/null @@ -1,3 +0,0 @@ -module Templates - require_relative "templates/features_templates" -end diff --git a/xcode/templates/templates/features_templates.rb b/xcode/templates/templates/features_templates.rb deleted file mode 100755 index 69eeeaf..0000000 --- a/xcode/templates/templates/features_templates.rb +++ /dev/null @@ -1,34 +0,0 @@ -module Templates - module FeatureTemplates - - def self.features_enum -" -// MARK: - Generated feature toggles - -public enum Feature: String, Codable, RawRepresentable, CaseIterable { - <% for @item in @items %> - case <%= @item %> - <% end %> -} -" - end - - def self.enabled_features_extension -" -// MARK: - Generated enabled features - -public extension Feature { - - static var enabled: [Feature] { - [ - <% for @item in @items %> - \.<%= @item %>, - <% end %> - ] - } -} -" - end - - end -end \ No newline at end of file -- 2.40.1 From e732e16d2132b6d6cafa1521dd9a273bdbbabadd Mon Sep 17 00:00:00 2001 From: Ivan Smolin Date: Thu, 18 Jan 2024 15:22:31 +0300 Subject: [PATCH 2/2] separate SyncCodeSigning to multiple actions --- xcode/bootstrap/Makefile | 2 +- xcode/commonFastfile | 156 ++++++------------ .../lib/match/storage/local_storage.rb | 2 + .../match/storage/local_storage_register.rb | 16 ++ xcode/fastlane/touchlane/lib/touchlane.rb | 7 +- .../actions/manually_update_code_signing.rb | 62 +++++++ .../lib/touchlane/actions/refresh_profiles.rb | 96 +++++++++++ .../replace_development_certificate.rb | 24 +++ .../actions/sync_signing_identities.rb | 26 +++ .../touchlane/lib/touchlane/configuration.rb | 15 +- .../lib/touchlane/configuration_type.rb | 1 + 11 files changed, 296 insertions(+), 111 deletions(-) create mode 100644 xcode/fastlane/touchlane/lib/match/storage/local_storage_register.rb create mode 100644 xcode/fastlane/touchlane/lib/touchlane/actions/manually_update_code_signing.rb create mode 100644 xcode/fastlane/touchlane/lib/touchlane/actions/refresh_profiles.rb create mode 100644 xcode/fastlane/touchlane/lib/touchlane/actions/replace_development_certificate.rb create mode 100644 xcode/fastlane/touchlane/lib/touchlane/actions/sync_signing_identities.rb diff --git a/xcode/bootstrap/Makefile b/xcode/bootstrap/Makefile index 09940d2..21ca414 100644 --- a/xcode/bootstrap/Makefile +++ b/xcode/bootstrap/Makefile @@ -6,7 +6,7 @@ RESET := $(shell tput -Txterm sgr0) RUBY_VERSION="2.7.6" open_project=(open *.xcworkspace) -install_dev_certs=(bundle exec fastlane SyncCodeSigning type:development readonly:true) +install_dev_certs=(bundle exec fastlane InstallDevelopmentSigningIdentities) install_pods=(bundle exec pod install || bundle exec pod install --repo-update) init_rbenv=(if command -v rbenv &> /dev/null; then eval "$$(rbenv init -)"; fi) diff --git a/xcode/commonFastfile b/xcode/commonFastfile index 09e8757..cb37987 100644 --- a/xcode/commonFastfile +++ b/xcode/commonFastfile @@ -2,13 +2,6 @@ $appName = File.basename(Dir['../*.xcworkspace'].first, '.*') require_relative 'fastlane/touchlane/lib/touchlane' -# ugly hack to add support for custom storage - -Match.module_eval do - def self.storage_modes - return %w(git google_cloud s3 local) - end -end private_lane :installDependencies do |options| podsReposPath = File.expand_path "~/.cocoapods/repos/master/" @@ -104,7 +97,7 @@ private_lane :buildConfiguration do |options| options[:workspace] = options[:workspace] || File.expand_path("../#{options[:appName]}.xcworkspace") configuration_type = Touchlane::ConfigurationType.from_lane_name(lane_name) - options = fill_up_options_using_configuration_type(options, configuration_type) + options = fill_up_options_using_configuration_type(options, configuration_type, true) generate_xcodeproj_if_needed(options) @@ -123,13 +116,13 @@ private_lane :buildConfiguration do |options| if !(options[:uploadToFabric] || options[:uploadToAppStore]) options[:skip_package_ipa] = true - sync_code_signing_using_options(options) + install_signing_identities(options) buildArchive(options) # check build failures and static analysis end if options[:uploadToFabric] - sync_code_signing_using_options(options) + install_signing_identities(options) addShield(options) buildArchive(options) uploadToFirebase(options) @@ -138,7 +131,7 @@ private_lane :buildConfiguration do |options| if options[:uploadToAppStore] options[:include_symbols] = options[:include_symbols].nil? ? true : options[:include_symbols] - sync_code_signing_using_options(options) + install_signing_identities(options) buildArchive(options) upload_to_app_store_using_options(options) end @@ -192,11 +185,39 @@ private_lane :buildArchive do |options| ) end -lane :SyncCodeSigning do |options| - configuration_type = Touchlane::ConfigurationType.from_type(options[:type]) +lane :InstallDevelopmentSigningIdentities do |options| + configuration_type = Touchlane::ConfigurationType.from_type("development") options = fill_up_options_using_configuration_type(options, configuration_type) - sync_code_signing_using_options(options) + install_signing_identities(options) +end + +lane :RefreshProfiles do |options| + type = options[:type] || "development" + + configuration_type = Touchlane::ConfigurationType.from_type(type) + options = fill_up_options_using_configuration_type(options, configuration_type) + + refresh_profiles(options) +end + +lane :ReplaceDevelopmentCertificate do |options| + configuration_type = Touchlane::ConfigurationType.from_type("development") + options = fill_up_options_using_configuration_type(options, configuration_type, true) + + replace_development_certificate(options) +end + +lane :SyncAppStoreIdentities do |options| + configuration_type = Touchlane::ConfigurationType.from_type("appstore") + options = fill_up_options_using_configuration_type(options, configuration_type, true) + + options[:readonly] = false + sync_signing_identities(options) +end + +lane :ManuallyUpdateCodeSigning do |options| + manually_update_code_signing(get_default_options.merge(options)) end private_lane :openKeychain do |options| @@ -221,98 +242,19 @@ private_lane :openKeychain do |options| end end -lane :ManuallyUpdateCodeSigning do |options| - register_local_storage_for_match() - - require 'match' - - storage_factory = lambda do - new_storage = Match::Storage.for_mode('local', { git_url: get_signing_identities_path() }) - new_storage.download - return new_storage - end - - encryption_factory = lambda do |stor| - new_encryption = Match::Encryption.for_storage_mode('local', { working_directory: stor.working_directory }) - new_encryption.decrypt_files - return new_encryption - end - - get_all_files = lambda do |stor| - Dir[File.join(stor.working_directory, "**", "*.{cer,p12,mobileprovision}")] - end - - storage = storage_factory.call - encryption = encryption_factory.call(storage) - old_files = get_all_files.call(storage) - - sh("open #{storage.working_directory}") - - # we are not using prompt() since it requires non-empty input which is not a case for Enter (\n) - puts "Enter any key when you're done" - STDIN.gets - - encryption.encrypt_files - - files_to_commit = get_all_files.call(storage) - old_directory = storage.working_directory - storage.save_changes!(files_to_commit: files_to_commit) - - - # need to check, because saving changes with delete is another function (update repo if needed) - files_diff = old_files - files_to_commit - - # match can not work with both save/delete functionality `You can't provide both files_to_delete and files_to_commit right now` - # to avoid this we use storage twice if needed - - if files_diff.length > 0 - storage = storage_factory.call - encryption = encryption_factory.call(storage) - - 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) - File.delete(new_file) if File.exist?(new_file) - file = new_file - end - - encryption.encrypt_files - storage.save_changes!(files_to_delete: files_to_delete) - end - -end - -def sync_code_signing_using_options(options) - register_local_storage_for_match() - - match( - app_identifier: options[:app_identifier], - username: options[:username] || options[:apple_id], - api_key_path: options[:api_key_path], - api_key: options[:api_key], - team_id: options[:team_id], - type: options[:type], - readonly: options[:readonly].nil? ? true : options[:readonly], - storage_mode: "local", - # we can't pass signing_identities_path as parameter name since params is hardcoded in match/runner.rb - git_url: get_signing_identities_path(), - skip_docs: true, - keychain_name: options[:keychain_name], - keychain_password: options[:keychain_password] - ) -end - -def register_local_storage_for_match - Match::Storage.register_backend(type: 'local', storage_class: Touchlane::LocalStorage) - Match::Encryption.register_backend(type: 'local', encryption_class: Match::Encryption::OpenSSL) +def get_default_options + { + :git_url => get_signing_identities_path(), + :signing_identities_path => get_signing_identities_path(), + :storage_mode => Touchlane::LocalStorage::STORAGE_TYPE + } end def get_signing_identities_path File.expand_path "../EncryptedSigningIdentities" end -def fill_up_options_using_configuration_type(options, configuration_type) +def fill_up_options_using_configuration_type(options, configuration_type, keychain_password_required = false) configuration = get_configuration_for_type(configuration_type.type) api_key_path = File.expand_path "../fastlane/#{configuration_type.prefix}_api_key.json" @@ -320,7 +262,7 @@ def fill_up_options_using_configuration_type(options, configuration_type) # default_options required to be empty due to the possibility of skipping the configuration type check below - default_options = {} + default_options = get_default_options # Check whether configuration type is required to configure one of api key parameters or not @@ -333,19 +275,19 @@ def fill_up_options_using_configuration_type(options, configuration_type) # If exists then fill in all required information through api_key_path parameter # and set a value to an options` parameter respectively - default_options = {:api_key_path => api_key_path} + default_options[:api_key_path] = api_key_path else # If doesn't exist then build api_key parameter through app_store_connect_api_key action # and set a value to an options` parameter respectively also - default_options = {:api_key => get_app_store_connect_api_key()} + default_options[:api_key] = get_app_store_connect_api_key() end end default_options .merge(configuration.to_options) - .merge(get_keychain_options(options)) + .merge(get_keychain_options(options, keychain_password_required)) .merge(options) end @@ -363,15 +305,15 @@ def get_app_store_connect_api_key() ) end -def get_keychain_options(options) +def get_keychain_options(options, keychain_password_required = false) 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( + elsif keychain_password_required && keychain_password.nil? + keychain_password = prompt( text: "Please enter your keychain password (account password): ", secure_text: true ) diff --git a/xcode/fastlane/touchlane/lib/match/storage/local_storage.rb b/xcode/fastlane/touchlane/lib/match/storage/local_storage.rb index 73759b8..e2b6bc0 100644 --- a/xcode/fastlane/touchlane/lib/match/storage/local_storage.rb +++ b/xcode/fastlane/touchlane/lib/match/storage/local_storage.rb @@ -6,6 +6,8 @@ module Touchlane class LocalStorage < Match::Storage::Interface attr_accessor :signing_identities_path + STORAGE_TYPE = "local" + def self.configure(params) return self.new( # we can't pass signing_identities_path since params is hardcoded in match/runner.rb diff --git a/xcode/fastlane/touchlane/lib/match/storage/local_storage_register.rb b/xcode/fastlane/touchlane/lib/match/storage/local_storage_register.rb new file mode 100644 index 0000000..e6dd662 --- /dev/null +++ b/xcode/fastlane/touchlane/lib/match/storage/local_storage_register.rb @@ -0,0 +1,16 @@ +require 'match' + +# ugly hack to add support for custom storage + +Match.module_eval do + def self.storage_modes + return ['git', 'google_cloud' 's3', Touchlane::LocalStorage::STORAGE_TYPE] + end +end + +def register_local_storage_for_match + storage_type = Touchlane::LocalStorage::STORAGE_TYPE + + Match::Storage.register_backend(type: storage_type, storage_class: Touchlane::LocalStorage) + Match::Encryption.register_backend(type: storage_type, encryption_class: Match::Encryption::OpenSSL) +end diff --git a/xcode/fastlane/touchlane/lib/touchlane.rb b/xcode/fastlane/touchlane/lib/touchlane.rb index 7ece7cd..049b040 100644 --- a/xcode/fastlane/touchlane/lib/touchlane.rb +++ b/xcode/fastlane/touchlane/lib/touchlane.rb @@ -1,6 +1,9 @@ module Touchlane require_relative "touchlane/configuration_type" require_relative "touchlane/configuration" - require_relative "touchlane/features" - require_relative "match/storage/local_storage" + require_relative "match/storage/local_storage_register" + require_relative "touchlane/actions/sync_signing_identities" + require_relative "touchlane/actions/refresh_profiles" + require_relative "touchlane/actions/replace_development_certificate" + require_relative "touchlane/actions/manually_update_code_signing" end diff --git a/xcode/fastlane/touchlane/lib/touchlane/actions/manually_update_code_signing.rb b/xcode/fastlane/touchlane/lib/touchlane/actions/manually_update_code_signing.rb new file mode 100644 index 0000000..c943ee2 --- /dev/null +++ b/xcode/fastlane/touchlane/lib/touchlane/actions/manually_update_code_signing.rb @@ -0,0 +1,62 @@ +require 'match' +require_relative '../../match/storage/local_storage' + +def manually_update_code_signing(options) + register_local_storage_for_match() + + storage_factory = lambda do + new_storage = Match::Storage.from_params(options) + new_storage.download + return new_storage + end + + encryption_factory = lambda do |stor| + new_encryption = Match::Encryption.for_storage_mode(options[:storage_mode], { working_directory: stor.working_directory }) + new_encryption.decrypt_files + return new_encryption + end + + get_all_files = lambda do |stor| + Dir[File.join(stor.working_directory, "**", "*.{cer,p12,mobileprovision}")] + end + + storage = storage_factory.call + encryption = encryption_factory.call(storage) + old_files = get_all_files.call(storage) + + sh("open #{storage.working_directory}") + + # we are not using prompt() since it requires non-empty input which is not a case for Enter (\n) + puts "Enter any key when you're done" + STDIN.gets + + encryption.encrypt_files + + files_to_commit = get_all_files.call(storage) + old_directory = storage.working_directory + storage.save_changes!(files_to_commit: files_to_commit) + + + # need to check, because saving changes with delete is another function (update repo if needed) + files_diff = old_files - files_to_commit + + # match can not work with both save/delete functionality `You can't provide both files_to_delete and files_to_commit right now` + # to avoid this we use storage twice if needed + + if files_diff.length > 0 + storage = storage_factory.call + encryption = encryption_factory.call(storage) + + 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) + File.delete(new_file) if File.exist?(new_file) + file = new_file + end + + encryption.encrypt_files + storage.save_changes!(files_to_delete: files_to_delete) + end + +end \ No newline at end of file diff --git a/xcode/fastlane/touchlane/lib/touchlane/actions/refresh_profiles.rb b/xcode/fastlane/touchlane/lib/touchlane/actions/refresh_profiles.rb new file mode 100644 index 0000000..e069bc9 --- /dev/null +++ b/xcode/fastlane/touchlane/lib/touchlane/actions/refresh_profiles.rb @@ -0,0 +1,96 @@ +require 'match' +require 'fastlane_core' +require 'Spaceship' + +def refresh_profiles(options) + register_local_storage_for_match() + + profiles_tmp_dir = Dir.mktmpdir + + unless options[:cert_id] + cert_type = Match.cert_type_sym(options[:type]) + + storage = Match::Storage.from_params(options) + storage.download + + output_dir_certs = File.join(storage.prefixed_working_directory, "certs", cert_type.to_s) + + matched_certs = Dir.glob("*.cer", base: output_dir_certs) + + if matched_certs.empty? + FastlaneCore::UI.error("Unable to locate certificate to upate profiles") + raise "No certificates found at #{output_dir_certs}" + end + + if matched_certs.length > 1 + options[:cert_id] = File.basename(FastlaneCore::UI.select("Please select the certificate", matched_certs), ".cer") + else + options[:cert_id] = File.basename(matched_certs.first, ".cer") + end + + if options[:cert_path].nil? && options[:p12_path].nil? + encryption = Match::Encryption.for_storage_mode(options[:storage_mode], { working_directory: storage.working_directory }) + encryption.decrypt_files + + tmp_certs_dir = Dir.mktmpdir + + cer_file_name = "#{options[:cert_id]}.cer" + cert_path = File.join(output_dir_certs, cer_file_name) + options[:cert_path] = File.join(tmp_certs_dir, cer_file_name) + + p12_file_name = "#{options[:cert_id]}.p12" + p12_path = File.join(output_dir_certs, p12_file_name) + options[:p12_path] = File.join(tmp_certs_dir, p12_file_name) + + IO.copy_stream(cert_path, options[:cert_path]) + IO.copy_stream(p12_path, options[:p12_path]) + end + end + + app_identifier = options[:app_identifier] + + Spaceship::ConnectAPI.token = Spaceship::ConnectAPI::Token.from_json_file(options[:api_key_path]) + + if app_identifier.is_a? Array + app_identifier.each { |app_id| refresh_profile_for_app(options, app_id, profiles_tmp_dir) } + else + refresh_profile_for_app(options, app_identifier, profiles_tmp_dir) + end +end + +def refresh_profile_for_app(options, app_id, profiles_tmp_dir) + provisioning_name = Fastlane::Actions.lane_context[Touchlane::SharedValues::TOUCH_BUNDLE_ID_PROFILE_NAME_MAPPING][app_id] + + profiles = Spaceship::ConnectAPI::Profile.all(filter: { name: provisioning_name }) + + if profiles.empty? + sigh_for_app(options, app_id, provisioning_name, profiles_tmp_dir) + else + FastlaneCore::UI.important("Did find existing profile #{provisioning_name}. Removing it from dev portal.") + + profiles.each { |profile| profile.delete! if profile.name == provisioning_name } + sigh_for_app(options, app_id, provisioning_name, profiles_tmp_dir) + end + + Match::Importer.new.import_cert( + options, + cert_path: options[:cert_path], + p12_path: options[:p12_path], + profile_path: lane_context[Fastlane::Actions::SharedValues::SIGH_PROFILE_PATH] + ) +end + +def sigh_for_app(options, app_id, provisioning_name, profiles_tmp_dir) + sigh( + app_identifier: app_id, + development: options[:development], + username: options[:username] || options[:apple_id], + api_key_path: options[:api_key_path], + api_key: options[:api_key], + team_id: options[:team_id], + provisioning_name: provisioning_name, + output_path: profiles_tmp_dir, + cert_id: options[:cert_id], + force: true # will also add all available devices to this profile + ) +end \ No newline at end of file diff --git a/xcode/fastlane/touchlane/lib/touchlane/actions/replace_development_certificate.rb b/xcode/fastlane/touchlane/lib/touchlane/actions/replace_development_certificate.rb new file mode 100644 index 0000000..76e736b --- /dev/null +++ b/xcode/fastlane/touchlane/lib/touchlane/actions/replace_development_certificate.rb @@ -0,0 +1,24 @@ +def replace_development_certificate(options) + register_local_storage_for_match() + + certs_path_tmp_dir = Dir.mktmpdir + + cert( + development: true, + username: options[:username] || options[:apple_id], + api_key_path: options[:api_key_path], + api_key: options[:api_key], + team_id: options[:team_id], + output_path: certs_path_tmp_dir, + keychain_password: options[:keychain_password] + ) + + options[:cert_id] = lane_context[Fastlane::Actions::SharedValues::CERT_CERTIFICATE_ID] + options[:cert_path] = lane_context[Fastlane::Actions::SharedValues::CERT_FILE_PATH] + options[:p12_path] = File.join(File.dirname(options[:cert_path]), "#{options[:cert_id]}.p12") + options[:readonly] = false + + refresh_profiles(options) + + sh("open #{certs_path_tmp_dir}") +end \ No newline at end of file diff --git a/xcode/fastlane/touchlane/lib/touchlane/actions/sync_signing_identities.rb b/xcode/fastlane/touchlane/lib/touchlane/actions/sync_signing_identities.rb new file mode 100644 index 0000000..aaaca2e --- /dev/null +++ b/xcode/fastlane/touchlane/lib/touchlane/actions/sync_signing_identities.rb @@ -0,0 +1,26 @@ +def install_signing_identities(options) + readonly_options = options + readonly_options[:readonly] = true + + sync_signing_identities(readonly_options) +end + +def sync_signing_identities(options) + register_local_storage_for_match() + + match( + app_identifier: options[:app_identifier], + username: options[:username] || options[:apple_id], + api_key_path: options[:api_key_path], + api_key: options[:api_key], + team_id: options[:team_id], + type: options[:type], + readonly: options[:readonly].nil? ? true : options[:readonly], + storage_mode: options[:storage_mode], + # we can't pass signing_identities_path as parameter name since params is hardcoded in match/runner.rb + git_url: options[:signing_identities_path] || options[:git_url], + skip_docs: true, + keychain_name: options[:keychain_name], + keychain_password: options[:keychain_password] + ) +end \ No newline at end of file diff --git a/xcode/fastlane/touchlane/lib/touchlane/configuration.rb b/xcode/fastlane/touchlane/lib/touchlane/configuration.rb index 02cc4d3..0a24e0d 100644 --- a/xcode/fastlane/touchlane/lib/touchlane/configuration.rb +++ b/xcode/fastlane/touchlane/lib/touchlane/configuration.rb @@ -1,6 +1,10 @@ require "yaml" module Touchlane + module SharedValues + TOUCH_BUNDLE_ID_PROFILE_NAME_MAPPING = :TOUCH_BUNDLE_ID_PROFILE_NAME_MAPPING + end + class Configuration def initialize(type, app_identifier, apple_id, team_id, itc_team_id) @type = type @@ -13,6 +17,8 @@ module Touchlane attr_reader :type, :app_identifier, :apple_id, :team_id, :itc_team_id def self.from_file(path, type) + Fastlane::Actions.lane_context[SharedValues::TOUCH_BUNDLE_ID_PROFILE_NAME_MAPPING] = {} + configuration_hash = load_configuration_from_file(path) attrs_hash = configuration_hash["types"][type] identifiers = get_app_identifiers_from_configuration_hash(configuration_hash, type) @@ -35,8 +41,15 @@ module Touchlane def self.get_app_identifiers_from_configuration_hash(configuration_hash, type) identifier_key = "PRODUCT_BUNDLE_IDENTIFIER" + profile_name_key = "PROVISIONING_PROFILE_SPECIFIER" + configuration_hash["targets"].collect do |target, types| - types[type][identifier_key] or raise "#{target}: There is no #{identifier_key} field in #{type}" + bundle_id = types[type][identifier_key] + profile_name = types[type][profile_name_key] + + Fastlane::Actions.lane_context[SharedValues::TOUCH_BUNDLE_ID_PROFILE_NAME_MAPPING][bundle_id] = profile_name + + bundle_id or raise "#{target}: There is no #{identifier_key} field in #{type}" end end diff --git a/xcode/fastlane/touchlane/lib/touchlane/configuration_type.rb b/xcode/fastlane/touchlane/lib/touchlane/configuration_type.rb index 9c9e455..d5e5a55 100644 --- a/xcode/fastlane/touchlane/lib/touchlane/configuration_type.rb +++ b/xcode/fastlane/touchlane/lib/touchlane/configuration_type.rb @@ -74,6 +74,7 @@ module Touchlane def to_options { :type => @type, + :development => @is_development, :export_method => @export_method, :configuration => @configuration } -- 2.40.1