bundle exec fastlane resign_ipa ipa:Provenance-tvOS.ipa provision:myprovision.mobileprovision
Last active
September 11, 2023 02:48
-
-
Save denisoster/808c9965ce9cc4bca3233d491c9a3e61 to your computer and use it in GitHub Desktop.
Resign ipa
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# frozen_string_literal: true | |
lane :resign_ipa do |options| | |
resign_ipa_os(options[:provision], options[:ipa], options[:identity]) { |plist| } | |
end | |
def resign_ipa_os(provision, ipa_path, identity, &block) | |
provision = verify_provision(provision) | |
ipa_path = verify_ipa_path(ipa_path) | |
puts "Using IPA #{ipa_path}" | |
puts "Mobile Provisioning #{provision}" | |
ipa_update = update_ipa(provision, ipa_path, &block) | |
puts "Modify IPA before resign #{ipa_update}" | |
resign_ipa(provision, ipa_update, identity) | |
end | |
def update_ipa(provision, ipa_path, &block) | |
ipa_path_update_dir = result_dir() | |
ipa_path_update = "#{ipa_path_update_dir}/#{ipa_path.split('/').last }" | |
unpack_name = "Payload" | |
sh "yes | unzip -q #{ipa_path}" | |
provision_content_path = "./provision.plist" | |
sh "security cms -D -i #{provision} > #{provision_content_path}" | |
raw_bundle_id = sh "/usr/libexec/PlistBuddy -c \"PRINT :Entitlements:application-identifier\" #{provision_content_path}" | |
bundle_id = raw_bundle_id.split(".").drop(1).join(".").gsub("\n", '') | |
sh "rm #{provision_content_path}" | |
app_name = Dir.children("./#{unpack_name}").select{|file| file.end_with?(".app") }[0] | |
plist_path = "./#{unpack_name}/#{app_name}/Info.plist" | |
original_bundle_id_raw = sh "/usr/libexec/PlistBuddy -c \"PRINT :CFBundleIdentifier\" #{plist_path}" | |
original_bundle_id = original_bundle_id_raw.gsub("\n", '') | |
puts "Original IPA BundleID: #{original_bundle_id}" | |
puts "Replace to IPA BundleID: #{bundle_id}" | |
# update bundle id | |
sh "/usr/libexec/PlistBuddy -c \"Set :CFBundleIdentifier #{bundle_id}\" #{plist_path}" | |
# hand to the caller to hanlde plist if needed | |
block.call(plist_path) | |
# remove plugins as not needed for base functioning. | |
sh "rm -fr ./#{unpack_name}/#{app_name}/PlugIns" | |
if Dir.exist?(ipa_path_update) | |
File.delete(ipa_path_update) | |
end | |
sh "zip -rq #{ipa_path_update} ./#{unpack_name}" | |
sh "rm -fr ./#{unpack_name}" | |
ipa_path_update | |
end | |
def resign_ipa(provision, ipa_path, identity) | |
if identity == nil | |
identity = find_identity(provision) | |
end | |
puts "using resign identity: #{identity}" | |
resign( | |
ipa: ipa_path, | |
signing_identity: identity, | |
provisioning_profile: provision | |
) | |
end | |
def find_identity(provision) | |
# Extract all the system certificates for identity search. | |
identities_list = (sh "security find-certificate -p -Z -a").split("-----END CERTIFICATE-----\n") | |
identities = {} | |
identities_list.each do |item| | |
lines = item.split("\n") | |
# key -> identity SHA-1, value -> certificate in PEM format | |
identities.store(lines[1].split(" ").last, lines.drop(3).join()) | |
end | |
# Decode mobileprovision. | |
xml = sh "security cms -D -i #{provision}" | |
parsed_info = Nokogiri::XML(xml) | |
identity = "" | |
# Find a match for mobileprovision and keychain certificates. | |
parsed_info.search('data').map(&:text).each do |pem| | |
identities.each do |key, value| | |
if value == pem | |
identity = key | |
end | |
end | |
end | |
identity | |
end | |
def result_dir | |
dir = "#{Dir.pwd}/resign" | |
Dir.mkdir(dir) unless Dir.exist?(dir) | |
dir | |
end | |
def verify_provision(provision) | |
verify_path(provision, "`provision` key with a full path to *.mobileprovision file must be provided.") { |path| | |
path.end_with?(".mobileprovision") | |
} | |
end | |
def verify_ipa_path(ipa_path) | |
verify_path(ipa_path, "ipa full file path must be provided.") { |path| | |
path.end_with?(".ipa") | |
} | |
end | |
def verify_path(path, error) | |
if path == nil || File.exists?(path) == false || path.start_with?("/") == false || yield(path) == false | |
UI.user_error!(error) | |
end | |
path | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# frozen_string_literal: true | |
source "https://rubygems.org" | |
gem 'fastlane', '~> 2.214' | |
gem 'nokogiri', '~> 1.15', '>= 1.15.4' |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment