class Escalator::Resign
Attributes
assets_path[RW]
bundle_version[RW]
cerIdentifier[RW]
command[RW]
iconInfo_path[RW]
keyInfo_path[RW]
tmpdir[RW]
Public Class Methods
run(command)
click to toggle source
# File lib/escalator/resign.rb, line 7 def run command @command = command prepareContext applyCertificates command.ipaPaths.map { |path| resignIPA handleIPA path } end
Private Class Methods
applyCertificates()
click to toggle source
# File lib/escalator/resign.rb, line 58 def applyCertificates Throw.note "begin apply certificates ..." cmd = "fastlane cert create --api_key_path #{keyInfo_path}" cmd += " --generate_apple_certs true -p #{command.user_password} -o #{tmpdir}" system cmd if !$?.success? Throw.error "Apply .cer file faild!" end cer = File.read Dir.glob("#{tmpdir}/*.cer").first @cerIdentifier = OpenSSL::Digest.hexdigest("SHA1", cer).upcase cmd = "fastlane sigh renew --api_key_path #{keyInfo_path} -a #{command.bundle_identifier}" cmd += " -q embedded.mobileprovision -o #{tmpdir}" system cmd if !$?.success? Throw.error "Apply embedded.mobileprovision file faild!" end end
handleAssets(appPath, assetsPath)
click to toggle source
# File lib/escalator/resign.rb, line 149 def handleAssets appPath, assetsPath Throw.note "begin handle assets ..." cmd = "actool --compile #{assets_path} --minimum-deployment-target 11.0 --platform iphoneos" cmd += " --app-icon AppIcon --output-partial-info-plist #{iconInfo_path}" cmd += " --compress-pngs #{command.iconAssets_path}" Dir.glob("#{assetsPath}/*.xcassets") { |file| cmd += " #{file}" icon_path = "#{file}/AppIcon.appiconset" if File.exist? icon_path FileUtils.rm_rf icon_path end } system cmd if !$?.success? Throw.error "Generate new Assets.car faild!" end FileUtils.mv Dir["#{assets_path}/*"], appPath, force: true end
handleBundle(appPath, newBundleName, newExecutableName)
click to toggle source
# File lib/escalator/resign.rb, line 223 def handleBundle appPath, newBundleName, newExecutableName Throw.note "begin handle bundle ..." plistPath = appPath + "/Info.plist" plist = CFPropertyList::List.new :file => plistPath data = CFPropertyList.native_types plist.value if !newExecutableName.empty? executableName = data["CFBundleExecutable"] FileUtils.mv "#{appPath}/#{executableName}", "#{appPath}/#{newExecutableName}", force: true data["CFBundleExecutable"] = newExecutableName end if !newBundleName.empty? data["CFBundleName"] = newBundleName end plist.value = CFPropertyList::guess data plist.save plistPath if !newBundleName.empty? newAppPath = File.dirname(appPath) + "/#{newBundleName}.app" FileUtils.mv appPath, newAppPath, force: true end end
handleIPA(ipaPath)
click to toggle source
# File lib/escalator/resign.rb, line 76 def handleIPA ipaPath basePath = File.dirname(ipaPath) coverInfoPath = basePath + "/CoverInfo.plist" coverData = Hash.new coverData["CFBundleVersion"] = "" coverData["CFBundleName"] = "" coverData["CFBundleExecutable"] = "" coverData["CFBundleDisplayName"] = "" if File.exist? coverInfoPath coverPlist = CFPropertyList::List.new :file => coverInfoPath CFPropertyList.native_types(coverPlist.value).each { |key, value| coverData[key] = value } end bundleVersion = coverData["CFBundleVersion"] if bundleVersion.empty? bundleVersion = bundle_version.to_s @bundle_version += 1 end displayName = coverData["CFBundleDisplayName"] if displayName.empty? displayName = command.display_name end bundleName = coverData["CFBundleName"] if bundleName.empty? bundleName = command.bundle_name end executableName = coverData["CFBundleExecutable"] if executableName.empty? executableName = command.executable_name end if (command.iconAssets_path.empty? && bundleName.empty? && executableName.empty?) return OpenStruct.new(:path => ipaPath, :displayName => displayName) end Throw.note "begin handle #{File.basename ipaPath} ..." content_path = tmpdir + "/content" FileUtils.mkdir_p content_path system "unzip -o -q #{ipaPath} -d #{content_path}" if !$?.success? Throw.error "Unzip ipa faild!" end appPath = Dir.glob("#{content_path}/**/*.app").first if !command.iconAssets_path.empty? handleAssets appPath, basePath end pluginsProvisions = [] pluginsPath = "#{appPath}/PlugIns" if File.exist? pluginsPath pluginsProvisions = handlePlugins pluginsPath end if !(bundleName.empty? && executableName.empty?) handleBundle appPath, bundleName, executableName end FileUtils.rm_rf ipaPath newIpaPath = ipaPath if !bundleName.empty? newIpaPath = File.expand_path "../#{bundleName}.ipa", ipaPath end system "cd #{content_path} && zip -q -r -D #{newIpaPath} ./*" if !$?.success? Throw.error "Zip payload faild!" end FileUtils.rm_rf content_path OpenStruct.new( :path => newIpaPath, :bundleVersion => bundleVersion, :displayName => displayName, :pluginsProvisions => pluginsProvisions ) end
handlePlugins(path)
click to toggle source
# File lib/escalator/resign.rb, line 168 def handlePlugins path appleIdField = command.apple_id.empty? ? "" : "-u #{command.apple_id}" parts = (command.bundle_identifier.split ".").sort_by { |p| p.length } groupName = parts.last groupIdentifier = "group.#{command.bundle_identifier}" system "fastlane produce group #{appleIdField} -g #{groupIdentifier} -n '#{groupName} App Group'" if !$?.success? Throw.error "Create #{groupName} app group faild!" end infos = Dir.glob("#{path}/*.appex/Info.plist").map { |infoPath| plist = CFPropertyList::List.new :file => infoPath CFPropertyList.native_types plist.value } enableNetworkExtension = false infos.each { |info| enableNetworkExtension |= info["NSExtension"]["NSExtensionPointIdentifier"].include? "com.apple.networkextension" } networkExtensionField = enableNetworkExtension ? "--network-extension" : "" system "fastlane produce enable_services #{appleIdField} --app-group #{networkExtensionField} -j ios -a #{command.bundle_identifier}" if !$?.success? Throw.error "#{command.bundle_identifier} enable services faild!" end system "fastlane produce associate_group #{appleIdField} #{groupIdentifier} -a #{command.bundle_identifier}" if !$?.success? Throw.error "#{command.bundle_identifier} associate group faild!" end system "fastlane sigh renew --api_key_path #{keyInfo_path} -f -a #{command.bundle_identifier} -q embedded.mobileprovision -o #{tmpdir}" if !$?.success? Throw.error "Apply embedded.mobileprovision file faild!" end infos.map { |info| originalIdentifier = info["CFBundleIdentifier"] name = originalIdentifier.split(".").last provisionName = "#{name}.mobileprovision" identifier = "#{command.bundle_identifier}.#{name}" system "fastlane produce create #{appleIdField} -i -j ios -a #{identifier} -q #{name}" if !$?.success? Throw.error "Create #{identifier} faild!" end system "fastlane produce enable_services #{appleIdField} --app-group #{networkExtensionField} -j ios -a #{identifier}" if !$?.success? Throw.error "#{identifier} enable services faild!" end system "fastlane produce associate_group #{appleIdField} #{groupIdentifier} -a #{identifier}" if !$?.success? Throw.error "#{identifier} associate group faild!" end system "fastlane sigh renew --api_key_path #{keyInfo_path} -a #{identifier} -q #{provisionName} -o #{tmpdir}" if !$?.success? Throw.error "Apply #{provisionName} file faild!" end "#{originalIdentifier}=#{tmpdir}/#{provisionName}" } end
prepareContext()
click to toggle source
# File lib/escalator/resign.rb, line 32 def prepareContext Throw.note "Prepare resign context ..." @tmpdir = ENV["TMPDIR"] + "escalator/resign" if File.exist? tmpdir FileUtils.rm_rf Dir["#{tmpdir}/*"] else FileUtils.mkdir_p tmpdir end @keyInfo_path = tmpdir + "/keyInfo.json" keyInfo = Hash.new keyInfo[:in_house] = false keyInfo[:key_id] = command.key_id keyInfo[:issuer_id] = command.issuer_id keyInfo[:key_filepath] = command.keyfile_path keyInfo[:key] = File.read command.keyfile_path file = File.new keyInfo_path, "w" file.write JSON.generate keyInfo file.close @bundle_version = command.bundle_version.to_i @assets_path = tmpdir + "/assets" FileUtils.mkdir_p assets_path info_path = File.expand_path "../../../resources/IconInfo.plist", __FILE__ FileUtils.cp info_path, tmpdir @iconInfo_path = tmpdir + "/IconInfo.plist" end
resignIPA(ipaInfo)
click to toggle source
# File lib/escalator/resign.rb, line 244 def resignIPA ipaInfo path = File.dirname ipaInfo.path ipaName = File.basename ipaInfo.path Throw.note "begin resign #{ipaName} ..." cmd = "fastlane sigh resign --short_version #{command.short_version}" cmd += " --bundle_version #{ipaInfo.bundleVersion}" if !ipaInfo.displayName.empty? cmd += " -d #{ipaInfo.displayName}" end cmd += " --use_app_entitlements -p #{tmpdir}/embedded.mobileprovision" ipaInfo.pluginsProvisions.each { |provision| cmd += " -p #{provision}" } cmd += " -i #{cerIdentifier} #{ipaInfo.path}" system cmd if !$?.success? Throw.error "Resign ipa faild!" end newPath = path + "_build_#{ipaInfo.bundleVersion}" FileUtils.mv path, newPath, force: true "#{newPath}/#{ipaName}" end