-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.rb
177 lines (158 loc) · 5.35 KB
/
main.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
# frozen_string_literal: true
require 'English'
require 'shellwords'
require 'colored'
require 'json'
require 'fileutils'
require 'nokogiri'
require 'openssl'
require_relative 'provisioning_parser'
def find_resign_path
sh_script_path = "#{File.expand_path(File.dirname(__FILE__))}/resign.sh"
"bash #{sh_script_path}"
end
def valid_xml?(xml_string)
Nokogiri::XML(xml_string)
true
rescue Nokogiri::XML::SyntaxError
false
end
def create_provisioning_options(provisioning_profiles)
provisioning_profiles.map do |app_id, app_id_prov|
if app_id_prov
app_id_prov = File.expand_path(app_id_prov)
else
app_id = File.expand_path(app_id)
end
"-p #{[app_id, app_id_prov].compact.map(&:shellescape).join('=')}"
end.join(' ')
end
def create_entitlement(target)
filepath = File.join(ENV['AC_TEMP_DIR'], "#{target['BundleId']}.xml")
if !File.exist?(filepath) && target['Entitlements']
if valid_xml?(target['Entitlements'])
File.write(filepath, target['Entitlements'])
"-e #{filepath.shellescape}"
else
puts "Target #{target['BundleId']} doesn't have valid entitlements"
nil
end
end
end
# TODO: Multiple Entitlements support
def create_entitlements_options(targets)
targets.map do |target|
filepath = File.join(ENV['AC_TEMP_DIR'], "#{target['BundleId']}.xml")
if !File.exist?(filepath) && target['Entitlements']
if valid_xml?(target['Entitlements'])
File.write(filepath, target['Entitlements'])
"-e #{filepath.shellescape}"
else
puts "Target #{target['BundleId']} doesn't have valid entitlements"
nil
end
end
end.compact.join(' ')
end
def get_provisioning_profiles
if ENV['AC_PROVISIONING_PROFILES'].nil? || ENV['AC_PROVISIONING_PROFILES'] == ''
puts 'AC_PROVISIONING_PROFILES does not exist.'
[]
else
provisioning_profiles = ENV['AC_PROVISIONING_PROFILES']
provisioning_profiles.split('|').map do |path|
converted = "#{path}.mobileprovision"
puts "Copying #{path} -> #{converted}"
FileUtils.cp(path, converted)
converted
end
end
end
def bundle_ids
if ENV['AC_BUNDLE_IDENTIFIERS'].nil? || ENV['AC_BUNDLE_IDENTIFIERS'] == ''
puts 'AC_BUNDLE_IDENTIFIERS does not exist.'
[]
else
bundle_ids = ENV['AC_BUNDLE_IDENTIFIERS']
bundle_ids.split('|')
end
end
def map_bundle_ids(targets)
targets.map do |target|
target['OriginalBundleId']
end
end
def resign(ipa, signing_identity, provisioning_profiles, entitlements, version, display_name, short_version,
bundle_version, new_bundle_id, use_app_entitlements)
resign_path = find_resign_path
provisioning_profiles = [provisioning_profiles] unless provisioning_profiles.is_a?(Enumerable)
provisioning_options = create_provisioning_options(provisioning_profiles)
version = "-n #{version}" if version
display_name = "-d #{display_name.shellescape}" if display_name
short_version = "--short-version #{short_version}" if short_version
bundle_version = "--bundle-version #{bundle_version}" if bundle_version
bundle_id = "-b '#{new_bundle_id}'" if new_bundle_id
use_app_entitlements_flag = '--use-app-entitlements' if use_app_entitlements
output_dir = ENV['AC_OUTPUT_DIR']
output_file = File.join(output_dir, ipa)
command = [
resign_path,
ipa.shellescape,
signing_identity.shellescape,
provisioning_options, # we are aleady shellescaping this above, when we create the provisioning_options from the provisioning_profiles
entitlements,
version,
display_name,
short_version,
bundle_version,
use_app_entitlements_flag,
bundle_id,
output_file # Output path must always be last argument
].join(' ')
puts(command.magenta)
puts(`#{command}`)
if $CHILD_STATUS.to_i.zero?
puts "✅ Successfully signed #{ipa}!".blue
else
raise("❌ Something went wrong while code signing #{ipa}")
end
end
ipa_url = ENV['AC_RESIGN_IPA_URL']
ipa = ENV['AC_RESIGN_FILENAME']
`curl -s -o "./#{ipa}" -k "#{ipa_url}"`
targets_json = ENV['AC_RESIGN_TARGETS']
targets = JSON.parse(File.read(targets_json))
main_target = targets.first
puts "Main Target: #{main_target}"
provisioning_profiles = get_provisioning_profiles
first_provision = MobileProvision.new(provisioning_profiles.first)
# Extract the first certificate
certificate = first_provision.developer_certs[0]
signing_identity = certificate.signature
signing_name = certificate.name
puts "Name: #{signing_name} SHA-1: #{signing_identity}"
original_bundle_ids = map_bundle_ids(targets)
# We must use original from the new targets.
new_provisioning_profiles = Hash[original_bundle_ids.zip(provisioning_profiles)]
puts "Provisioning Profile Bundle Ids: #{bundle_ids}"
puts "Original Bundle Ids: #{original_bundle_ids}"
puts "Provisionining profiles #{new_provisioning_profiles}"
entitlements = create_entitlement(main_target)
version = nil
display_name = main_target['Display']
short_version = main_target['Version']
bundle_version = main_target['BuildNumber']
original_bundle_id = main_target['OriginalBundleId']
new_bundle_id = main_target['BundleId']
use_app_entitlements = main_target['UseAppEntitlements']
new_bundle_id = nil if new_bundle_id == original_bundle_id
resign(ipa,
signing_identity,
new_provisioning_profiles,
entitlements,
version,
display_name,
short_version,
bundle_version,
new_bundle_id,
use_app_entitlements)